以下是一些代码:
def func
def func
1
end
end
接着我在irb
中尝试了以下操作:
func
func.func
func
并获取结果:
:func
1
1
能否有人解释一下发生了什么?我有点理解第一个输出,但不理解后面的。谢谢!
以下是一些代码:
def func
def func
1
end
end
接着我在irb
中尝试了以下操作:
func
func.func
func
并获取结果:
:func
1
1
能否有人解释一下发生了什么?我有点理解第一个输出,但不理解后面的。谢谢!
在全局作用域中,您可以在方法内部定义方法。方法定义返回一个带有其名称的符号。
func
时,它会被内部的func
重新定义。这就是为什么后续对func
的调用返回1
的原因。func.func
。尝试定义其他方法,您将能够在任何符号上调用它:def func
def func
1
end
end
def a
'a'
end
func.a
# 'a'
:asd.a
# 'a'
这很复杂。在Ruby中,这确实不应该起作用,但它确实起作用了。
def func
在顶层定义了一个全局方法。但是在Ruby中,它是如何工作的呢?实际上它使用了两种技巧:
Object
中,以便您可以从任何地方调用它(因为self
始终是一个Object
)private
,因为私有方法的规则是它们不能有“显式接收者”,也就是说,在调用它们时不能在对象和点之前放置。这是为了防止错误,例如如果我认为类Foo
有自己的puts
方法,但实际上它没有,Foo.new.puts
将引发错误,而不是调用全局的puts
。所以,如果你的代码只是这样的:
def func
1
end
1.func
1
上调用私有方法,因此它会崩溃。class A
def outer
def inner
3
end
end
end
x = A.new
y = A.new
x.outer
y.inner # calls the method defined by x
你的代码表现得如此奇怪,是因为你在顶层执行,此时...嵌套方法定义的当前行为是无用的。它应该被废除以打开未来的可能性(我会投票支持警告)。
self
只是一个 Object
。def func # normal private method in Object
def func # adds a normal instance method to the current class i.e. Object
1
end
end
Object.private_methods.include?(:func) # true
func # returns :func, but also now re-defines func to be a normal method on Object
Object.private_methods.include?(:func) # false
func.func # same as 1.func, which is OK because it's not private
func
上调用a
,但它返回了private method 'a' called for :func:Symbol (NoMethodError)
,Ruby 2.6.1p33 [x86_64-darwin18]。 - Sebastián Palmaruby 2.5.1p57
上可以运行。请在新控制台中尝试。 - mrzasaKernel
中,而Kernel
几乎包含了所有Ruby对象。只需在全局命名空间中定义a
方法,即可使1.a
、:foo.a
和"foo".a
正常工作。当调用foo.foo
时,您只需在第一个foo
调用的返回值上调用foo
即可。 - 3limin4t0r