Gavin Kistner wrote: > On Jan 25, 2005, at 9:09 AM, Gennady Bystritksy wrote: > >> I do not think what you want has anything to do with 'duck typing'. >> 'duck typing' only means that you can send a message to any object and >> if the object has a corresponding method it gets executed regardless >> of object type. It does not urge you to abandon the "normal" way of >> method definition for a class. > > > FWIW, in Javascript you can invoke a method defined anywhere with any > scope that you wish. For example: > > Object.prototype.toString = function(){ > return '['+this.constructor.name+' "'+this.name+'"]'; > } > > function Bird( inName ){ > this.name = inName; > this.wings = 2; > } > Bird.prototype.fly = function(){ > if ( this.wings ) > { > this.altitude += 100; > alert( 'Look ma, ' + this + ' is flying!' ); > } > } > > function Pig( inName ){ > this.name = inName; > } > > var robin = new Bird( 'Tweeters' ); > robin.fly(); // Look ma, [Bird "Tweeters"] is flying! > > var super_pig = new Pig( 'Babe' ); > super_pig.wings = 17; > robin.fly.call( super_pig ); // Look ma, [Pig "Babe"] is flying! > Bird.prototype.fly.call( super_pig ); // Look ma, [Pig "Babe"] is flying! def method_missing( arg1, arg2=nil ) if arg1.to_s =~ /([^=]*)=/ instance_eval "@#{$1}= #{arg2};def #{$1}; @#{$1}; end" else super end end class Bird attr_accessor :wings def initialize( name ) @name = name @wings = 2 end def self.fly( arg=nil ) obj = arg if obj.wings obj.instance_eval "@altitude ||=0" obj.instance_eval "@altitude += 100" puts "Look ma, #{obj.instance_eval '@name' } is flying!" end end def fly( arg=self ) Bird.fly( arg ) end end class Pig def initialize( name ) @name = name end end robin = Bird.new( "Tweeters" ) robin.fly super_pig = Pig.new( 'Babe' ) super_pig.wings = 17 robin.fly( super_pig ) Bird.fly( super_pig ) You can still achieve the same outcome, just not using the ECMA language syntax. JavaScript isn't the only prototype-based langauge out there. Flash ActionScript is much like this as well (and I believe nicer then JS). Not having to mess with things like: Object.prototype.method.call Object.__prototype__.method.call is a nice way to use class or module methods IMO, it's just much cleaner looking: Bird.prototype.fly.call( super_pig ) Bird.fly( super_pig ) The nice thing about Ruby is that you DONT have to succumb to the behavior where new attributes will be created on the fly. If you want that functionality override method missing. Perhaps not every single Object out there needs this ability, but if you feel you need it somewhere then it's simple, easy and quick to add. Zach