Ruby respond_to_missing?打电话给超级好吗?

时间:2017-08-02 15:55:12

标签: ruby-on-rails ruby metaprogramming

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

2 个答案:

答案 0 :(得分:2)

这取决于类的实现以及您想要的#respond_to_missing?行为。查看ActiveSupport::TimeWithZone,它是Time的代理包装器。它试图模仿它,愚弄你认为它是Time的一个实例。例如,TimeWithZone#is_a?会在true传递时回复Time

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

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

因此,将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

答案 1 :(得分:1)

respond_to_missing?出现在Ruby版本1.9.2中,作为method方法的解决方案。这是Ruby核心提交者关于它的博客文章:http://blog.marc-andre.ca/2010/11/15/methodmissing-politely/

然而,调用super的原因是,如果您的逻辑返回false,则调用会将类层次结构冒泡到Object,返回false。如果您的类是实现respond_to_missing?的类的子类,那么您希望在逻辑返回false的情况下调用super。这通常是库代码的问题,而不是应用程序代码的问题。