什么是Python相当于Ruby的method_missing方法?我尝试过使用__getattr__但是这个钩子也适用于字段.我只想拦截方法调用.Python的方法是什么?
在Ruby中,对象有一个方便的方法method_missing,允许人们处理甚至没有(显式)定义的方法的方法调用:
当obj被发送一个它无法处理的消息时,由Ruby调用.symbol是被调用方法的符号,args是传递给它的任何参数.默认情况下,解释器在调用此方法时会引发错误.但是,可以覆盖该方法以提供更多动态行为.下面的示例创建一个类Roman,它响应名称由罗马数字组成的方法,返回相应的整数值.
class Roman
 def romanToInt(str)
   # ...
 end
 def method_missing(methId)
   str = methId.id2name
   romanToInt(str)
 end
end
r = Roman.new
r.iv      #=> 4
r.xxiii   #=> 23
r.mm      #=> 2000
例如,Ruby on Rails使用它来允许调用诸如的方法find_by_my_column_name.
我的问题是,其他语言支持的等价物method_missing,以及如何在代码中实现等效语言?
我正在学习Ruby中的元编程,我只是尝试通过method_missing和define_method定义缺失的方法.我有一些意想不到的行为,我想知道是否有人可以解释这一点.这是我的班级:
class X
  def method_missing(m, *args, &block)
    puts "method #{m} not found. Defining it."
    self.class.send :define_method, m do
      puts "hi from method #{m}"
    end
    puts "defined method #{m}"
  end  
end
现在,这段代码:
x = X.new
x.some_method
puts
x.some_method
puts
puts x
产生输出:
method some_method not found. Defining it.
defined method some_method
hi from method some_method
method to_ary not found. Defining it.
defined method to_ary
#<X:0x007fcbc38e5030>
我没有得到的是最后一部分:为什么Ruby在调用puts时调用to_ary?为什么Ruby会尝试将我的对象转换为数组只是为了打印它?
我用Google搜索并发现了以下相关链接:
这些也讨论了method_missing和to_ary陷阱,但没有具体说明为什么puts会调用to_ary.
我还应该提一下,当我定义一个to_s时,行为不会改变,例如
def to_s
  "I'm an instance of X"
end
然后输出"puts x": …
我对静态类型语言没有多少经验(目前正在学习Scala并喜欢它!)但我注意到的一件事是它们似乎没有像Ruby的method_missing或ColdFusion的onMissingMethod那样的东西.静态类型语言是否存在一些固有的限制,可以防止或使其变得困难?
Python中是否有任何可用于拦截消息(方法调用)的技术,如Ruby中的method_missing技术?
如果我的Rakefile没有找到具有特定名称的任务,我想rake根据某些规则创建一个新任务,如果存在缺少任务名称的文件.但如果没有,我想回到默认("不知道如何构建任务'foo'!").
简而言之,method_missingRake有吗?
当我调用一个不存在的方法时,method_missing会告诉我该方法的名称.当我尝试访问尚未设置的变量时,该值很简单nil.
我试图动态拦截对nil实例变量的访问,并根据被访问变量的名称返回一个值.最接近的等价物是PHP __get.Ruby中有没有相同的功能?
我有几个扩展方法缺失的模块:
module SaysHello
    def respond_to?(method)
        super.respond_to?(method) || !!(method.to_s =~ /^hello/)
    end
    def method_missing(method, *args, &block)
        if (method.to_s =~ /^hello/)
            puts "Hello, #{method}"
        else
            super.method_missing(method, *args, &block)
        end
    end
end
module SaysGoodbye
    def respond_to?(method)
        super.respond_to?(method) || !!(method.to_s =~ /^goodbye/)
    end
    def method_missing(method, *args, &block)
        if (method.to_s =~ /^goodbye/)
            puts "Goodbye, #{method}"
        else
            super.method_missing(method, *args, &block)
        end
    end
end
class ObjectA
    include SaysHello
end
class ObjectB
    include SaysGoodbye
end
这一切都运作良好,例如ObjectA.new.hello_there输出"Hello, hello_there".同样,ObjectB.new.goodbye_xxx产出"Goodbye, xxx".respond_to?也有效,例如 …
我在这里找到了这个方法.
  start = DateTime.now
  sleep 15
  stop = DateTime.now
  #minutes
  puts ((stop-start) * 24 * 60).to_i
  hours,minutes,seconds,frac = Date.day_fraction_to_time(stop-start)
我有以下错误:
`<main>': private method `day_fraction_to_time' called for Date:Class (NoMethodError)
我检查了/usr/lib/ruby/1.9.1/date.rb,我发现了它:
def day_fraction_to_time(fr) # :nodoc:
  ss,  fr = fr.divmod(SECONDS_IN_DAY) # 4p
  h,   ss = ss.divmod(3600)
  min, s  = ss.divmod(60)
  return h, min, s, fr * 86400
end
但如果我用ruby1.8运行它,我没有问题./usr/lib/ruby/1.8/date.rb给了我:
  def self.day_fraction_to_time(fr)
    ss,  fr = fr.divmod(SECONDS_IN_DAY) # 4p
    h,   ss = ss.divmod(3600)
    min, s  = ss.divmod(60)
    return h, …method-missing ×10
ruby ×7
python ×2
coldfusion ×1
comparison ×1
datetime ×1
objective-c ×1
oop ×1
rake ×1
scala ×1