Ruby 不能';我不理解`puts{}.class`和`puts({}.class)之间的区别`

Ruby 不能';我不理解`puts{}.class`和`puts({}.class)之间的区别`,ruby,Ruby,因为匿名块和散列块看起来大致相同。我在玩它。我做了一些认真的观察,如下所示: {}.class #=> Hash 好的,很酷。空块被视为散列 print{}.class #=> NilClass puts {}.class #=> NilClass 现在,为什么上面的代码显示与NilClass相同,但下面的代码再次显示了散列 puts ({}.class) #Hash #=> nil print({}.class) #Hash=> nil 有谁能帮我理解一下

因为匿名块和散列块看起来大致相同。我在玩它。我做了一些认真的观察,如下所示:

{}.class
#=> Hash
好的,很酷。空块被视为
散列

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

#=> NilClass
现在,为什么上面的代码显示与
NilClass
相同,但下面的代码再次显示了
散列

puts ({}.class)
#Hash
#=> nil
print({}.class)
#Hash=> nil
有谁能帮我理解一下上面的内容吗

我完全不同意Lindydancer的观点

您将如何解释以下内容:

print {}.class
#NilClass
print [].class
#Array=> nil
print (1..2).class
#Range=> nil
为什么与下面的
print[]类和
print(1..2).类不同

编辑

当调用
局部变量
方法
时,Ruby会抛出一个错误,如下所示:

name
#NameError: undefined local variable or method `name' for main:Object
#        from (irb):1
#        from C:/Ruby193/bin/irb:12:in `<main>'
名称
#NameError:main:对象的未定义局部变量或方法“name”
#来自(irb):1
#来自C:/Ruby193/bin/irb:12:in`'

现在,
{}
的情况就不一样了(因为
空代码块
散列
块之间也存在歧义)。作为IRB,这里也不确定它是
空块
还是
散列
。那么,当IRB遇到
print{}.class
{}.class
时,为什么没有抛出错误呢?

ruby的优先规则使
print{}.class
解释为
(print{}.class
)。当
print
显然返回
nil
时,
class
方法返回
\NilClass


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

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

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

您会遇到Ruby的一些细微差别,其中字符的含义根据上下文而有所不同。源代码的解释方式遵循以下规则,其中之一是
{}
在方法调用之后是闭包块,否则是散列构造函数

在整个语言中,根据上下文或语句中的位置,字符表示不同的意思是很常见的


示例: 用于方法调用或优先级的参数

print(1..5).class => NilClass
print (1..5).class => Range <returns nil>
星号
*
用于乘法或飞溅

1 * 5 => 5
[*1..5] => [1, 2, 3, 4, 5]
用于符号->过程或逻辑and的符号和

0 & 1 => 0
[1, 2, 3].map(&:to_s) => ["1", "2", "3"]
或者在您的例子中,大括号用于块闭包或散列

... hope it makes sense now ...

是 啊也许你是对的。但它绝不像林迪丹瑟所说的那样是为了优先权。这是错误的。我证明了。FYI
do;end.class
{}.class
在没有任何打印语句的情况下在
IRB
中键入时是不一样的。@IAMRUBUU是的,没有方法调用块就没有意义,因此
{}
本身(不是在方法调用之后)不能表示除空哈希之外的任何内容。关于“歧义性”:IRB不会因为不明确而抛出错误,它抛出错误是因为它既找不到局部变量,也找不到名为
name
@Lindydancer的方法。我提到了这个事实,但想知道为什么
{}
不明确?:)@Misha当我们将say
name
放入IRB时,如果它是一个方法或局部变量,当变量不是通过赋值操作创建的,或者某个方法定义了相同的变量时,这是一个歧义。由于歧义,Ruby抛出一个错误。这是事实。@theTinMan的可能重复不可能重复。这与链接完全不同。这是正确的解释。优先顺序决定操作的哪个部分首先发生。我们每周都会看到这个问题好几次。您可以通过适当地使用括号来控制优先级来解决此问题。@THINMAN的解释仍然不正确。你有没有尝试过什么,或者只是读了答案,并用链接映射,然后在这里说他是对的。试一试
(print(){}).class
。想想
(print{}).class
(print(){}).class
是否相同?因为
print{}.class
被解析为
(print(){})。class
其中
{}
是闭包块而不是散列。不要粗鲁无礼。我读了你的问题和答案。在我看来,这仍然是一个优先顺序问题。
Asterisk*用于乘法或splatting
,不要忘记使用它来重复数组
[1]*2=>[1,1]
和重复字符串
“1”*2=>“11”
<代码>&
也是一种设置操作:
[1,2]&[2]=>[2]
+
|
一样。而且“歧义”并不局限于Ruby,因为Perl也有同样的问题。哈哈@theTinMan并不意味着详尽无遗。我还把星号的另一种用法看作是一种隐喻的乘法,同样也有关于Perl的有趣的联合和交集——除了阅读Perl中的文件和正则表达式之外,从来没有做太多的事情。
... hope it makes sense now ...