与Ruby中IRB的方法调用混淆

时间:2013-03-07 11:09:52

标签: ruby

我正在使用方法定义并在IRB的main中调用它们。

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"

1 个答案:

答案 0 :(得分:4)

在Ruby中,您可以在没有接收器且没有参数列表的情况下调用方法。但是,这意味着存在歧义:foo是否意味着“隐式接收器foo上的调用方法self没有参数,即相当于self.foo()”或者是否意味着“取消引用变量foo”? Ruby无法知道你的意思,所以有一些简单的规则。

对于局部变量,规则是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。)