【问题标题】:Supporting Ruby 1.9's hash syntax in Ruby 1.8在 Ruby 1.8 中支持 Ruby 1.9 的哈希语法
【发布时间】:2012-03-30 10:54:34
【问题描述】:

我正在为我的代码中的哈希使用{key: 'value'} 语法编写一个Ruby gem。我的测试都在 1.9.x 中通过,但我(可以理解)在 1.8.7 中得到 syntax error, unexpected ':', expecting ')'

是否有支持 1.8.x 的最佳实践?是否需要使用我们的老朋友=> 重写代码,还是有更好的策略?

【问题讨论】:

  • Ruby 1.8 即将淡出。你不需要支持它。
  • 这是一种流行的观点吗?我当然在寻找其他 Gem 作者正在做什么的输入。我知道在 Ruby 社区内有一个很大的推动力,就是让每个人都上 1.9 的火车。我个人不介意留下 1.8。

标签: ruby hash syntax backwards-compatibility ruby-1.8


【解决方案1】:

我认为你运气不好,如果你想支持 1.8,那么你必须使用=>。像往常一样,我会提到你必须在 1.9 的某些情况下使用=>

  1. 如果键不是符号。请记住,任何对象(符号、字符串、类、浮点数等)都可以是 Ruby 哈希中的键。
  2. 如果您需要引用的符号::'this.that'
  3. 如果您将 MongoDB 用于几乎任何事情,您将使用 :$set => hash 之类的东西,但 $set: hash 是语法错误。

回到我们定期安排的节目。

为什么我说你不走运? Hash 文字语法(两者)在解析器中是硬连线的,我认为你不会很幸运地从你的 gem 中修补解析器。 Ruby 1.8.7's parse.y 有话要说:

assoc    : arg_value tASSOC arg_value
             {
                 $$ = list_append(NEW_LIST($1), $3);
             }
         ;

tASSOC=>,所以哈希文字是硬连线使用=>1.9.3's 是这样说的:

assoc    : arg_value tASSOC arg_value
             {
             /*%%%*/
                 $$ = list_append(NEW_LIST($1), $3);
             /*%
                 $$ = dispatch2(assoc_new, $1, $3);
             %*/
             }
         | tLABEL arg_value
             {
             /*%%%*/
                 $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
             /*%
                 $$ = dispatch2(assoc_new, $1, $2);
             %*/
             }
         ;

我们再次使用了粗箭头语法 (arg_value tASSOC arg_value) 和 JavaScript 样式 (tLABEL arg_value); AFAIK,tLABEL 也是限制哪些符号(没有:$set,没有:'this.that',...)可以与 JavaScript 样式语法一起使用的来源。当前主干 parse.y 匹配 1.9.3 的哈希字面量。

所以 Hash 文字语法是硬连线到解析器中的,如果你想支持 1.8,你会被粗箭头卡住。

【讨论】:

  • 非常好的和彻底的答案,mu。看起来我可能不得不重写使用 JS 样式语法的实例。只希望有一种方法可以在不编写遗留代码的情况下支持遗留版本。不过,这可能是最好的选择。
【解决方案2】:

Ruby 1.8.7 不支持新的哈希语法。

如果你迫切需要非 YARV 基于 c 的 Ruby 实现的哈希语法,那么有一个完全不受支持的 1.8 头分支,所以你 can 这样做

rvm install ruby-head --branch ruby_1_8 ; rvm ruby-head
ruby -v
ruby 1.8.8dev (2011-05-25) [i386-darwin10.7.0]

但升级到 1.9 是可行的方法。

【讨论】:

  • 我认为 JackCA 的目的是提供一个 Ruby 1.8 用户可以使用的 gem,而不是 JackCA 使用的是 Ruby 1.8。所以我认为这不会有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多