Ruby (译) 我不喜欢新哈希语法

zw963 · 2012年04月17日 · 最后由 john1king 回复于 2012年04月18日 · 4414 次阅读

早前看过的一片文章,写的很不错,一直没空,断断续续总算翻译完了。

文章中描述的内容还是很值得思考的。

原文地址:http://logicalfriday.com/2011/06/20/i-dont-like-the-ruby-1-9-hash-syntax/ (可能被墙)

我不喜欢 Ruby1.9 新哈希语法


首先我要说:我真的不喜欢他,我不知道为什么你们喜欢她。

我先假设你喜欢新哈希语法,每个人都在谈论它 (除了我).

当我在 RailsConf 大会上,看到一个又一个示例者使用新的哈希语法,我的心一次又一次受伤。

我就是不明白,这是为什么...

我也没有总是抱怨,我曾尝试去适应它,同时,你也可以告诉我你为什么喜欢它?

性感的哈希火箭才是我的朋友。

我喜欢哈希火箭 (不仅仅因为它是个火箭), 我也知道我无法离开它,然而,我不喜欢新哈希语法,我有我自己的原因:

定义 Key 的字符受限。

新的哈希语法要求必须以英文字母以及下划线开头 (名称内可以包含数字), 但是我就是喜欢使用任意对象作为一个哈希 key.

