Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何实施';可比';如果父类已经有一个'==';_Ruby - Fatal编程技术网

Ruby 如何实施';可比';如果父类已经有一个'==';

Ruby 如何实施';可比';如果父类已经有一个'==';,ruby,Ruby,我有一个库类,它提供了相等和不相等的方法。我从中派生出另一个类,与父类不同,它引入了排序关系,也就是说,请求派生类的两个元素是有意义的,哪一个更小。特别是,可以对派生类的对象数组进行排序 我的第一个方法是 class MyClass < LibraryClass def <(other) ... end def <=>(other) return 0 if self == other return -1 if self < oth

我有一个库类,它提供了相等和不相等的方法。我从中派生出另一个类,与父类不同,它引入了排序关系,也就是说,请求派生类的两个元素是有意义的,哪一个更小。特别是,可以对派生类的对象数组进行排序

我的第一个方法是

class MyClass < LibraryClass
  def <(other)
    ...
  end
  def <=>(other)
    return 0 if self == other
    return -1 if self < other
    return 1
  end
  # code for operators > <= >= is not shown here....
end
class MyClass
这似乎是可行的,但我认为最好改为[sic]
Comparable
,因为这将免费提供大量其他方法

  • Comparable
    的描述说我必须实现
    操作符,以及其他操作符,包括
    ==
    =将自动实现。但是,我已经对父类中的
    =
    操作符感到满意,因此不应该生成新的相等方法

  • 我想使用父类中的
    =
    操作符测试是否相等。如果我实现了
    操作符,并且
    Comparable
    根据
    操作符实现了
    =
    操作符,那么我将以递归调用结束


  • 对于表达式
    self==other
    ,如何指定应调用父类的
    =
    运算符?

    include
    使
    MyClass
    的超类
    compariable
    LibraryClass
    的超类
    compariable
    。因此,在
    Comparable
    中实现
    ==
    会覆盖在
    LibraryClass
    中实现
    =

    然后,您可以使用与
    LibraryClass
    中相同的版本再次覆盖
    =
    中的
    =

    class MyClass < LibraryClass
      include Comparable
    
      def <=>(other)
        # whatever
      end
    
      define_method(:==, LibraryClass.public_instance_method(:==))
    end
    
    class MyClass
    首先,让我们创建一个覆盖
    范围的Range子类

    class OddRange < Range
      def ==(other)
        !super
      end
    end
    
    OddRange.new(1, 10) == OddRange.new(2, 7)
      #=> true
    
    其中不包括可比较的
    。现在,让我们创建一个子类
    OddRange
    ,并检查它的行为

    class MyRange < OddRange
    end
    
    MyRange.ancestors
      #=> [OddRange, Range, Enumerable, Object, Kernel, BasicObject]
    MyRange.instance_method(:==).owner
      #=> OddRange 
    rng1 = MyRange.new(1, 5)
    rng2 = MyRange.new(2, 4)
    rng3 = MyRange.new(1, 5)
    rng1 == rng2
      #=> true 
    rng1 == rng3
      #=> false
    
    没有意外

    如果我们不希望
    compariable#=
    覆盖
    MyRange#=
    ,我们可以执行以下操作

    class MyRange
      def ==(other)
        method(__method__).super_method.super_method.call(other)  
      end
    end
    
    class MyRange
      (instance_methods & OddRange.instance_methods(false)).each do |m|
        define_method(m) do |other|
          method(__method__).super_method.super_method.call(other)  
        end
      end
    end
    
    rng1 = MyRange.new(1, 5)
    rng2 = MyRange.new(2, 4)
    rng3 = MyRange.new(1, 5)
    rng1 == rng2
      #=> true
    rng1 == rng3
      #=> false
    rng1 <= rng3
      #=> true
    
    此“跳过”可比较的
    并使用
    的方法
    :=。看

    现在,让我们向
    OddRange
    添加另一个实例方法

    class OddRange
      def :<=(other)
        (self.begin <=> self.begin) <= 0
      end
    end
    
    rng1 = MyRange.new(1, 5)
    rng2 = MyRange.new(2, 4)
    rng1 <= rng2
      #=> false
    
    MyRange
    。更一般地说,如果我们不希望
    compariable
    实例方法覆盖任何
    OddRange
    实例方法(可能会随着时间的推移而改变),我们可以执行以下操作

    class MyRange
      def ==(other)
        method(__method__).super_method.super_method.call(other)  
      end
    end
    
    class MyRange
      (instance_methods & OddRange.instance_methods(false)).each do |m|
        define_method(m) do |other|
          method(__method__).super_method.super_method.call(other)  
        end
      end
    end
    
    rng1 = MyRange.new(1, 5)
    rng2 = MyRange.new(2, 4)
    rng3 = MyRange.new(1, 5)
    rng1 == rng2
      #=> true
    rng1 == rng3
      #=> false
    rng1 <= rng3
      #=> true
    
    类MyRange
    (instance_methods&OddRange.instance_methods(false))。每个都有|
    定义方法(m)do |其他|
    方法(方法)。超级方法。超级方法。调用(其他)
    结束
    结束
    结束
    rng1=MyRange.new(1,5)
    rng2=MyRange.new(2,4)
    rng3=MyRange.new(1,5)
    rng1==rng2
    #=>正确
    rng1==rng3
    #=>错误
    rng1为真
    

    1实际上没有必要重新定义下面的
    rng1
    rng2
    rng3

    你为什么拒绝Ruby方式?只需按照文档所说的去做。为什么它会以递归调用结束呢?你能澄清一下吗?@sawa:因为在我的设置中,my会调用==,这是Comparable的==,然后会再次调用my。但多亏了JörgWMittag发布的简明解决方案和CarySwoveland发布的优秀教程,我现在知道了如何正确地完成它。
     def <=(other)
        method(__method__).super_method.super_method.call(other)  
     end
    
    class MyRange
      (instance_methods & OddRange.instance_methods(false)).each do |m|
        define_method(m) do |other|
          method(__method__).super_method.super_method.call(other)  
        end
      end
    end
    
    rng1 = MyRange.new(1, 5)
    rng2 = MyRange.new(2, 4)
    rng3 = MyRange.new(1, 5)
    rng1 == rng2
      #=> true
    rng1 == rng3
      #=> false
    rng1 <= rng3
      #=> true