private method clarification, please

T

Tim Pease

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
 
G

Gregory Brown

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
 
C

Chris Shea

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/113573#265252

HTH,
Chrs
 
T

Tim Pease

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
 
M

matt neuburg

Tim Pease said:
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.
 
C

Chris Shea

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
 
B

Brett Simmers

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
 
C

Chris Shea

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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top