Private method clarification, please

Is this behavior expected?

$ cat t.rb
class C
  def meth1() private_method end
  def meth2() self.private_method end
  def private_method() puts 'you called?' end
  private :private_method
end

c = C.new
c.meth1
c.meth2

$ ruby --version
ruby 1.8.5 (2006-12-25 patchlevel 12) [i386-cygwin]

$ ruby t.rb
you called?
t.rb:3:in `meth2': private method `private_method' called for
#<C:0x442fdd4> (NoMethodError)
        from t.rb:10

It seems distinctly strange to me that you cannot call a private
method using the self semantics shown in meth2. Is this the expected
behavior?

Blessings,
TwP

Hmm... I can't decide is it's strange or not. I always think of using
self.whatever in methods as using 'external' access, in which case,
it's not surprising. You can of course, send() through.

So yeah, I can see where that behaviour might seem surprising but it's
not particularly surprising to me.

-greg

···

On 7/3/07, Tim Pease <tim.pease@gmail.com> wrote:

Is this behavior expected?

$ cat t.rb
class C
  def meth1() private_method end
  def meth2() self.private_method end
  def private_method() puts 'you called?' end
  private :private_method
end

c = C.new
c.meth1
c.meth2

$ ruby --version
ruby 1.8.5 (2006-12-25 patchlevel 12) [i386-cygwin]

$ ruby t.rb
you called?
t.rb:3:in `meth2': private method `private_method' called for
#<C:0x442fdd4> (NoMethodError)
        from t.rb:10

It seems distinctly strange to me that you cannot call a private
method using the self semantics shown in meth2. Is this the expected
behavior?

The only reason it seems strange is that you can use the self
semantics in some cases -- i.e. when calling a setter method

class C
  def meth3( val ) self.private_setter = val end
  def private_setter=( val ) puts "you said '#{val}'" end
  private :private_setter=
end

c = C.new
c.meth3( 'hello' ) #=> you said 'hello'

So, that case works, but others do not. Just seems strange.

TwP

···

On 7/3/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 7/3/07, Tim Pease <tim.pease@gmail.com> wrote:
> Is this behavior expected?
>
> $ cat t.rb
> class C
> def meth1() private_method end
> def meth2() self.private_method end
> def private_method() puts 'you called?' end
> private :private_method
> end
>
> c = C.new
> c.meth1
> c.meth2
>
> $ ruby --version
> ruby 1.8.5 (2006-12-25 patchlevel 12) [i386-cygwin]
>
> $ ruby t.rb
> you called?
> t.rb:3:in `meth2': private method `private_method' called for
> #<C:0x442fdd4> (NoMethodError)
> from t.rb:10
>
> It seems distinctly strange to me that you cannot call a private
> method using the self semantics shown in meth2. Is this the expected
> behavior?

Hmm... I can't decide is it's strange or not. I always think of using
self.whatever in methods as using 'external' access, in which case,
it's not surprising. You can of course, send() through.

So yeah, I can see where that behaviour might seem surprising but it's
not particularly surprising to me.

The only reason it seems strange is that you can use the self
semantics in some cases -- i.e. when calling a setter method

From what I understand, the difference between private and protected methods is that protected methods can only be called by objects of the same class, while private methods cannot be called with an explicit receiver. This implies that private methods can only be called from within the object itself. However, you have to use an explicit receiver with setter methods from within the class, otherwise the interpreter will think you're trying to set a local variable. If you couldn't use self with private setter methods there would be no way to call them. You could try "private_setter=(args)" but that might still be parsed as an assignment to the local variable private_setter. It seems a little inconsistent but I think it makes sense.

-Brett