NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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:00763
用户头像

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

关注

评论

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

DDD领域驱动设计实战(四)-值对象

JavaEdge

12月日更

前端开发:关于Vue组件中的data属性值是函数而不是对象的详解

三掌柜

28t 28天写作 12月日更

微信朋友圈高性能架构分析与设计

皓月

架构实战 #架构实战营 「架构实战营」

Cordova应用的JavaScript代码和自定义插件代码的调试

Jerry Wang

JavaScript android 28天写作 12月日更 cordova

Kubernetes + Spring Cloud 集成链路追踪 SkyWalking

zuozewei

链路追踪 性能测试 性能监控 12月日更

模块七作业——王者荣耀商城异地多活架构设计

deng

架构实战营

Guava的布隆过滤器

程序员历小冰

算法 布隆过滤器 28天写作 12月日更

架构实战营 第 4 期 模块二作业

架构实战营 模块二 「架构实战营」

React进阶(九):React-Redux

No Silver Bullet

React React-Redux 12月日更

跟着动画学Go数据结构之希尔排序

宇宙之一粟

golang 希尔排序 12月日更

LabVIEW图像特征与机器视觉概念(理论篇—4)

不脱发的程序猿

机器视觉 图像处理 工业自动化 图像特征

关于HDFS中的Lease Recovery

Joseph295

信贷风控从Model-centric到Data-centric

一直学习一直爽

互联网金融 风控模型 机器学习算法

模块二:朋友圈

撿破爛ぃ

「架构实战营」

给弟弟的信第17封|拒绝自我感觉良好

大菠萝

28天写作

如何做一个区块链浏览器

Rayjun

区块链 区块链浏览器

2021学习总结

将军-技术演讲力教练

微信朋友圈高性能分析

swallowluo

架构训练营 架构实战营 「架构实战营」

天下武功,无坚不摧,唯快不破

Tiger

28天写作

架构训练营 - 模块二作业

伊静西蒙

从对象内存布局了解锁的膨胀

Ayue、

锁升级

kubernetes APIServer是如何限流的?

xcbeyond

Kubernetes 限流 28天写作 12月日更

[Pulsar] 设置认证和鉴权

Zike Yang

Apache Pulsar 12月日更

Android ShareSDK 微博分享 (8995)app auth fail for appKey&sign&package 解决

阿策小和尚

28天写作 Android 小菜鸟 12月日更

Python爬虫反爬,你应该从这篇博客开启,UA反爬,Cookie 特定参数反爬

梦想橡皮擦

12月日更

Prometheus Exporter (三十一)ProxySQL Exporter

耳东@Erdong

Prometheus 28天写作 exporter 12月日更 ProxySQL

dart系列之:这里不需要标新立异,dart代码最佳实践

程序那些事

flutter dart 代码规范 程序那些事 12月日更

🏆【Alibaba中间件技术系列】「EasyExcel实战案例」实战研究一下EasyExcel如何从指定文件位置进行读取数据

洛神灬殇

EasyExcel Apache POI Alibaba 12月日更

架构实战营模块2课后作业

墨宝

情绪价值

搬砖的周狮傅

情绪

JavaScript 数组方法 .map() 的 5 个使用场景

devpoint

JavaScript map array 12月日更

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