From: Phrogz on 31 Mar 2010 00:26 Below are two files that differ only in the 2nd line of code in each. Can you guess what difference they will reveal? I must admit I was surprised when I ran into this. $ cat alias.rb class Object alias_method :to_js, :inspect end class Array def to_js; "[#{map{|o|o.to_js}.join(',')}]"; end end class Hash def to_js "{#{map{|k,v| "#{k.to_s.to_js}:#{v.to_js}" }.join(',')}}" end end [ 1, [true], {a:"foo"} ].each{ |o| puts o.to_js } $ cat wrapped.rb class Object def to_js; inspect; end end class Array def to_js; "[#{map{|o|o.to_js}.join(',')}]"; end end class Hash def to_js "{#{map{|k,v| "#{k.to_s.to_js}:#{v.to_js}" }.join(',')}}" end end [ 1, [true], {a:"foo"} ].each{ |o| puts o.to_js }
From: Robert Klemme on 31 Mar 2010 05:19 2010/3/31 Phrogz <phrogz(a)mac.com>: > Below are two files that differ only in the 2nd line of code in each. > Can you guess what difference they will reveal? I must admit I was > surprised when I ran into this. > > $ cat alias.rb > class Object > alias_method :to_js, :inspect > end This one always invokes Object#inspect - unless you override #to_js explicitly. > $ cat wrapped.rb > class Object > def to_js; inspect; end > end This is the one you really want IMHO: #to_js delegates to whatever #inspect is present in the class. Pretty straightforward inheritance behavior - although I'd concede that it's subtle. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Martin DeMello on 31 Mar 2010 05:30 On Wed, Mar 31, 2010 at 10:01 AM, Phrogz <phrogz(a)mac.com> wrote: > Below are two files that differ only in the 2nd line of code in each. > Can you guess what difference they will reveal? I must admit I was > surprised when I ran into this. It's pretty clear if you think of it in terms of message handlers and method objects > class Object > alias_method :to_js, :inspect > end This binds the message handler Object#to_js to the method object Object#inspect. This should be illustrative: $ cat test.rb class Object alias_method :to_js, :inspect alias_method :inspect, :hash end a = Object.new puts a.inspect p a puts a.to_js $ ruby test.rb 67266180 67266180 #<Object:0x804cd08> > $ cat wrapped.rb > class Object > def to_js; inspect; end > end This creates a new method object, which contains a thunk that sends the message "inspect" to self when it is invoked, and binds the Object#to_js message handler to that method object. martin
From: Phrogz on 31 Mar 2010 10:00 On Mar 31, 3:19 am, Robert Klemme <shortcut...(a)googlemail.com> wrote: > 2010/3/31 Phrogz <phr...(a)mac.com>: > > > Below are two files that differ only in the 2nd line of code in each. > > Can you guess what difference they will reveal? I must admit I was > > surprised when I ran into this. > > > $ cat alias.rb > > class Object > > alias_method :to_js, :inspect > > end > > This one always invokes Object#inspect - unless you override #to_js explicitly. Yes; specifically, in this case, Object#inspect on a String calls #to_s (because it's defined), so: puts "foo".to_js #=> foo instead of the desired "foo" (with quotes).
|
Pages: 1 Prev: Error in Starling on Windows.. Next: Playing Games with "Ruids" |