Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 当方法调用原则上可以是常量时,为什么需要消除歧义?_Ruby_Methods_Syntax_Constants - Fatal编程技术网

Ruby 当方法调用原则上可以是常量时,为什么需要消除歧义?

Ruby 当方法调用原则上可以是常量时,为什么需要消除歧义?,ruby,methods,syntax,constants,Ruby,Methods,Syntax,Constants,方法调用通常可以忽略接收方和参数的括号: def foo; "foo" end foo # => "foo" 在上面的例子中,foo在方法调用和对潜在局部变量的引用之间是不明确的。如果没有后者,则将其解释为方法调用 然而,当方法名称原则上可以是一个常量名称时(即,当它以大写字母开头,并且仅由字母组成时),似乎需要消除歧义 def Foo; "Foo" end Foo # => NameError: uninitialized constant Foo Foo() # => "

方法调用通常可以忽略接收方和参数的括号:

def foo; "foo" end
foo # => "foo"
在上面的例子中,
foo
在方法调用和对潜在局部变量的引用之间是不明确的。如果没有后者,则将其解释为方法调用

然而,当方法名称原则上可以是一个常量名称时(即,当它以大写字母开头,并且仅由字母组成时),似乎需要消除歧义

def Foo; "Foo" end
Foo # => NameError: uninitialized constant Foo
Foo() # => "Foo"
self.Foo # => "Foo"

为什么会这样?为什么即使在没有同名常量的情况下,方法调用也需要与常量引用明确区分开来?

您提出了一个很好的问题。正如您所指出的,ruby希望将其视为常量,因此执行常量查找

但是,下面的代码片段显示了当前的行为,然后通过修改const_missing,您似乎获得了所需的行为。跟你说实话,我似乎什么也没打破

我的结论是,正如有人已经建议的那样,这只是一个设计决策,但这很奇怪,因为一般来说ruby支持约定而不是强制执行

或者我错过了一些情况,事情变得混乱,错误的事情发生了


外汇基金票据及债券;元素['#output'].html=元素['#output'].html+s.to_.gsub(“\n”,“
”).gsub(“,”)+“
”;结束 阶级 def self.to_ “我是伊玛班的” 结束 结束 定义IMA方法 “你好” 结束 不知道什么课 def self.to_ “一个班级” 结束 结束 def DontKnowWhatIAm “一种方法” 结束 放置“ImAClass:#{ImAClass}” 开始 放置“ImAMethod:#{ImAMethod}” 救援异常=>e 放入“混乱!#{e.message}” 结束 放置“ImAMethod():#{ImAMethod()}” 将“DontKnowWhatIAm:#{DontKnowWhatIAm}” 放置“DontKnowWhatIAm():#{DontKnowWhatIAm()}” 类模块 别名\u方法:旧的\u常量\u缺失,:常量\u缺失 def const_缺失(c) 如果self.response\u?C 自我发送 其他的 旧建筑失踪(c) 结束 结束 结束 福班 def自动控制杆 “我在酒吧” 结束 结束 放置“现在我们可以说:Foo::Bar,它就工作了!#{Foo::Bar}”
程序中任何给定点范围内的局部变量集都是按词汇定义的,因此可以静态确定,甚至早在解析时就可以确定。因此,Ruby甚至在运行之前就知道哪些局部变量在作用域中,因此可以区分消息发送和局部变量取消引用


常量首先通过词汇查找,然后通过继承(即动态)查找。运行前不知道哪些常量在作用域中。因此,为了消除歧义,Ruby总是假定它是一个常量,除非它显然不是,即它接受参数或有接收器或两者兼有。

这种差异背后没有什么大的原因。我只是希望foo的行为像foo(),如果作用域中没有局部变量foo的话。我认为它对创建DSL等很有用,但我认为没有理由让Foo表现得像Foo()。

谢谢你的回答。事实上,局部变量是在解析时定义的,这就是为什么
如果为false,那么Foo=43 end;foo#=>nil(而不是namererror)
@JörgWMittag这很有道理。那么这是为了提高效率?换言之,如果我们随意使用以大写字母开头的方法,那么所有这些方法都必须经过消歧过程。如果出于某种原因需要,您可以重写该行为(如我的答案所示)这是一个很好的答案。@MitchVanDuyn:真正的危险在于,您无法控制的第三方库只需在继承链的某个位置引入一个常量,就可以更改代码的含义。真令人惊讶!本物の松本さんですか。