[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

private method clarification, please

Tim Pease

7/3/2007 6:03:00 PM

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

7 Answers

Gregory Brown

7/3/2007 6:08:00 PM

0

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.

-greg

Chris Shea

7/3/2007 6:09:00 PM

0

On Jul 3, 12:03 pm, "Tim Pease" <tim.pe...@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?
>
> Blessings,
> TwP

Yes (although maybe it shouldn't be, but that's something else).

Private methods need to be called with an implicit caller.
self.private_method makes the caller explicit. It's a casualty of
Ruby's way of trying to keep private methods private.

See: http://www.ruby-forum.com/topic/113...

HTH,
Chrs

Tim Pease

7/3/2007 6:19:00 PM

0

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

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

matt

7/3/2007 6:28:00 PM

0

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?

I could be wrong, but my impression is that "private" means simply that
the method cannot be called with an explicit receiver (i.e.
dot-notation). In self.private_method, self is an explicit receiver (it
comes before a dot). So that's illegal.

So, if I'm right about that, then the concept "private" is very simple
and very simple-minded, thought at least it's clear. You are expecting
"self" to be evaluated ("ah, yes, he is sending this message to the same
object"), but it's never getting that far; instead, Ruby is saying,
"Hey, he's trying to send that message to an object, but you can't do
that with a private method."

m.

--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Tiger - http://www.takecontrolbooks.com/tiger-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...

Chris Shea

7/3/2007 6:33:00 PM

0

On Jul 3, 12:18 pm, "Tim Pease" <tim.pe...@gmail.com> wrote:
> On 7/3/07, Gregory Brown <gregory.t.br...@gmail.com> wrote:
>
>
>
> > On 7/3/07, Tim Pease <tim.pe...@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
>
> 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

It's because you can't do it the other way.

Think about this:

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

c = C.new

Now when you call c.meth3('hello'), private_setter = val is
ambiguous. Does it mean set a variable called private_setter to
'hello', or does it mean call private_setter=('hello'). Ruby guesses
the latter. Which means you need make it explicit. And that breaks
the rule about private methods needed to be called with an implicit
caller, but at least it's still private in the sense that you can't
call it from outside.

Chris

Brett Simmers

7/3/2007 6:34:00 PM

0


> 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


Chris Shea

7/3/2007 6:34:00 PM

0

On Jul 3, 12:32 pm, Chris Shea <cms...@gmail.com> wrote:
> On Jul 3, 12:18 pm, "Tim Pease" <tim.pe...@gmail.com> wrote:
>
>
>
> > On 7/3/07, Gregory Brown <gregory.t.br...@gmail.com> wrote:
>
> > > On 7/3/07, Tim Pease <tim.pe...@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
>
> > 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
>
> It's because you can't do it the other way.
>
> Think about this:
>
> class C
> def meth3( val ) private_setter = val end
> def private_setter=( val ) puts "you said '#{val}'" end
> private :private_setter=
> end
>
> c = C.new
>
> Now when you call c.meth3('hello'), private_setter = val is
> ambiguous. Does it mean set a variable called private_setter to
> 'hello', or does it mean call private_setter=('hello'). Ruby guesses
> the latter. Which means you need make it explicit. And that breaks
> the rule about private methods needed to be called with an implicit
> caller, but at least it's still private in the sense that you can't
> call it from outside.
>
> Chris

I mean, Ruby guesses the former. It sets the variable
private_setter. Sorry.