如何检测Ruby对象何时是比较的右手边?

时间:2016-05-14 19:27:47

标签: ruby

我想在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而不是对象。

1 个答案:

答案 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。