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 ...
是 啊也许你是对的。但它绝不像林迪丹瑟所说的那样是为了优先权。这是错误的。我证明了。FYIdo;end.class
和{}.class
在没有任何打印语句的情况下在IRB
中键入时是不一样的。@IAMRUBUU是的,没有方法调用块就没有意义,因此{}
本身(不是在方法调用之后)不能表示除空哈希之外的任何内容。关于“歧义性”:IRB不会因为不明确而抛出错误,它抛出错误是因为它既找不到局部变量,也找不到名为name
@Lindydancer的方法。我提到了这个事实,但想知道为什么{}
不明确?:)@Misha当我们将sayname
放入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 ...