Self and private setter

A private method cannot be called with an explicit receiver – even
self – except when calling a private setter method, because otherwise
an assignment to a local variable will be assumed.

For example:

class Q

def a1
@p = nil
self.p=(3)
@p
end

def a2
@p = nil
p=(3)
@p
end

private

def p=(obj)
@p = obj
end
end

CONSOLE

Q.new.a1
=> 3

Q.new.a2
=> nil


Since there is already this exception to the rule, why not allow
explicitly using self for ALL private methods? What harm can be done?

On Dec 17, 6:44 pm, Paul [email protected] wrote:

self.p=(3)

Q.new.a2

=> nil

Since there is already this exception to the rule, why not allow
explicitly using self for ALL private methods? What harm can be done?

I’m pretty sure that’s the difference between protected and private
visibility; protected lets you use an explicit receiver (and maybe
other things like children classes can also access the method?). But
if you need to use private methods, you can always call them with an
explicit receiver by using #send.

Regards,
Jordan

Found the article I was thinking of from Jamis B., where he talks
about private/protected:

http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby

Regards,
Jordan

On Dec 17, 6:08 pm, MonkeeSage [email protected] wrote:

@p = nil

private
=> 3
other things like children classes can also access the method?). But
if you need to use private methods, you can always call them with an
explicit receiver by using #send.

I think you may be missing Paul’s point. As shown in his sample code
above (which I have not tried but assume to be correct), there is a
particular syntax that allows self to be used with private methods.
Paul’s question is “why not always allow it?”

The distinction between private and protected is only superficially
about whether an explicit receiver may be used. Primarily it is the
difference between…well, read for yourself:
http://phrogz.net/ProgrammingRuby/language.html#accesscontrol

I don’t have an answer to Paul’s question, or for/against his
proposal, but thought I’d clarify what I think may have been some
miscommunication.

On Dec 17, 7:53 pm, Phrogz [email protected] wrote:


p=(3)

explicitly using self for ALL private methods? What harm can be done?
Paul’s question is “why not always allow it?”

The distinction between private and protected is only superficially
about whether an explicit receiver may be used. Primarily it is the
difference between…well, read for yourself:The Ruby Language

I don’t have an answer to Paul’s question, or for/against his
proposal, but thought I’d clarify what I think may have been some
miscommunication.

NP. I understand the question, I just answered it indirectly. Viz., it
seems to me that protected is specifically meant for allowing access
with a receiver, and unless it is necessary to use private (e.g.,
someone else’s code), using protected is the Right Thing To Do(R) when
you want access through a receiver. There would seem to be no
difference between private/protected if private methods could be
called with explicit the self receiver (see the example output in
Jamis’ article, also the link in the fifth comment). Maybe I’m missing
something though.

Regards,
Jordan

On Dec 17, 8:15 pm, MonkeeSage [email protected] wrote:

difference between private/protected if private methods could be
called with explicit the self receiver (see the example output in
Jamis’ article, also the link in the fifth comment). Maybe I’m missing
something though.

There would still be this difference:

class Foo
def call_prot( someone_else )
someone_else.prot
end

def call_priv( someone_else )
someone_else.priv
end

protected
def prot; “prot”; end

private
def priv; “priv”; end
end

f1 = Foo.new
f2 = Foo.new

p f1.call_prot( f2 )
#=> “prot”

p f1.call_priv( f2 )
#=> NoMethodError: private method ‘priv’ called for #Foo:0x281e50

Other instances of the same class can still call protected methods on
you, while only you yourself can call private methods. Paul’s proposal/
question would be if this works already (which it does):

class Foo
def call_bar_set( val )
self.bar = val
end
private
def bar=( val ); “yay”; end
end

Foo.new.call_bar_set( 42 )

then why not allow this to work:

class Foo
def call_bar
self.bar
end
private
def bar; “yay”; end
end

Foo.new.call_bar

I suppose it might be a small extra burden on the runtime to allow
this:

class Foo
def call_bar( someone_else )
someone_else.bar
end
private
def bar; end
end

…as the runtime would have to check if ‘someone_else’ was the same
as ‘self’ inside call_bar. Since it already has to check if the ‘self’
inside call_bar is of the same class as the class as ‘someone_else’,
this doesn’t seem particularly burdensome, however.

On Dec 17, 9:52 pm, Phrogz [email protected] wrote:

someone else’s code), using protected is the Right Thing To Do(R) when
someone_else.prot
def priv; “priv”; end

Other instances of the same class can still call protected methods on
you, while only you yourself can call private methods.

Not trying to be contrary, but I think calling #call_priv with f1 as
the argument should raise the same exception (no receiver allowed,
even self). I’m not sure it has anything to do with different
instances…

class Foo
def call_priv; priv; end
private
def priv; “priv”; end
end
f1 = Foo.new
f2 = Foo.new
m = Foo.instance_method(:call_priv)
p m.bind(f1).call # => “priv”
p m.bind(f2).call # => “priv”

I have a feeling I’m still missing something? Were you talking about a
proposal for the way private could work if explicit self was allowed,
in order to distinguish it from protected?

end

Foo.new.call_bar

I understand. I also don’t know enough about ruby under the hood to be
for / against the suggestion. But I’m still not sure it is needed or
desirable (protected still seems like the right tool for the job to
me, or using #send to bypass visibility restrictions if you can’t
choose the visibility yourself).

…as the runtime would have to check if ‘someone_else’ was the same
as ‘self’ inside call_bar. Since it already has to check if the ‘self’
inside call_bar is of the same class as the class as ‘someone_else’,
this doesn’t seem particularly burdensome, however.

Regards,
Jordan

On 12/17/07, Phrogz [email protected] wrote:

…as the runtime would have to check if ‘someone_else’ was the same
as ‘self’ inside call_bar. Since it already has to check if the ‘self’
inside call_bar is of the same class as the class as ‘someone_else’,
this doesn’t seem particularly burdensome, however.

No, it only has to do this for protected methods not private methods.

For private methods the only check that’s needed is whether or not
there was a specified receiver, no need to dig down the call stack.

In the case of

self.x = y

I’m almost certain that the parser turns this into the semantic
equivalent of

setx(y)

where setx is a fictional alias to the :x= message selector. In other
words it’s just syntactic sugar for a functional form method call.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/