ruby - 从数组强制

标签 ruby arrays coerce

假设我有这个简单的类(class):

class Color
  attr_accessor :rgb
  def initialize(ary)
    @rgb = ary
  end
  def +(other)
    other = Color.new(other) unless Color === other
    Color.new(@rgb.zip(other.rgb).map {|p| [p.reduce(:+), 255].min })
  end
end

我知道这是一个不好的实现方法,但这是我能想到的最短的方法。

c100 = Color.new([100, 100, 100])
c100 + c100         #=> Color(200, 200, 200)
c100 + c100 + c100  #=> Color(255, 255, 255)

如果我给出一个数组作为颜色,它也有效:

c100 + [50, 50, 50] #=> Color(150, 150, 150)

但我不能这样做:

[50, 50, 50] + c100 #=> TypeError: can't convert Color into Array

定义强制不起作用。我怎样才能让它工作?

最佳答案

因为代码

[50, 50, 50] + c100

调用 Array 上的 + 方法,而不是 Color,并且该方法无法将颜色转换为 Array。

相比之下,

 c100 + [50, 50, 50]

确实调用 Color 的 + 方法。

但是,即使你在Color中定义了转换方法:

class Color
def to_ary
return @rgb
end
end

Array 方法不会像你期望的那样工作;结果将是两个数组的串联,因为 Array 的 + 方法连接它们的操作数,而不是添加它们的元素:

irb>[50,50,50]+c100
=> [50,50,50,100,100,100]

这里,结果将是一个数组,而不是颜色。

编辑:

我认为实现此功能的唯一方法是为 Array 的 + 方法起别名,以处理接收 Color 作为第二个操作数的特殊情况。然而,我承认这种方法相当丑陋。

class Array
  alias color_plus +
  def +(b)
    if b.is_a?(Color)
      return b+self
    end
    return color_plus(b)
  end
end

关于ruby - 从数组强制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7549181/

相关文章:

检查数组中的所有字符是否都是整数

javascript - 为什么尾随逗号不会将 undefined 添加到 javascript 数组?

ruby-on-rails - Rails 4.0 中的路由、路径助手和 STI

javascript - Ruby on Rails 确认提交标签的条件

mysql - 如何在数据库中保存数组 - Rails

ruby - 在 Ruby 中,coerce() 是如何工作的?

ruby - 使用 GridFS 时出现 "Document exceeds allowed max BSON size. The max is 16777216."错误

javascript - AngularJS 关联数组 Foreach

Python:强制新型类