Newbie question : private / public methods

K

krzysieq Gazeta.pl

[Note: parts of this message were removed to make it a legal post.]

Hi,

I'm new both to this mailing list and to Ruby. Here's an example, question
will come later.

class PrivateMethodTest
private
def privateMethod(the_string)
'haha! ' + the_string
end

public
def publicMethod(the_string)
self.privateMethod(the_string)
end
end


require 'private.rb'
require 'test/unit'

class PrivateMethodTestTest < Test::Unit::TestCase

def test_publicMethod
var = PrivateMethodTest.new()
assert_equal('haha! test', var.publicMethod('test'))
end
end

Now the question: why is it, that when the self. (bolded in the code) is
there, the test fails, whereas if I remove it, the test is successful? This
is the failure message:

1) Error:
test_publicMethod(PrivateMethodTestTest):
NoMethodError: private method `privateMethod' called for
#<PrivateMethodTest:0x2b0876d805a0>
./private.rb:9:in `publicMethod'
private_test.rb:8:in `test_publicMethod'

What am I missing?

Thanks for any help and sorry if this question is silly :)
Cheers,
Chris
 
S

Stefano Crocco

Hi,

I'm new both to this mailing list and to Ruby. Here's an example, question
will come later.


class PrivateMethodTest
private
def privateMethod(the_string)
'haha! ' + the_string
end

public
def publicMethod(the_string)
self.privateMethod(the_string)
end
end


require 'private.rb'
require 'test/unit'

class PrivateMethodTestTest < Test::Unit::TestCase

def test_publicMethod
var = PrivateMethodTest.new()
assert_equal('haha! test', var.publicMethod('test'))
end
end

Now the question: why is it, that when the self. (bolded in the code) is
there, the test fails, whereas if I remove it, the test is successful? This
is the failure message:

1) Error:
test_publicMethod(PrivateMethodTestTest):
NoMethodError: private method `privateMethod' called for
#<PrivateMethodTest:0x2b0876d805a0>
./private.rb:9:in `publicMethod'
private_test.rb:8:in `test_publicMethod'

What am I missing?

Thanks for any help and sorry if this question is silly :)
Cheers,
Chris

Ruby implements private methods as methods which can't be called using an
explicit receiver (i.e, using the form obj.method_name), but only using the
implicit receiver (that is, method_name). Since the implicit receiver is
always self, this ensures that private instance methods can only be called by
instance methods of that class (or of derived classes) and can't be accessed
by other instances of the same class. An unpleasant side effect of this is
that you can't call private methods using the explicit receiver even when that
receiver is equal to the implicit one (that is, self), which is the situation
you discovered.
 
K

Krzysieq

[Note: parts of this message were removed to make it a legal post.]

Then it enforces habits, which I've been encouraged to develop anyways - my
managers always told me not to use this.doSomething whenever there is no
risk of ambiguity. Don't You think however, that this is quite harsh - I
mean, don't You think this might get someone into bigger trouble sometime? I
don't know Ruby well enough to think of an example yet, but something tells
me this "feature" could be tricky...

Mateusz: You changed the name of the test class, that's why the error.

Cheers,
Chris
 
S

Stefano Crocco

Then it enforces habits, which I've been encouraged to develop anyways - my
managers always told me not to use this.doSomething whenever there is no
risk of ambiguity. Don't You think however, that this is quite harsh - I
mean, don't You think this might get someone into bigger trouble sometime?
I don't know Ruby well enough to think of an example yet, but something
tells me this "feature" could be tricky...

Do you refer to being unable to write self.a_private_method ? I don't think it
can cause any trouble. It does prevent you from writing code like the
following:

class C

def initialize
@x = 2
end

def a_method value
self.x = value
end

private

def x= value
#set the value of @x to something and do some other thing
end

end

What the code is trying to do is define a private method, x= which changes the
value of the instance variable @x and does some extra processing, then use
this method every time it needs to change the value of @x. However, this kind
of setter methods (those ending in =) need to be called with an explicit
receiver, since otherwise ruby thinks we want to create the local variable x.
But, since x= is a private method, it can't be called with an explicit
receiver, either.

Of course, this is not a big problem: we have to call the method with another
name (set_x, for example) and everything works again, even if it's not as
pretty as it would have been with x=.

Stefano
 
K

Krzysieq

[Note: parts of this message were removed to make it a legal post.]

Well, my story is slightly different. I encountered this in a situation,
when I had a private method to do some operations, and a number of public
methods to use that one. And these public methods can't call the private
using self. It's just something I'm used to doing, and perhaps now I will
need to get unused to it :) Maybe it's not dangerous at all, it's just
different from what I've seen so far. And people tend to fear what they do
not understand...

Thanks for explanations.
Cheers,
Chris
 

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

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top