# Ruby 1.8 语法, 这个执行正确.
{:this => 'syntax', 'is' => 'fun', #<And:0x10036bb58> => 'flexible'}
# Ruby 1.9 语法, 这个会出错.
{this: 'syntax', 'will': 'cause', #<Nasty:0x10031bf85>: 'errors'}

显然在 key 中包含其他字符并没有太大帮助,但是,你一定会在某个时候突然发现需要使用一个带\的字符串一个数字作为哈希 key.

容易误导的

你似乎输入了一个字符串,但是实际上,你是一个符号.

hash = { test: 'hash' }
# => { :test => 'hash' }
hash.test
# => NoMethodError (works in JavaScript!)
hash['test']
# => nil
hash[:test]
# => 'hash' (hooray!)


与其他语言的相似性:

我并不完全了解使得语言之间变得更加相似好处,(也许得在语言之间切换更容易一些?). 新哈希语法模仿了 JSON, 它对于 Ruby 很重要 (至少对于 Rails 很重要), 毕竟 javascript 是一门开发者经常使用的语言,理论上这样不错。然而,我喜欢语言之间的差别明显一些。我希望每个写 Ruby 代码的人都使用 Ruby 特有的的方式来写自己的代码,在我来说,改变新哈希语法,几乎和在 Ruby 中使用驼峰方式来定义变量一样不可饶恕。

向后兼容

显然,Ruby1.8 不支持这种语法,他不会成为 Ruby1.8 的新特性,然而如此基本的一个语言特性,我不明白为什么我们需要新的方式来重写它。尤其来说,如果一个 gem 库的编写者试图升级使用 1.9 新语法来升级一个 gem 库,这个库在 1.8 下将不可用 (我相信有很多人还在使用 1.8), 我不跟你争辩诸如`1.8 的使用者会越来越少,我们将会慢慢迁移到新的语法', 但是我不认为过渡会有那么快。

混合书写

当在一个项目组内写代码或给一个大的项目贡献代码,代码风格是重要的,存在两种语法,不可避免的会造成两种风格混乱。这对于代码的一致性是很不好的,就算你统一为新哈希语法,如果有一次当你想使用一个对象作为 hash key, 你只能用 1.8 哈希语法。

新语法的好处

我承认新哈希语法不是一无是处, 至少有一个地方,使用新哈希语法比老语法要好一些。例如:

# Ruby 1.8 syntax
before_save :do_awesome, :if => -> { its_awesome_time?(Time.now) }
# Ruby 1.9 syntax
before_save :do_awesome, if: -> { its_awesome_time?(Time.now) }

原谅我使用这个蹩脚的例子,1.9 也引入了新的 lambda 语法,和老式的=>放在一起看起来的确有点傻,但是和新哈希语法在仪器却很不错。当然,在 Ruby1.8 下面,我们使用以下方式:

# Ruby 1.8 syntax
before_save :do_awesome, :if => lambda { awesome_time?(Time.now) }


这看起来也不错。

我错了吗?

似乎有很多很多人都支持新的语法,他们都直接开始一个 Ruby1.9 项目,并直接使用新的哈希语法,但我仍拒绝使用它。

有人可以告诉我,为什么哈希引号'比性感的哈希火箭'更好吗?


翻译完了,有关这篇文章的读者评论,那也是相当的精彩,能翻墙的还是自己去看看吧。

下面随便摘一段:(观点针锋相对啊!)


HI PHIL!

As promised, my retort:

I think all of your points mentioned above are valid. However, I think you omis one.

When I use hashes, 99% of the time I want a symbol (something immutable) as the key. Therefore, in the majority of cases, I find the new hash syntax pleasing. For example, consider initializing a connection to AWS S3 using the popular fog gem. You might do something like this:

con = Fog::Storage.new( provider: ‘AWS’, aws_secret_access_key: ‘ABC123′, region: ‘eu-west-1′, aws_access_key_id: ‘ABC123′ )

See how nice and concise that is? It’s almost prose! I’ve used a similar ‘syntax’ in the paragraph above. retort: “I like symbols as keys”.

To comment on a couple of other points raised:

The new syntax is not the only improvement in Ruby 1.9. In fact one might go far as to say it is a trivial one. Fibers, native Object#tap (rather than using Rail’s implementation) and others are all arguably more useful. Therefore those using the new syntax in gems are not always doing so for “no good reason”.

As for thinking one can treat the new hash syntax like JavaScript, well I would chalk that up to user error. It’s still a hash (with a symbol as a key) and will behave as such. That it does not use Ruby’s symbol to denote that the key is a hash could arguably be confusing, but then it is a convenience. Making it explicit would result in the old syntax.

To quote that infalible source of teenage wisdom Road Trip:

“That’s why they call it a shortcut. If it was easy it would just be the way.”

Anyway, just a few thoughts. As I mentioned, I think all your points are valid. Wrong, but valid ;)


I also dislike the new hash syntax. “When I use hashes, 99% of the time I want a symbol (something immutable) as the key. ” is a fallacy, IMHO. In fact, it’s much more I/O friendly to have hashes full of strings. Anyone using rails is probably working with hashes full of strings more than 1% of the time.

I also don’t like having 2 ‘equivalent’ ways of doing something. Honestly, the old way, even if hard to type for some (cough*use vi*cough) was ‘the’ way to create hashes. This is just one more thing people have to learn. This violates ‘simpler is better’ by introducing not only a new format for creating hashes, but also a new way to declare symbols. It’s also creating a need for ‘convention’ among programmers — not that this is bad, but it’s one more bullet point people trying to adhere to a given form need to check.


也许是这篇文章标题的缘故吧,看到评论还是以反对者居多 (几乎一边倒), 貌似从 1.8 过来的人都喜欢老式的,从其他语言过来的新人,比较习惯新式语法,因为他们都认为=>很难输入,事实上,我也是觉得麻烦,并且设定了专门的快键,用来输入`=> '. 但是新式语法又会给一些学习 Ruby 的新人带来不小的困扰。

例如:

hash = { test: hash }
# => { :test => ‘hash’ }
hash[:test]
# => ‘hash’



foo = { bar: 'I am bar' }  

2 print foo[bar] # 错误

3 print foo['bar'] # 错误

4 print foo[bar:] # 错误

5 print foo[:bar] # 这才正确, 对于新人, 一定很晕.


foo = { :bar => 'I am bar' }  

print foo[:bar] # 一致性很明显, 通过:bar定义, 也通过:bar来引用key.


你很难向新人解释,为什么通过第一行的方式定义,输出结果冒号跑到前面去了?foo 定义和后续使用方式的一致性,对一个语言,是一个很大的伤害,而在 Ruby1.8 中,更不用提如果 key 和 value 都是 Symbol 的话,看起来有多别扭了。

不过这也是仁者见仁,智者见智的事情,个人也比较倾向于作者以及评论观点,这样一个改变,虽然有一点好处,对于语言自身而言,所带来的代价是不菲的。而且这个修改,个人应该还是以 Matz 个人的想法居多一些,这也是一个语言被某一个人 (或极小一群人所掌控) 的坏处吧。

总的来说,从这个文章以及评论得到了一个结论就是:

考虑到编码的一致性,以及阅读的方便性 (=> 很直观), 在使用 Ruby 时,还是老老实实的使用 1.8 哈希语法吧。不过如果把 Rails 自身作为一个独立于 Ruby 语言自身的 DSL 来考虑的话,使用新哈希语法也是不错的,至少风格上,相对来说更加统一了

或者至少,除了命名参数以及哈希定义之外,在其他地方,应该使用=> .(事实上,即使是命名参数,如果跨行写,还是 1.8 语法更直观啊) 至于输入问题,完全可以靠编辑器来解决嘛。至少对我来说,无论是定义哈希还是输入=> , 都是很快的。

HASH ROCKET IS VERY SEXY!

主席辛苦了! 我用=>比较多 :>

匿名 #2 2012年04月17日

I love hash rocket !!!

HASH ROCKET IS VERY SEXY!

如果没有 symbol,新语法倒是很简洁;可是对于已经充满 symbol 的 ruby 世界,新语法让问题变糟了。。。反正我自己是看着有点头昏混淆,当然,如果没有编辑器的话:比 => 要少敲一次键盘 :)

我一直还是用 => 。。。。

#5 楼 @donnior => 太常用了,我直接设定为 C-> 快键。

原来它又个这么酷的名字哈希火箭,我好喜欢这个词

#5 楼 @donnior 少三次 空格,=, >

vim 里 snipmate 直接用冒号

snippet :
    :${1:key} => ${2:"value"}${3}

我也不太喜欢,尤其当 value 是 Symbol 时:

link_to 'edit', edit_post_path, class: :post

HASH ROCKET IS VERY SEXY! 👍

#8 楼 @kenshin54 还有一个太空船

<=>


用新 hash 语法最难受的地方还是 符号 和 : 间不能有空格

需要 登录 后方可回复, 如果你还没有账号请 注册新账号