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

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

关注

评论

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

说说Vue响应式系统中的Watcher和Dep的关系-面试进阶

bb_xiaxia1998

Vue

前端vue面试题集锦1

bb_xiaxia1998

Vue

Vue.$nextTick的原理是什么-vue面试进阶

bb_xiaxia1998

Vue

必会vue面试题(附答案)

bb_xiaxia1998

Vue

昨天,同事优化加锁方式时,出现死锁了

华为云开发者联盟

高并发 开发 华为云 12 月 PK 榜

时隔3个月,Uber 再遭数据泄露...

SEAL安全

数据泄露 uber 第三方风险 12 月 PK 榜

一文盘点Zebec生态的收益模型

西柚子

京东前端高频vue面试题(边面边更)

bb_xiaxia1998

Vue

校招前端二面常考手写面试题汇总

helloworld1024fd

JavaScript

西藏等保测评公司有哪些?共有几家?

行云管家

等保测评 等保测评公司 西藏

社招前端二面react面试题整理

beifeng1996

React

前端一面必会vue面试题(边面边更)

bb_xiaxia1998

Vue

腾讯前端手写面试题及答案

helloworld1024fd

JavaScript

怎样徒手写一个React

helloworld1024fd

JavaScript

为什么是无代码?

间隔

微信小程序 编辑器 无代码

面试官:vue2和vue3的区别有哪些?

bb_xiaxia1998

Vue

Vue-Router 路由与配置

千锋IT教育

分享一下MySQL数据库中好玩的14个小玩意

Java永远的神

Java MySQL 数据库 程序员 后端

Python 的安装与配置(图文教程)

千锋IT教育

HarmonyOS年度开发者活动,赋能逾万名开发者开启HarmonyOS学习之旅

极客天地

计算存储分离在京东云消息中间件JCQ上的应用

京东科技开发者

容器 中间件 存储分离 消息中间件 存储计算分离

2022 Gartner全球数据库魔力象限发布,腾讯云数据库入选

腾讯云数据库

数据库 tdsql Gartner 腾讯云数据库

只要是做乙方,欧美白人下班后也别想失联?

SAP虾客

IT行业 乙方 工作与生活分开 欧美 TICKET

基于 Caddy 部署盘古 Admin 实现流量网关

码农大熊

盘古开发框架

老生常谈React的diff算法原理-面试版

beifeng1996

React

关于Kubernetes中如何访问集群外服务的一些笔记

山河已无恙

12月月更

实践丨GaussDB(DWS)资源管理排队原理与问题定位

华为云开发者联盟

数据库 华为云 12 月 PK 榜

手写JS函数的call、apply、bind

helloworld1024fd

JavaScript

Spring Cloud 应用 Proxyless Mesh 模式探索与实践

阿里巴巴云原生

阿里云 微服务 云原生

说说你对Vue的keep-alive的理解

bb_xiaxia1998

Vue

火山引擎DataTester科普:A/B实验常见名词解释

字节跳动数据平台

大数据 AB testing实战 12 月 PK 榜

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