有没有办法判断 `method_missing` 是否被显式调用?
Is there a way to tell if `method_missing` was explicitly called?
从方法定义中,有没有办法判断方法 method_missing
是被显式调用还是作为挂钩方法被调用?
使用方法 initialize
,可以通过执行以下操作来判断它是被显式调用还是作为钩子调用:
class A
def initialize
puts caller
end
end
当作为钩子调用时,方法 initialize
有一行 new
:
a = A.new
# => ...:in `new'
# => ...
# => ...:in `<main>'
显式调用时,没有这样一行(除非从new
显式调用):
a.send(:initialize)
# => ...
# => ...:in `<main>'
但是当我用method_missing
做类似的事情时,我无法区分这两种情况:
class A
def method_missing *;
puts caller
end
end
a.foo
# => ...
# => ...:in `<main>'
a.method_missing
# => ...
# => ...:in `<main>'
与 initialize
不同,is invoked explicitly via the Class#new
, the BasicObject#method_missing
由 Ruby 解释器调用:
Invoked by Ruby when obj is sent a message it cannot handle. symbol is
the symbol for the method called, and args are any arguments that were
passed to it. By default, the interpreter raises an error when this
method is called. However, it is possible to override the method to
provide more dynamic behavior.
Kernel#caller
将不包括执行堆栈跟踪中的那些位置,从那里 Ruby 解释器调用 method_missing
如果那是你正在寻找的。
您可以检查第一个参数:
class A
def method_missing(name = nil, *)
if name
puts "called via `#{name}'"
else
puts "called directly"
end
end
end
A.new.foo
#=> called via `foo'
A.new.method_missing
#=> called directly
从方法定义中,有没有办法判断方法 method_missing
是被显式调用还是作为挂钩方法被调用?
使用方法 initialize
,可以通过执行以下操作来判断它是被显式调用还是作为钩子调用:
class A
def initialize
puts caller
end
end
当作为钩子调用时,方法 initialize
有一行 new
:
a = A.new
# => ...:in `new'
# => ...
# => ...:in `<main>'
显式调用时,没有这样一行(除非从new
显式调用):
a.send(:initialize)
# => ...
# => ...:in `<main>'
但是当我用method_missing
做类似的事情时,我无法区分这两种情况:
class A
def method_missing *;
puts caller
end
end
a.foo
# => ...
# => ...:in `<main>'
a.method_missing
# => ...
# => ...:in `<main>'
与 initialize
不同,is invoked explicitly via the Class#new
, the BasicObject#method_missing
由 Ruby 解释器调用:
Invoked by Ruby when obj is sent a message it cannot handle. symbol is the symbol for the method called, and args are any arguments that were passed to it. By default, the interpreter raises an error when this method is called. However, it is possible to override the method to provide more dynamic behavior.
Kernel#caller
将不包括执行堆栈跟踪中的那些位置,从那里 Ruby 解释器调用 method_missing
如果那是你正在寻找的。
您可以检查第一个参数:
class A
def method_missing(name = nil, *)
if name
puts "called via `#{name}'"
else
puts "called directly"
end
end
end
A.new.foo
#=> called via `foo'
A.new.method_missing
#=> called directly