在 Ruby 中, coerce() 方法可以知道哪个运算符需要帮助进行强制转换吗?
在 Ruby 中,似乎可以通过 coerce() 来完成很多帮助
def coerce(something)
[self, something]
end
,当
3 + rational
需要时,Fixnum 3
不知道如何处理添加 Rational,因此它询问 Rational#coerce通过调用rational.coerce(3)来寻求帮助,这个coerce实例方法会告诉调用者:
# I know how to handle rational + something, so I will return you the following:
[self, something]
# so that now you can invoke + on me, and I will deal with Fixnum to get an answer
那么如果大多数操作符都可以使用这个方法,但在(a - b) != (b - a)情况下不能使用呢? coerce() 是否可以知道它是哪个运算符,并仅处理这些特殊情况,同时仅使用简单的 [self, some] 来处理 (a op b) == (b op a) 的所有其他情况? (op是运算符)。
In Ruby, it seems that a lot of coerce() help can be done by
def coerce(something)
[self, something]
end
that's is, when
3 + rational
is needed, Fixnum 3
doesn't know how to handle adding a Rational, so it asks Rational#coerce for help by calling rational.coerce(3), and this coerce instance method will tell the caller:
# I know how to handle rational + something, so I will return you the following:
[self, something]
# so that now you can invoke + on me, and I will deal with Fixnum to get an answer
So what if most operators can use this method, but not when it is (a - b) != (b - a) situation? Can coerce() know which operator it is, and just handle those special cases, while just using the simple [self, something] to handle all the other cases where (a op b) == (b op a) ? (op is the operator).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
强制的重点不在于知道您要执行什么操作。其目的是使论点和自我达成共识。此外,相同的运算符在某些类中可以是可交换的,而在其他类中则不能(例如,
Numeric#+
和Array#+
),因此您的小型基于交换性的强制
利用确实不会有回报。您应该创建一个新类(例如,
ScalarPoint
),并使用它来连接标量值,而不是强制强制
去做它不打算做的事情。与您的Point
:等
(注意:代码未测试)
The point of
coerce
is not to know what operation you are trying to perform. Its purpose is to bring the argument andself
to a common ground. Additionally, same operators can be commutative in certain classes, and not in other (Numeric#+
andArray#+
, for example), so your small commutativity-basedcoerce
exploit really won't pay off.Instead of pushing your
coerce
to do what it's not intended to, you should create a new class instead (such asScalarPoint
, for example), and use it to interface scalar values with yourPoint
:and
etc. (NB: code not tested)
这个问题的答案是,您可以通过查看回溯来了解运算符,但您不应该这样做。
Ruby 的强制机制并不是这样设计的。正如我在你之前的问题中回答的那样,
coerce
应该返回两个等价的值[a, b]
,这样无论操作符是什么,a.send(operator, b)
都可以工作。The answer to this question is that you can know the operator by looking at the backtrace but you shouldn't do that.
That is not how the coerce mechanism of Ruby has been designed. As I answered in your previous question,
coerce
should return two equivalent values[a, b]
such thata.send(operator, b)
will work, whatever the operator.