写点什么

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

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

关注

评论

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

解析!1V1直播源码开发搭建技术实时语音识别翻译功能的应用

山东布谷科技

软件开发 直播 源码搭建 一对一直播源码 1v1语音系统搭建

ChatGPT:向未来迈进的智能对话伴侣 | 社区征文

架构精进之路

技术 后端 社区征文 ChatGPT 年中技术盘点

从头学Java17-今天的Kotlin更香吗

烧霞

kotlin java17

带你走进 IntelliJ IDEA 的插件世界

冰心的小屋

idea plugin

强化学习:基于蒙特卡洛树和策略价值网络的深度强化学习五子棋(含码源)

汀丶人工智能

人工智能 深度学习 蒙特卡洛 强化学习

PyTorch: 权值初始化

timerring

PyTorch

AI的“道德感”如何训练而来(1)|社区征文

石君

AIGC 年中技术盘点 人工智能道德

Apache Doris 用户行为分析实践

冰心的小屋

数据仓库 OLAP Doris

来自 BOSS 的需求,我们该怎么处理?

Bonaparte

产品 产品需求 BOSS需求 需求处理

Visual Studio Code错误:Cannot build and debug because the active file is not a C or C++ source file

codists

Visual Studio Code

真正的千万级分布式延迟任务系统 Grape

dinstone

c++类型转换与RTTI运行阶段类型识别

芯动大师

ClickHouse 学习分享

冰心的小屋

OLAP Clickhouse

对线面试官-Redis 九 | 持久化的方式及优缺点

派大星

Java 面试题

免费试用商业智能工具,帮助您轻松解决商业智能选型问题

对不起该用户已成仙‖

2023-07-15:给你一个 非递减 的正整数数组 nums 和整数 K, 判断该数组是否可以被分成一个或几个 长度至少 为 K 的 不相交的递增子序列。 输入:nums = [1,2,2,3,3,

福大大架构师每日一题

Go rust 福大大架构师每日一题

代码随想录 Day17 - 二叉树(四)

jjn0703

Open-OAuth2Playground:开箱即用的开源版OAuth2在线调试服务

冯骐

OAuth 2.0 Go 语言 开放平台 API 调试 Playground

GitHub Copilot深度剖析:一个AI产品的性能提升、成本控制与效果评估

无人之路

ChatGPT Copilot

WAIC2023丨AI图像内容安全“黑科技”如何助力科技向善发展?

陈橘又青

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