Private encapsulation question

Hello,
I am trying to improve my understanding of encapsulation but I can't
understand the reason why the last 2 method calls in the following code
produce different results (cut and paste in irb, plus return key):

class N
  def initialize(n)
    @number=n
  end
    
  def self_n_wrapper
    self.n
  end
  
  def n_wrapper
     n
  end
  
private

  def n
    @number
  end
  
end

a=N.new(8)
a.n_wrapper
a.self_n_wrapper

Thanks for help
Andrea

···

--

http://myretrocomputing.altervista.org

Alle Sunday 10 February 2008, andrea ha scritto:

Hello,
I am trying to improve my understanding of encapsulation but I can't
understand the reason why the last 2 method calls in the following code
produce different results (cut and paste in irb, plus return key):

class N
  def initialize(n)
    @number=n
  end

  def self_n_wrapper
    self.n
  end

  def n_wrapper
     n
  end

private

  def n
    @number
  end

end

a=N.new(8)
a.n_wrapper
a.self_n_wrapper

Thanks for help
Andrea

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. For a similar reason, you can call that method from an
instance method of a class C derived from A. A side effect of this approach is
that you can't call a private method using the explicit receiver self, even if

self.my_method

is the same as

my_method

I hope this helps

Stefano

why the last 2 method calls

Only a partial answer: protected instead of private should work.

andrea wrote:

  def self_n_wrapper
    self.n
  end

a.self_n_wrapper

private method `n' called

Calling self.n is equivalent to calling a.n here, isn't it?

···

--
Ruurd

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 :slight_smile:

Bye
Andrea

···

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.

--

Alle Sunday 10 February 2008, andrea ha scritto:

> 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 :slight_smile:

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

···

Stefano Crocco <stefano.crocco@alice.it> wrote:

[cut]

I hope this makes things clearer

Yes, definitely. Now I get the point.
Thanks again.

Andrea

···

Stefano Crocco <stefano.crocco@alice.it> wrote:

--