【问题标题】:Upcased method is not detected未检测到大写的方法
【发布时间】:2014-10-20 11:03:45
【问题描述】:

以下定义了一个具有大写名称的方法,并尝试调用它,但失败了:

class Module
  def Foo; puts "foo" end
end

class A
  Foo
end
# => uninitialized constant A::Foo

我知道同名常量的存在优先于方法查找,但在这种情况下没有这样的常量。

如果我将其作为一种方法进行消歧,则检测到该方法:

class A
  Foo()
end
# => foo

方法名不大写时,查找不会失败。

class Module
  def foo; puts "foo" end
end

class A
  foo
end
# => foo

为什么方法查找会因不明确的 upcased 方法而失败?

【问题讨论】:

    标签: ruby methods


    【解决方案1】:

    Ruby 具有灵活的消息发送语法。特别是,您可以不使用接收器,也可以不使用参数列表。如果两者都做,那么这种无接收无参数的消息发送在语法上与变量解引用没有区别。

    因此,我们需要一些规则来区分无接收无参数消息发送和变量解引用之间的歧义。这些规则很简单:

    • 对于实例变量、类变量和全局变量,没有歧义
    • 对于局部变量,这样的构造总是被解释为消息发送,除非局部变量在范围内,否则它被解释为变量解引用
    • 对于常量,它总是被解释为变量解引用

    由于这种歧义仅在发送无接收者无参数消息时出现,因此可以通过添加接收者或参数列表轻松解决。

    【讨论】:

    • 是什么让常量的大小写不同于局部变量?
    • 消息发送和变量解引用之间的区别是静态的。找出哪些局部变量在作用域内可以静态完成,但对于常量,它相当于解决停止问题。或者更糟:module Foo; Bar = :baz end; if rand > 0.5 then include Foo end; Bar # is Bar in scope or not?
    • 我明白了。我觉得我明白了(但我仍在掌握它)。
    猜你喜欢
    • 2014-12-23
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    相关资源
    最近更新 更多