Alle Sunday 10 February 2008, andrea ha scritto:
> Stefano Crocco <stefano.crocco / alice.it> wrote:
> > Ruby implements private methods forbidding to call them with an explicit
> > receiver, but only with the explicit receiver, self. This is enough to
> > ensure a private instance method of class A can't be called by, for
> > example an instance method of class B, because in the latter self is an
> > instance of class B, not of class A.
>
> I don't know if I understand correctly your last sentence, but also less
> rescrictive (compared to private) protected methods behave the way you
> described, am I right? I am asking because I don't get the link between
> the 2 sentences quoted above.
> Sorry, while the rest of your post is pretty clear it seems I am missing
> something here... any further explaination is welcome :)
>
> Bye
> Andrea

I agree that what I wrote isn't very clear. This is what I meant: a private 
method can only be called without explicitly using a receiver, that is:

my_method(1,2,3)

is OK, but

something.my_method(1,2,3)

is wrong. This means that, if my_method is a private instance method of class 
A, i can only call it from places where self is an instance of class A 
because, if I try to call it from somewhere else, I need an explicit receiver, 
which doesn't work for private methods. The weird thing is that even 
self.my_method uses an explicit receiver and so causes an error, even if the 
receiver is the same as the explicit receiver.

There are a couple of other peculiarities which arise from this approach to 
private methods, compared with other languages, such as C++

* you can only call a private method of self, not of another object of the 
same class (because you'd need to use an explicit receiver to do so)
* you can can call a private method from a derived class (because you don't 
need an explicit receiver).

Here there are some examples:

class A

  def m1
  end
  private :m1

  def m2
    m1  #this works, because I'm using the implicit receiver, self
  end

  def m3
    #this doesn't work because I'm using an explicit receiver, even
    #if it's the same object as the implicit receiver
    self.m1  
  end

  def m4 other
    #this doesn't work, regardless of whether other is an instance of A
    #or not (of course, provided it doesn't have a public m1 method)
    other.m1  
  end

end

A.new.m1 #this doesn't work because of explicit receiver

class B < A
  
  def m5
    m1  #this works because I don't need to use an explicit receiver
  end

end

I hope this makes things clearer

Stefano