在以下示例中:
main.rb的
def main
obj = ExampleClass.new
def multiply(a, b, c, d)
return a * b * c * d
end
puts obj.multiply(1, 2, 3, 4) # this prints 24
end
main
ExampleClass.rb
class ExampleClass
def initialize
end
end
为什么multiply
方法现在是obj
实例的一部分? (main
方法不属于ExampleClass
定义)
答案 0 :(得分:3)
在没有附加class .. end
,module .. end
附件的情况下编写的代码将在特殊main
对象的上下文中逐步执行。可以使用以下方式引用此对象:
2.2.2 :001 > self
# => main
没有附加classes/modules
定义的方法被定义为main
对象的私有方法,因此,作为Ruby中几乎任何其他对象的私有方法:
2.2.2 :002 > def foo
2.2.2 :003?> 42
2.2.2 :004?> end
# => :foo
2.2.2 :005 > foo
# => 42
2.2.2 :006 > [].foo
# => NoMethodError: private method `foo' called for []:Array
2.2.2 :007 > [].send :foo
# => 42
因此,在您的代码中,main
方法(或者它可以是任何其他方法)位于main
对象的上下文中,因此可以从{{1}调用multiply
方法}}或ExampleClass.new
或来自任何其他类。
来源:Wikipedia
<强>更新强>
engineersmnky评论中的一些注释。
这不是main中的私有方法,而是BasicObject的私有方法(在2.0-2.2中)。
从2.3(和1.9.3)开始,这种方法甚至没有私有化。
它不一定是Array.new
的实例,例如class
因为类本身也会定义此方法,例如Class.new
答案 1 :(得分:2)
可能是因为变量obj
和定义方法multiply
的上下文都有Object
作为父/祖先。
如果您致电obj.class
,您将获得ExampleClass < Object
。假设您在控制台中,如果您拨打self.class
,则会收到Object < BasicObject
。因此,在您的代码中,您已为multiply
类定义了一个方法Object
。这就是multiply
是obj
实例的一部分的原因。
答案 2 :(得分:2)
在脚本范围定义的方法成为Object
的私有实例方法。 (在IRb中除外,它们成为Object
的公共实例方法。)
因此,main
是Object
的私有实例方法。
方法内部的方法定义不会创建嵌套方法,即multiply
不嵌套在main
中。相反,每次调用main
时,您都会创建一个名为multiply
的新方法作为Object
的实例方法。由于某些原因我不太清楚,它最终会成为 public 方法。
所以,会发生以下情况:
main
定义为Object
main
,然后将multiply
定义为Object
的公共实例方法multiply
,这是有效的,因为obj
是ExampleClass
的一个实例,它是Object
的子类,具有您的multiply
方法