【问题标题】:How do you override the ruby case equality operator? (===)你如何覆盖 ruby​​ 大小写相等运算符? (===)
【发布时间】:2009-03-10 10:58:58
【问题描述】:

我有一个类,我想在 case 语句中与字符串和符号进行比较,所以我认为我只是为我的类覆盖了 ===() 方法,所有这些都是黄金。但是,我的 ===() 方法在 case 语句期间永远不会被调用。有什么想法吗?

这是一些示例代码,以及 irb 会话中发生的情况:

class A
   def initialize(x)
      @x=x #note this isn't even required for this example
   end
   def ===(other)
      puts "in ==="
      return true
   end
end

irb(main):010:0> a=A.new("hi")
=> #
irb(main):011:0> case a
irb(main):012:1> 当 "hi" 然后 1
irb(main):013:1> 其他 2
irb(main):014:1> 结束
=> 2

(它从不打印消息并且应该始终返回 true) 请注意,理想情况下我想做一个

def ===(other)
          #puts "in ==="
          return @x.===(other)
end

提前致谢。

【问题讨论】:

    标签: ruby overloading


    【解决方案1】:

    'case' 关键字之后的表达式是 === 表达式的右侧,而 'when' 关键字之后的表达式是表达式的左侧。所以,被调用的方法是 String.===,而不是 A.===。

    逆转比较的快速方法:

    class Revcomp
        def initialize(obj)
            @obj = obj
        end
    
        def ===(other)
            other === @obj
        end
    
        def self.rev(obj)
            Revcomp.new(obj)
        end
    end
    
    class Test
        def ===(other)
            puts "here"
        end
    end
    
    t = Test.new
    
    case t
    when Revcomp.rev("abc")
        puts "there"
    else
        puts "somewhere"
    end
    

    【讨论】:

    • 酷。这解释了它,它的工作原理!这种做案例陈述的方式是否违反直觉?
    • 好。是的,它看起来确实有点乱,但我没有对这个答案的语法考虑太多。你可能会想出一些更简洁的语法,或者你可以在你想在 LHS 上拥有的类中做一些邪恶的事情,比如覆盖 operator===。
    • 谢谢 - 我可以更简洁一点,但这也让我觉得我可能使用了错误的工具(案例)来完成这项工作,但它确实有效,所以谢谢你(我应该有昨天问这个)。
    • 没问题。你也可以做一些简单的事情,比如在你的类上有一个方法来返回你想在比较中使用的字符串。这样你就可以完全避免使用 === 做任何特别的事情。
    • 完全有道理:a.===(b) 的意思是“嘿,'a','b' 是你的成员吗?” Number 知道它是否是 Range 的成员是没有意义的,但 Range 应该知道 Number 是否在其内部。因此,'1..3 === 2' 和 'case 2 when 1..3' 的含义相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 2017-07-06
    • 2022-11-17
    • 1970-01-01
    • 2014-01-05
    相关资源
    最近更新 更多