From: Robert Klemme Date: 2008-09-26T20:41:19+09:00 Subject: Re: Getting the right class with inheritance and super() 2008/9/25 Kyle Schmitt : > On Thu, Sep 25, 2008 at 1:31 PM, Robert Klemme > wrote: >> 2008/9/25 Kyle Schmitt : >>> Reading the example you gave, and even some on the net, it looks like >>> I'd need the Array class to have a coerce method that can change an >>> Array into a FixedSizeArray? >> >> No. Your coerce method needs to take care. Look at my example. I >> did not change Fixnum or Float. > Right, you didn't change it, but in the example you're calling coerce > on whatever it is that's passed in (perhaps this is the source of my > confusion): The critical thing to understand is that the _other_ instance's coerce method is invoked! 13:38:43 ~$ ruby -r bigdecimal -e 'bd=BigDecimal.new("2");set_trace_func lambda {|*a|p a};1+bd' ["line", "-e", 1, nil, #, false] ["c-call", "-e", 1, :+, #, Fixnum] ["c-call", "-e", 1, :coerce, #, BigDecimal] ["c-return", "-e", 1, :coerce, #, BigDecimal] ["c-call", "-e", 1, :+, #, BigDecimal] ["c-return", "-e", 1, :+, #, BigDecimal] ["c-return", "-e", 1, :+, #, Fixnum] Look at trace lines 2 and 3: Fixnum#+ is invoked and then BigDecimal#coerce. > Class X > ... most everything removed ... > def + other > if self.class === other > # fake only > self.class.new > else > #only going to get here if other isn't of class X > a, b = other.coerce(self) > #doesn't whatever class other is have to have a coerce method? > a + b > end > end > end > > > Now if we pull up irb. > fixnum=10 > float=11.0 > hash={} > array=[] > string="Wax Rabbits" > > fixnum.respond_to?"coerce" > => true > float.respond_to?"coerce" > => true > hash.respond_to?"coerce" > => false > array.respond_to?"coerce" > => false > string.respond_to?"coerce" > => false > > So since Arrays Hashes and Strings don't have a coerce, does that mean > they can't be used in this fashion? 13:39:04 ~$ ruby -e '1+[]' -e:1:in `+': Array can't be coerced into Fixnum (TypeError) from -e:1 13:41:04 ~$ ruby -e '[]+1' -e:1:in `+': can't convert Fixnum into Array (TypeError) from -e:1 13:41:12 ~$ ruby -e '1+{}' -e:1:in `+': Hash can't be coerced into Fixnum (TypeError) from -e:1 13:41:19 ~$ ruby -e '{}+1' -e:1: undefined method `+' for {}:Hash (NoMethodError) Cheers robert -- use.inject do |as, often| as.you_can - without end