我想在Ruby中创建一个对象,它可以在访问时懒惰地执行某些代码,例如当它被检查或比较时。使用method_missing
拦截消息很容易(可以处理object > 5
),但这并不包括访问该对象的所有尝试。
举例说明:
class Proxy
def initialize(obj)
@object = obj
end
def do_something
self
end
def do_something_else
self
end
def method_missing(msg, *args)
puts "I'm here #{msg}"
# Do something here
@object.send(msg, *args)
end
end
用法:
proxy = Proxy.new(5)
proxy.do_something.do_something_else
proxy > 2
# I'm here >
# true
2 > proxy
# ArgumentError: comparison of Fixnum with Proxy failed
我想知道是否有Proxy
的实现,2
实际上看到了5
而不是对象。
答案 0 :(得分:1)
不,你不能“检测Ruby对象什么时候是比较的右手边。”我将从此推断,希望正确地说,你实际试图解决的问题是如何使用在右侧的Ruby对象与不同类型的对象进行比较。
答案是定义coerce
方法。当对象位于比较运算符的右侧并且“不兼容”对象位于左侧时,将自动调用此方法。 LHS对象将作为参数提供,并且它应该返回一个包含两个元素的数组:“新”LHS和 兼容的RHS值。使用您的代理示例:
class Proxy
def initialize(obj)
@object = obj
end
def coerce(other)
if other.is_a?(Fixnum)
return [ other, @object.to_i ]
end
super
end
end
proxy = Proxy.new(5)
2 > proxy
# => false
当然,如果您希望Proxy类能够“包装”Fixnums以外的值,那么您的coerce
方法可能会更复杂。例如,如果@object
是字符串且other
是浮点数,您会怎么做?
当然,这仅在对象是RHS时处理。为了使其作为LHS工作,您还需要使用Comparable mixin。