Ruby respond_to_missing?打电话还是不打电话?

Pie*_*s C 5 ruby metaprogramming ruby-on-rails

查看Rails 代码库有时会respond_to_missing?调用 super,有时不调用。是否存在不应从 respond_to_missing 调用 super 的情况?

m. *_*org 3

这取决于类的实现和您想要的行为#respond_to_missing?。看一下ActiveSupport::TimeWithZone,它是 的代理包装器Time。它试图模仿它,欺骗你,让你认为它是 的一个实例Time。例如,当通过时TimeWithZone#is_a?会做出响应。trueTime

# Say we're a Time to thwart type checking.
def is_a?(klass)
  klass == ::Time || super
end
alias_method :kind_of?, :is_a?
Run Code Online (Sandbox Code Playgroud)

respond_to_missing?应该捕获 会捕获的案例method_missing,因此您必须查看这两种方法。TimeWithZone#method_missing将缺少的方法委托给Time而不是super.

def method_missing(sym, *args, &block)
  wrap_with_time_zone time.__send__(sym, *args, &block)
rescue NoMethodError => e
  raise e, e.message.sub(time.inspect, inspect), e.backtrace
end
Run Code Online (Sandbox Code Playgroud)

respond_to_missing?因此,将其委托给Time也是有道理的。

# Ensure proxy class responds to all methods that underlying time instance
# responds to.
def respond_to_missing?(sym, include_priv)
  return false if sym.to_sym == :acts_like_date?
  time.respond_to?(sym, include_priv)
end
Run Code Online (Sandbox Code Playgroud)