From: Colin Bartlett Date: 2010-05-13T09:51:20+09:00 Subject: Re: In Ruby, can the coerce() method know what operator it is th On Wed, May 12, 2010 at 6:13 PM, Rick DeNatale wrote: > Based on an earlier thread from the OP where the use case was > operations on integers and points 1. the OP might want to take a look at the Vector class in matrix.rb. 2. In that earlier thread: On Mon, May 10, 2010 at 12:49 PM, Rick DeNatale wrote: > I may be wrong here, it's early and I haven't yet had a full cup of coffee "A mathematician is a machine for turning coffee into theorems" (* by Alfred Renyi, not Paul Erdos! http://en.wikiquote.org/wiki/Paul_Erdos *) > but while multiplication of a point (vector) and a scalar makes sense, > I'm not sure that there is a conventional meaning to > subtraction (or addition) of a scalar and a vector. Yes, I agree: in my draft reply (but left out of my post) was: "Thought: right or left multiplying (or dividing) a vector (that is point) by a scalar is OK, but do you really want to allow adding a vector and a scalar instead of raising an exception?" 3. Back to this thread! > [if] we need to allow: 1 * Point.new(1,1) > but disallow: 1 + Point.new(1, 1) or 1 - Point.new(1,1) > One way to address this might be something like > class Point > ... > def +(value) > # add if value is point, raise exception if it isn't > ... > class ScalarWrapper > attribute :scalar_value > def +(value) > raise ArgumentError.new("Attempt to add scalar to a point") > end I think you've anticipated and answered a thought I was about to put to you in that earlier thread, which was that if we want to: (a) allow scalar * point, and (b) disallow scalar - point, how would you implement that, adding that I could only think of two ways: 1. amend code in Fixnum, Bignum, Float, etc, which is messy; or 2. use something like the Point::Coerce class in my previous post in that thread, but adding code to raise appropriate exceptions. I then spent quite a bit of time half implementing an example, before it occurred to me that if there was a Ruby matrix class then that would probably have to do something similar - there is, and it does: it's Matrix::Scalar. Do you know this class well? I ask because: (A) I don't think I'd previously looked at matrix.rb in sufficient detail for my suggestion of something similar to Matrix::Scalar to be an unconscious memory of what's in matrix.rb, in which case that would be an example in Ruby of there being "only one obvious way to do it", and if your code in this thread was similarly starting from first principles, then that would reinforce this example. (B) The actual code in Matrix::Scalar#+ raises an exception for Numeric + (Matrix or Vector), but also allows for (Numeric or Matrix::Scalar) + Matrix::Scalar, with in both cases the result being Matrix::Scalar, and I can't immediately think of any circumstances where those cases would actually arise. But I may be wrong: the last cup of coffee I had was nearly 40 years ago, so unless there's some sort of homeopathic effect here I think your caffeine stimulation is likely to be more effective than mine! A short article in yesterday's London Metro newspaper cites a recent study on the effectiveness of caffeine, links: http://www.businessweek.com/lifestyle/content/healthday/639045.html http://www.news-medical.net/news/20100512/Caffeine-helps-shift-workers-make-fewer-errors-Cochrane-researchers.aspx