IRB - Ruby 1.9.x哈希语法:{if:true}不等于{:if => true}

时间:2021-07-13 22:29:18

Long story short, I was writing a method that included an options argument, that will do certain stuff if the value for the key :if, evaluated to true. When I trying the hash in IRB using the new syntax I got a syntax error in IRB, the prompt stays open:

简而言之,我正在编写一个包含选项参数的方法,如果键的值为:if,则会执行某些操作。当我使用新语法在IRB中尝试哈希时,我在IRB中遇到语法错误,提示保持打开状态:

1.9.3p374 :010 > {if: true}
1.9.3p374 :011?>

Using the old syntax, works just fine:

使用旧语法,工作得很好:

1.9.3p374 :011 > {:if => true}
 => {:if=>true} 

All keywords that start a statement, exhibit the same behavior. E.g. def, do, module, case

所有启动语句的关键字都表现出相同的行为。例如。 def,do,module,case

Other reserved words that occur in the middle and class work just fine: else, end

在中间和类中发生的其他保留字工作正常:否则,结束

My question is: Is this expected behavior, a bug or a limitation?

我的问题是:这是预期的行为,错误还是限制?

1 个解决方案

#1


6  

It's challenging to reliably and unambiguously parse things in any language. This is especially true when you start using reserved words. And irb has to go beyond that and provide an interactive model on top of the parser, which is even harder. I personally don't think there's too much value in worrying about cases like this, either as a user of the language or as a maintainer. In my mind, it's better to simply figure out what works and avoid getting into these situations if possible.

用任何语言可靠而明确地解析事物是一项挑战。当您开始使用保留字时尤其如此。并且irb必须超越它并在解析器之上提供交互式模型,这更加困难。我个人并不认为担心这样的案件有太大的价值,无论是作为语言的用户还是作为维护者。在我看来,最好简单地找出哪些有效,并尽可能避免陷入这些情况。

You can see some similar behaviors in plain Ruby, outside irb. For example:

您可以在irb之外的纯Ruby中看到一些类似的行为。例如:

puts({if: true})  # no problem, behaves as expected in Ruby 1.9.3.
puts {if: true}   # raises a syntax error in Ruby 1.9.3

To answer your question, is it "expected behavior, a bug or a limitation", I'd say you should ignore irb and compare it to plain Ruby, and if you do this, it works fine. That means it has to be an irb bug.

要回答你的问题,它是“预期的行为,错误或限制”,我会说你应该忽略irb并将它与普通的Ruby进行比较,如果你这样做,它就可以正常工作。这意味着它必须是一个irb bug。

But is it possible or worthwhile to solve? @coreyward makes a good point in his comment that irb has to delay execution in most cases when it encounters an if. You'd have to look further to know for sure, but you may not be able to unambiguously interpret all cases like this.

但是有可能或值得解决吗? @coreyward在他的评论中提出了一个很好的观点,即当遇到if时,irb必须在大多数情况下延迟执行。你必须进一步了解,但你可能无法明确地解释所有这样的情况。

My advice: avoid this construct altogether if you can, and don't use reserved words for labels if you can avoid it!

我的建议:如果可以的话,完全避免这种结构,如果可以避免,不要使用保留字作为标签!

Here's a file you can run with plain Ruby (eg MRI). You should see {:if=>true} in the output to confirm it works.

这是一个可以用普通Ruby(例如MRI)运行的文件。您应该在输出中看到{:if => true}以确认它是否有效。

{if: true}
foo = {if: true}
# if MRI is working, should be able to execute this file without trouble.
p foo

#1


6  

It's challenging to reliably and unambiguously parse things in any language. This is especially true when you start using reserved words. And irb has to go beyond that and provide an interactive model on top of the parser, which is even harder. I personally don't think there's too much value in worrying about cases like this, either as a user of the language or as a maintainer. In my mind, it's better to simply figure out what works and avoid getting into these situations if possible.

用任何语言可靠而明确地解析事物是一项挑战。当您开始使用保留字时尤其如此。并且irb必须超越它并在解析器之上提供交互式模型,这更加困难。我个人并不认为担心这样的案件有太大的价值,无论是作为语言的用户还是作为维护者。在我看来,最好简单地找出哪些有效,并尽可能避免陷入这些情况。

You can see some similar behaviors in plain Ruby, outside irb. For example:

您可以在irb之外的纯Ruby中看到一些类似的行为。例如:

puts({if: true})  # no problem, behaves as expected in Ruby 1.9.3.
puts {if: true}   # raises a syntax error in Ruby 1.9.3

To answer your question, is it "expected behavior, a bug or a limitation", I'd say you should ignore irb and compare it to plain Ruby, and if you do this, it works fine. That means it has to be an irb bug.

要回答你的问题,它是“预期的行为,错误或限制”,我会说你应该忽略irb并将它与普通的Ruby进行比较,如果你这样做,它就可以正常工作。这意味着它必须是一个irb bug。

But is it possible or worthwhile to solve? @coreyward makes a good point in his comment that irb has to delay execution in most cases when it encounters an if. You'd have to look further to know for sure, but you may not be able to unambiguously interpret all cases like this.

但是有可能或值得解决吗? @coreyward在他的评论中提出了一个很好的观点,即当遇到if时,irb必须在大多数情况下延迟执行。你必须进一步了解,但你可能无法明确地解释所有这样的情况。

My advice: avoid this construct altogether if you can, and don't use reserved words for labels if you can avoid it!

我的建议:如果可以的话,完全避免这种结构,如果可以避免,不要使用保留字作为标签!

Here's a file you can run with plain Ruby (eg MRI). You should see {:if=>true} in the output to confirm it works.

这是一个可以用普通Ruby(例如MRI)运行的文件。您应该在输出中看到{:if => true}以确认它是否有效。

{if: true}
foo = {if: true}
# if MRI is working, should be able to execute this file without trouble.
p foo