无法理解`puts {}。class`和`puts({} .class)`之间的区别

时间:2013-03-11 12:55:21

标签: ruby

由于匿名块和哈希块看起来大致相同。我正在玩它。我正在做以下几个严肃的观察:

{}.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 [].classprint (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>'

{}现在不一样了(因为empty code blockHash阻止之间也存在歧义)。因为IRB也不确定它是empty block还是Hash。那么,当IRB遇到print {}.class{}.class

时,为什么错误没有出现

3 个答案:

答案 0 :(得分:6)

ruby​​的优先规则使print{}.class解释为(print{}).class。由于print显然会返回nilclass方法会返回#NilClass

编辑:正如在其他答案和问题更新中所讨论的那样,print{} 当然被解释为调用print一个块,而不是哈希。但是,这仍然是优先级,因为{}[](1..2)更强(并且强于do ... end)。

答案 1 :(得分:3)

在这种情况下,

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

print {}.class                            # => NilClass
print do;end.class                        # => NilClass

答案 2 :(得分:1)

你正在遇到Ruby的一些细微差别,根据上下文,字符意味着不同的东西。如何解释源代码遵循规则,其中之一是{}是闭包块,如果它遵循方法调用,否则是Hash构造函数。

在整个语言中,根据语句中的上下文或位置,字符意味着不同的东西是很常见的。


示例:

Parens ()用于方法调用或优先级

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>

Asterisk *用于乘法或splatting

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

用于符号的&符号& - &gt; proc或逻辑和

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

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

... hope it makes sense now ...