4

由于匿名块和散列块看起来大致相同。我正在玩它。我做了以下一些严肃的观察:

{}.class
#=> Hash

好的,很酷。空块被认为是Hash

print{}.class
#=> NilClass
puts {}.class

#=> NilClass

现在为什么上面的代码显示相同NilClass,但​​下面的代码又显示了Hash

puts ({}.class)
#Hash
#=> nil
print({}.class)
#Hash=> nil

任何人都可以在这里帮助我了解上面发生了什么吗?

我完全不同意@Lindydancer的观点

您将如何解释以下几行:

print {}.class
#NilClass
print [].class
#Array=> nil
print (1..2).class
#Range=> nil

为什么与下面的print [].class和不一样print (1..2).class

编辑

local variablemethod调用发生歧义时,Ruby 会抛出一个关于以下事实的错误:

name
#NameError: undefined local variable or method `name' for main:Object
#        from (irb):1
#        from C:/Ruby193/bin/irb:12:in `<main>'

现在情况不一样了(因为或块{}之间也有歧义)。由于 IRB 在这里也不确定它是 a还是. 那么为什么当 IRB 遇到时错误没有抛出?empty code blockHashempty blockHashprint {}.class{}.class

4

3 回答 3

6

ruby 的优先规则使得print{}.class解释为(print{}).class. print显然返回nilaclass方法#NilClass返回。

编辑:正如在其他答案和问题更新中所讨论的那样,print{}当然被解释为使用块调用print,而不是散列。但是,这仍然与优先级有关,因为{}绑定比[](1..2)(并且比do ... end就此而言更强)。

于 2013-03-11T12:59:27.063 回答
3

{}在这种情况下被识别为传递给的块print,而[]明确表示空数组。

print {}.class                            # => NilClass
print do;end.class                        # => NilClass
于 2013-03-11T13:09:37.393 回答
1

您遇到了 Ruby 的一些细微差别,其中字符的含义取决于上下文。如何解释源代码遵循规则,其中之一是如果它遵循方法调用{},则为闭包,否则为 Hash 构造函数。

在整个语言中,根据上下文或语句中的位置,看到字符表示不同的事物是很常见的。


例子:

用于()方法调用或优先级的括号

print(1..5).class => NilClass
print (1..5).class => Range <returns nil>

方括号[]用于调用:[]方法或数组

print[].class => NoMethodError: undefined method `[]' for nil:NilClass
print([].class) => Array <returns nil>

*用于乘法或飞溅的星号

1 * 5 => 5
[*1..5] => [1, 2, 3, 4, 5]

符号&用于符号 -> proc 或逻辑和

0 & 1 => 0
[1, 2, 3].map(&:to_s) => ["1", "2", "3"]

或者在您的情况下,用于块闭包或哈希的大括号

... hope it makes sense now ...
于 2013-03-11T21:19:42.063 回答