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