I am slightly confused with calling a private method:
···
--------------------------------------------------
class Foo
def without_self
x=5
end
def with_self
self.x=5
end
def call_priv_with_self
self.priv
end
private
def x=(value)
puts "x=#{value}"
end
def priv
puts "priv"
end
end
Foo.new.without_self # no output
Foo.new.with_self # output "x=5"
Foo.new.call_priv_with_self # bang
--------------------------------------------------
I guess the first call is just an assignment to the variable x. But
from my understanding of pickaxe2, 329, Variable/Method Ambiguity this
should not be the case, because Ruby did not encounter an assignment
before.
The second call works, although it is a private method and I learned
that private methods must not have a receiver, as 'proved' in line
three.
So my two questions are: why is there no method call in
Foo#without_self? And why does self.x= report an error?
An expression that looks like ‘identifier = value’ always
sets a variable, and never calls a method. This is simply
the way the language is defined.
When you want to call a setter method on the current object,
you *have* to say ‘self.foo = bar’, precisely because if you
leave out the ‘self.’, you will just create a local variable.
(You may encounter code that has each setter method aliased
to a names like ‘set_foo’ or ‘set_bar’. This of course
removes the need for the ‘self.’ prefix, because ‘set_foo’
and ‘set_bar’ can be called directly.)
And why does self.x= [not] report an error?
As you have already pointed out yourself, private methods
may not normally be called with an explicit receiver.
However, there is an exception to this rule which says that
private setter methods *may* be called with an explicit
receiver, provided that explicit receiver is exactly ‘self’.
(No other receiver, not even ‘(self)’, is excused.)
Of course, this exception exists precisely because it would
otherwise be very difficult to call a private setter method.
···
--
Daniel Brockman <daniel@brockman.se>
So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.
Isn't the preferred way of doing this the following?
@foo = bar
Is this equivalent to
self.foo = bar
Is this true?
An expression that looks like '@attr-name = value' always calls a
method whose name is 'attr-name='.
···
On 7/25/05, Daniel Brockman <daniel@brockman.se> wrote:
An expression that looks like 'identifier = value' always
sets a variable, and never calls a method. This is simply
the way the language is defined.
When you want to call a setter method on the current object,
you *have* to say 'self.foo = bar', precisely because if you
leave out the 'self.', you will just create a local variable.
--
R. Mark Volkmann
Partner, Object Computing, Inc.
> An expression that looks like 'identifier = value' always
> sets a variable, and never calls a method. This is simply
> the way the language is defined.
>
> When you want to call a setter method on the current object,
> you *have* to say 'self.foo = bar', precisely because if you
> leave out the 'self.', you will just create a local variable.
I just want to make sure I fully understand this.
Isn't the preferred way of doing this the following?
@foo = bar
Is this equivalent to
self.foo = bar
Is this true?
Often it has the same effect.
An expression that looks like '@attr-name = value' always calls a
method whose name is 'attr-name='.
No it's the other way round. Most methods looking like 'attr_name='
are implemented like this:
# public accessor method
def attr_name=(val)
# Set instance variable @attr_name
# @attr_name is only accessible in methods of self @attr_name = val
end
Let's look at an example:
% cat foo.rb
class Foo
def initialize @text = ""
end
def text=(val)
# an empty string is a "true value" in Ruby,
# nil is a "false value" @text = val || ""
end
def text
# just return @text @text
end
def set_nil @text = nil
end
end
a = Foo.new
a.text = nil
b = Foo.new
b.set_nil
p a.text
p b.text
% ruby foo.rb
""
nil
···
On Thursday 28 July 2005 23:59, Mark Volkmann wrote:
On 7/25/05, Daniel Brockman <daniel@brockman.se> wrote:
An expression that looks like =91identifier =3D value=92 always
sets a variable, and never calls a method. This is simply
the way the language is defined.
Then this part in Pickaxe II is the first section that irritates me.
What's wrong with the Pickaxe II here? Can you point to the problem =20
section?
Oh, I see, I misread the example. I was talking about 'Variable/Method
Ambiguity', Chapter 22, page 329 and I thought that is also related to
assignment. But that is not stated there. Thanks for asking again, so I
reread the section and made things clearer. (Although the description
of Attribute Assignment, p. 350 did not mention the special case that
these methods can be private).
> An expression that looks like '@attr-name = value' always calls a
> method whose name is 'attr-name='.
No it's the other way round. Most methods looking like 'attr_name='
are implemented like this:
# public accessor method
def attr_name=(val)
# Set instance variable @attr_name
# @attr_name is only accessible in methods of self @attr_name = val
end
Let's look at an example:
% cat foo.rb
class Foo
def initialize @text = ""
end
def text=(val)
# an empty string is a "true value" in Ruby,
# nil is a "false value" @text = val || ""
end
def text
# just return @text @text
end
def set_nil @text = nil
# replace the above line with:
# self.text = nil
# and the method text= we've defined above will
# be called
end
end
a = Foo.new
a.text = nil
b = Foo.new
b.set_nil
p a.text
p b.text
% ruby foo.rb
""
nil
HTH,
Stefan
···
On Friday 29 July 2005 00:24, Stefan Lang wrote:
On Thursday 28 July 2005 23:59, Mark Volkmann wrote: