2

我在玩方法定义并在mainIRB 中调用它们。

def show
 p "hi"
end
#=> nil

show
#"hi"
#=> "hi"

self.show
#"hi"
#=> "hi"

上面说的很好理解。

现在让我们尝试一些不同的东西:

def Foo
 p "hi"
end
#=> nil

Foo
#NameError: uninitialized constant Foo
        #from (irb):4
        #from C:/Ruby193/bin/irb:12:in `<main>'

虽然调用Foo已引发上述错误,但以下如何删除该错误?

self.Foo
#"hi"
#=> "hi"
4

1 回答 1

4

在 Ruby 中,您可以在没有接收器和参数列表的情况下调用方法。但是,这意味着存在歧义:是指“在不带参数的隐式接收器上foo调用方法,即等效于”还是意味着“取消引用变量”?Ruby 不知道你的意思,所以有一些简单的规则。fooselfself.foo()foo

对于局部变量,规则是foo始终方法调用,除非在解析foo静态已知为局部变量。那么,什么时候静态地知道它是一个变量呢?当对该变量进行赋值时,该变量在使用前已解析(但不一定执行!)。

例子:

foo        # method call

if false
  foo = 42 # will never be executed, but *will* be parsed
end

foo        # variable dereference, since the `foo` assignment was parsed

对于常量变量,规则更简单:Foo总是解释为常量解引用。时期。

那么,如何调用具有这样名称的方法呢?简单:就像我说的,歧义只出现在没有参数列表和显式接收器的方法调用中。因此,如果我们添加其中一个或两个,Ruby 将知道我们正在尝试调用方法而不是取消引用变量:

foo()
self.foo
self.foo()

Foo()
self.Foo
self.Foo()

当然,在您上面给出的示例中,只有第一个可以工作。当您在顶层定义一个方法时,它会作为private方法添加到Object,并且private方法只能在没有显式接收器的情况下调用,即使该接收器是self。所以,self.Foo不会工作,因为Foo是私人的。(除了在 IRb 中,为了方便起见,顶级方法是public.)

于 2013-03-07T13:05:54.660 回答