--- Peter Vanbroekhoven <calamitas / advalvas.be> wrote:

> On Wed, 31 Aug 2005, Peter Vanbroekhoven wrote:
> 
> > On Tue, 30 Aug 2005, David A. Black wrote:
> >
> >> I see what you mean; it's very magic.  I can't think of a
> way to
> >> implement it in Ruby, and even though someone will be able
> to with dl
> >> or whatever, it will still be too magic :-)
> >
> > Actually... Here's an implementation using the very thing
> that started this 
> > thread:
> >
> >  class Object
> >    private :send
> >    def method_missing(m, *args, &blk)
> >      if m == :send
> >        eval "self.#{args[0]}(*args[1..-1], &blk)"
> >      else
> >        eval "#{m}(*args, &blk)"
> >      end
> >    end
> >  end
> >
> >  class A
> >    def do_sth
> >      puts "hello"
> >    end
> >    private :do_sth
> >  end
> >
> >  A.new.instance_eval { do_sth } # => prints "hello"
> >  A.new.do_sth # => raises NoMethodError
> 
> OK, pasted the wrong version... Here goes another try:
> 
>    class Object
>      private :send
>      def method_missing(m, *args, &blk)
>        if m == :send
>          eval "self.#{args[0]}(*args[1..-1], &blk)"
>        else
>          super
>        end
>      end
>    end
> 
>    class A
>      def do_sth
>        puts "hello"
>      end
>      private :do_sth
>    end
> 
>    A.new.instance_eval { send(:do_sth) } # => prints "hello"
>    A.new.send(:do_sth) # => raises NoMethodError
> 
> Peter

How about a version that allow classes to override send and
call the original with super?  Or how about aliasing send? 
Here are some of the tests I showed in a previous message with
this:

a = A.new
a.send(:do_sth) # => raises NoMethodError
a.send(:send,:do_sth) # => raises NoMethodError
a.instance_eval{send(...)} # => prints "hello"
a.instance_eval{send(:send,...)} # => prints "hello"

class A
  alias _send send
  def send(m,*args,&block)
    super
  end
end

a.send(:do_sth) # => prints "hello"
a.instance_eval{send(:do_sth)} # => prints "hello"
a._send(:do_sth) # => prints "hello"
a.instance_eval{_send(:do_sth)} # => prints "hello"
  
Notice you lose the dual functionality as soon as you do
anything to send.  It looks like you can get it back by doing
this:

class A
  private :_send
  private :send
end

It is quite difficult to follow what is going on in the above
examples and why it works.

This is an interesting way of determining whether a method was
called with or without a receiver.  But, I still think it isn't
a good idea.  I think a method's functionality should be
independent of that.


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com