ruby - object 与 fixnum 的比较

标签 ruby

我希望能够将对象与 fixnums 进行比较。

class Dog
  include Comparable
  def <=>(other)
    1
  end
end

鉴于上面的类(class),为什么这样做:

dog = Dog.new
array = [2, 1, 4, dog]
array.min
=> 1

但这不是:

dog = Dog.new
array = [dog, 2, 1, 4]
array.min
ArgumentError: comparison of Fixnum with Dog failed
    from (irb):11:in `each'
    from (irb):11:in `min'
    from (irb):11

当对象是第一个元素时,为什么我不能将对象与数字进行比较? 有什么办法可以解决这个问题吗?我希望 Dog 对象在与数组中的任何其他值进行比较时始终是最大值,这就是我在 <=> 方法中将其设置为 1 的原因。

谢谢!

最佳答案

要与数字类型进行比较,您可以实现 coerce :

class Dog
  include Comparable

  def initialize(age)
    @age = age
  end

  def <=>(other)
    @age <=> other
  end

  def coerce(numeric)
    [numeric, @age]
  end
end

Dog.new(5) <=> Dog.new(5)  #=>  0
Dog.new(5) <=> 1           #=>  1
         1 <=> Dog.new(5)  #=> -1

[1, 3, Dog.new(2)].sort
#=> 1, #<Dog @age=2>, 3]

不执行<=>也可以实现上面的排序和 coerce使用 sort_by :

class Dog
  attr_accessor :age

  def initialize(age)
    @age = age
  end
end

[1, 3, Dog.new(2)].sort_by { |obj| obj.is_a?(Dog) ? obj.age : obj }
#=> 1, #<Dog @age=2>, 3]

还有 min_by max_by .

关于ruby - object 与 fixnum 的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24702398/

相关文章:

ruby-on-rails - 让 Bundler 从 Gemfile/s 中解析并加载依赖项,在 gem/s 中加载 :path

ruby-on-rails - 对于经验丰富的 Ruby/Rails 开发人员来说,HAML 是更好的工具吗?

jquery - 满足条件时跳过某些字段的验证

c# - 为什么 C# ProcessStartInfoRedirectStandardOutput 会导致 xcopy 进程失败

ruby - 如何在同一端口上提供 Cramp::Websocket 和普通 Rack 应用程序?

ruby-on-rails - Twitter 的 Omniauth 服务不可用错误

ruby-on-rails - 如何 "crawl"只有根 URL 与 Anemone ?

ruby-on-rails - Actionmailer 是如何工作的?

ruby - 重载 Ruby 的 [...] 数组创建速记

mysql - 无法按虚拟属性对事件管理中的记录进行排序