【发布时间】:2011-12-28 06:25:45
【问题描述】:
假设我有一个名为Foo 的Ruby 对象。此代码将产生以下结果:
Foo.bar.baz #=> "bar baz"
我怎么能做到这一点。 (我知道这似乎毫无意义,并且可能违反了几个约定,我只是想知道如何实现这一点。
【问题讨论】:
-
您可能想尝试在
Foo类中使用method_missing构建它。
假设我有一个名为Foo 的Ruby 对象。此代码将产生以下结果:
Foo.bar.baz #=> "bar baz"
我怎么能做到这一点。 (我知道这似乎毫无意义,并且可能违反了几个约定,我只是想知道如何实现这一点。
【问题讨论】:
Foo 类中使用 method_missing 构建它。
使用 method_missing 是一种可怕的 hackey 方式来做这件可怕的事情。
class Ouch
def initialize
@log = ""
end
def method_missing(method)
if @log.empty?
@log = method.to_s
else
@log += " #{method}"
end
self
end
def run
@log
end
end
现在你可以这样做了:
Foo = Ouch.new
Foo.bar.baz.run
>> "bar baz"
这就是说,如果您将Ouch 的实例传递给它不知道的方法(除了运行之外的任何方法),获取该方法的新方法并将其附加到存储为实例变量的日志字符串(@log ) 在您的实例中。最后,您需要一些提取器函数(如 run)让对象知道您已完成并希望返回累积的日志。希望这会有所帮助。
[编辑]
明确地说,method_missing 是一个“神奇”的 Ruby 函数,只要在对象无法识别的对象上调用方法时,就会调用该函数。
【讨论】:
class Object
def bar; [(instance_of?(String)? self : nil), "bar"].join(" ") end
def baz; [(instance_of?(String)? self : nil), "baz"].join(" ") end
end
Foo.bar.baz #=> "bar baz"
Foo.baz.bar #=> "baz bar"
【讨论】:
Foo.this.will.return.a.string 一样工作,比如 method_missing 或类似的东西。