50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

Ruby 编程:清晰明确的代码还是简洁精炼的代码?

  • 2007-07-30
  • 本文字数:966 字

    阅读完需:约 3 分钟

Pier Cawley 撰文探讨了他在一篇介绍延迟初始化属性的博客文章中发现的潜在问题。出现问题的代码如下:

def content<br></br> @content ||= []<br></br>end这段代码的目的是为了支持类的延迟初始化属性。在这个例子当中,除非@content这个实例变量已经初始化完毕,否则在它的访问器方法content方法被调用的时候,它就会被初始化。||=这个操作符意思是“如果左边的变量值为nil,将它的值赋为右边表达式,否则仅返回左边的变量值。”

然而,Piers 指出,对于某些值来说,这样做是会出现问题的,因为 Ruby 处理布尔值和nil的方式比较特殊。我们来看看下面这样一个例子:

a = false<br></br>a ||= "Ruby"这样的代码结果是怎样的呢?由于a已经在第一行被初始化,第二行不应产生任何效果。然而,在代码执行之后,我们会发现a现在的值为"Ruby",而不是false

在熟记 Ruby 中编写nil检查通用方式之后,问题就变得非常显而易见:

if name<br></br> puts name.capitalize<br></br>end在 Ruby 中,nil被解释成布尔值false,因此if子句中的代码只有在name的值不等于nil的时候才能运行。

尽管在通常意义上这不会成为一个问题,但是在延迟初始化属性的代码中,如果付给属性的合法值是nil或者false的时候,这就会成为一个问题。在这种情况下,对属性进行访问之后,属性值就会被重设成缺省值。

当然,这是一个边界情况,但是这样的问题会导致人们花很长时间进行调试,来试图找出到底为什么某些方法有些时候会被重设而另外一些则不会。

Piers为这段代码给出了一个条理更为清晰的代码

def content<br></br> unless instance_variable_defined? :@content<br></br> @content = []<br></br> end<br></br> return @content<br></br>end这样,代码只会在变量还没有被定义的时候才会初始化变量。

通过这个小例子,我们可以把错误归咎于 Ruby 及其部分语言特性——但 _ 哪一类 _ 程序员会把错误归咎于工具而不是他们自身,这已经是众所周知的事实了。尽管 Ruby 代码的简洁性非常有用,但还是有一些情况下使用更加明确表达意图的表达式会更安全一些。在这个例子中,||=并非正确的解决方案,相反初始化代码应当检查变量是否已经被定义。

亲爱的读者,您在以前是否也被这样的问题敲中脑门呢?Ruby 是否存在哪些你希望避免的语言特性,以预防上述难于发现的问题呢?

查看英文原文: Explicit vs. concise code in Ruby

2007-07-30 09:001289
用户头像

发布了 117 篇内容, 共 20.6 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

终于有人用7部分讲明白了Spring Security OAuth2.0认证授权全过程

Java全栈架构师

Java spring 程序员 面试 springsecurity

奇怪,为什么ArrayList初始化容量大小为10?HashMap的初始化容量为16?

Java全栈架构师

Java 源码 程序员 面试 程序人生

十大靠谱“计算机视觉数据集”榜单

澳鹏Appen

人工智能 机器学习 计算机视觉 数据集 训练数据

直播预告|SQL也能玩转工业级机器学习?MLOps meetup V3带你一探究竟!

星策开源社区

人工智能 机器学习 sql 特征平台 MLOps

提升可观测性 - 业务指标监控实践

bilibili游戏技术

IDC:阿里云获2021中国数据治理平台市场份额第一

阿里云大数据AI技术

数据挖掘 大数据 数据采集

OUT了吧,Kafka能实现消息延时了

华为云开发者联盟

云计算 开发

电商秒杀系统架构设计

哈喽

「架构实战营」

应用实践 | 10 亿数据秒级关联,货拉拉基于 Apache Doris 的 OLAP 体系演进(附 PPT 下载)

SelectDB

数据库 flink OLAP Doris 数仓建设

Java Core「19」使用 Java IO API 创建 C/S 程序的方法

Samson

学习笔记 Java core 6月月更

Zadig 构建究竟何强大?一起来实践

Zadig

gitlab 云原生 jenkins Zadig

华为云的AI深潜之旅

脑极体

穿越过后,她说多元宇宙真的存在

脑极体

软件测试的三个沟通技巧

FunTester

如何设计业务高性能高可用计算架构 - 作业

阿拉阿拉幽幽

Android Target 31 升级全攻略 —— 记阿里首个超级 App 的坎坷升级之路

阿里巴巴终端技术

android App target

OneFlow源码解析:算子签名的自动推断

OneFlow

源码解析 算子 Relu

为什么要使用 Rust 语言?

面向加薪学习

rust

2022最新Java面试突击手册,1000道面试题+优质面经

Java全栈架构师

Java 程序员 面试 算法 计算机网络

基于管线的混合渲染

Finovy Cloud

gpu 渲染器 GPU服务器 显卡、gpu

Mac中Git如何忽略.DS_Store文件

坚果

git git 规范 6月月更

wrk压力测试工具介绍

乌龟哥哥

6月月更

Zadig 面向开发者的自测联调子环境技术方案详解

Zadig

DevOps Service Mesh CI/CD 测试环境治理

Zadig 正式推出 VS Code 插件,本地开发更高效

Zadig

vscode 插件 热部署 本地化开发 Zadig

这个简单的小功能,半年为我们产研团队省下213个小时

阿里云云效

云计算 阿里云 云原生 产品开发 研发

构建实战化防御体系之立体防渗透

穿过生命散发芬芳

6月月更 攻防演练

TDengine ×英特尔®边缘洞见软件包 加速传统行业的数字化转型

TDengine

数据库 tdengine 时序数据库

如何高效优雅地管理接口文档

Liam

测试 开发工具 API接口管理 API文档 免费API接口

微博评论的高性能高可用计算架构方案

joak

安全 创新 实践|海泰方圆受邀参加“数字时代的网信创新与价值共创”技术交流研讨会

电子信息发烧客

Zadig + SonarQube,为开发过程安全保驾

Zadig

DevOps 代码扫描 SonarQube 质量内建

Ruby编程:清晰明确的代码还是简洁精炼的代码?_Ruby_Werner Schuster_InfoQ精选文章