我提交了pull request,修改了Matrix
类,以便可以使用实数进行添加:
Matrix[ [25, 93], [-1, 66] ] + 5
Matrix
类有一个方法+()
,在这种情况下调用它。
我还希望用户能够将操作的顺序更改为
5 + Matrix[ [25, 93], [-1, 66] ]
Matrix
class似乎支持*()
方法的此操作顺序,我不确定如何为+()
方法实现此操作。
答案 0 :(得分:2)
使用coerce
方法处理强制。此方法返回两个要重试给定运算符/方法的元素。 Matrix
定义coerce
,如:
def coerce(other)
case other
when Numeric
return Scalar.new(other), self
else
raise TypeError, "#{self.class} can't be coerced into #{other.class}"
end
end
但请注意,它不会更改操作数的顺序,而是将数值转换为Scalar
类。因此,看到5 + Matrix[...]
的红宝石将执行Scalar.new(5) + Matrix[...]
。
Scalar
类在同一个文件中定义,并定义了自己的一组运算符,包括+
和' - '。所以你需要做的是摆脱行Scalar.Raise ErrOperationNotDefined, "+", @value.class, other.class
并在这里强制执行你的代码,例如使用other + self
答案 1 :(得分:2)
评论太长了,这是一种答案。但是,我不想解释#coerce
如何工作,任何人都可以从文档中读到,我想告诉你,不要这样做。就此而言,我的意思是
Matrix#+
重载,Matrix#coerce
。 1.的原因是您认为您正在添加功能。但你也失去了一些东西。矩阵通常只能与相同维度的其他矩阵相加。如果你犯了一个错误并尝试总结不同维度的矩阵,或者试图用一些不相关的对象来总结一个矩阵,你就会得到一个错误。此错误是程序员的服务。这是一个受欢迎的reminer,它允许我们尽早发现我们犯了一个错误,我们正在尝试将不兼容的对象添加到矩阵中。此错误允许我们尽早发现问题。如果你开始超载Matrix#+
,你将获得新的功能,但你也失去了警告,语言变得越来越脆弱。如果您确实要为每个元素添加一个数字,请定义一个新方法,例如
class Matrix
def add_to_each n
self + self.map { n }
end
end
对于2.,你再次破坏了2个对象:Matrix::Scalar
和数字对象。您认为自己正在提供服务,使Matrix
更有用。但是写作
Matrix[[1, 2], [3, 4]].map { |e| e + 5 }
并不困难。 Imo,通过重载+
来改变这种语法是一种净损失。我知道你已经完成了这项工作,但是把它作为一个宝石发布,不要用这个特征蠕变污染核心。