我有一个名为AB的模块。现在它看起来像这样:
module AB
extend self
def some_method(hash)
....
end
....
end
我们像这样使用它:AB.some_method(:thing =>:what,:etc =>'你得到了主意')。用户必须传递大约六个字符串,我想变成动态方法,而不是AB.some_method(:thing =>:无论......)他们只是打电话给AB .whatever(...)或AB :: what(...)。我以为我可以用method_missing做到这一点,但我想我不明白。我做了这样的事情:
module AB
def method_missing(name,*args)
super unless THINGS.include?(name.to_s)
...
end
end
但是在尝试调用AB :: what时我从未涉及过该方法。我想过使用define_method循环使用THINGS,但我不确定如何定义带参数的方法。
任何帮助表示感谢。
答案 0 :(得分:4)
第二个代码示例中的问题是method_missing
应该声明为self.method_missing
。以下按预期工作:
module AB
THINGS = %w(whatever)
def self.method_missing(name, *args)
super unless THINGS.include?(name.to_s)
"responding to #{name}"
end
end
p AB.whatever #=> "responding to whatever"
p AB.something #=> NoMethodError
答案 1 :(得分:0)
我认为您可以使用两种不同的方法,一种是动态定义方法,另一种是依赖method_missing
。以下是两者的示例:
# first approach, define methods
class MyClassDefine
def some_method args
p args
end
[:foo,:bar].each do |name|
define_method name do |args|
# assume args is a hash, fix me
some_method args.merge({:thing => name})
end
end
end
# second approach, use method_missing
class MyClassMissing
def some_method args
p args
end
def method_missing name, args
super unless [:foo, :bar].include? name
# again, assuming argument is a hash
some_method args.merge(:thing => name)
end
end
mcd = MyClassDefine.new
mcd.foo :etc => 'you get idea'
#=> {:etc=>"you get idea", :thing=>:foo}
mcm = MyClassMissing.new
mcm.foo :etc => 'you get idea'
#=> {:etc=>"you get idea", :thing=>:foo}
这里剩下的工作是覆盖方法传递方法而不是哈希的情况作为参数。