On Sat, 27 Aug 2005, Yukihiro Matsumoto wrote:

> Although this explains the situation, I admit this is confusing.  I
> decided to make Kernel#send to call public methods only (in 1.9 for
> the sake of compatibility).  If you want to invoke private methods,
> use a new method, #fcall.

Something has been bothering me about this still, and now I know what. 
Kernel#send used to call the given method as if it was being called 
without receiver (thus being able to call private methods). Changing 
Kernel#send does not change how calling a method without receiver works, 
so the confusion persists there. For example:

   class A
     def m1(x)
       "m1/1"
     end
     private :m1
     def method_missing(m, *args)
       return "m1/2" if m == :m1
       super
     end
     def use_m1
       p m1(5) # prints "m1/1"
       p self.m1(5) # prints "m1/2"
       t = self
       p t.m1(5) # prints "m1/2"
     end
   end

   A.new.use_m1

I only see two ways of avoiding this confusion. The first is not to call 
method_missing for private/protected methods. In a way that makes sense 
because if a method is private, it is not missing, just inaccessible. The 
consequence would be that method calls with an without receiver do exactly 
the same, or the one with receiver gives an error.

The second possibility would be to give methods implemented through 
method_missing precedence over private methods. Thus without receiver, 
first a public method is sought for, if not found method_missing is 
called, if that fails, the private method is called if present. So 
essentially it tries the call with receiver, then it tries without.

I think it's still OK to have two versions of Kernel#send, one that does 
the call as if with receiver, one as if without receiver (which can call 
private methods) -- however you name them. But the confusion is not 
because of Kernel#send; it's because of the semantics of method calls with 
receiver vs without receiver, and changing Kernel#send does not solve 
that. Well, IMHO at least.

Or am I missing the point completely?

Peter

PS: fcall is used in Ruby's internals to refer to a call without receiver. 
This looks like a call to a procedural function, hence fcall.