No,
It's not strange in any way.
attr_reader simply gives you what java would call a "getter" method. A means to access the variable. It says nothing about the status or changeableness of the variable itself. It's about the attribute. Try as you might, you will not be able to change the variable that is assigned to a attr_reader specified attribute of an object.
For instance.
class Blah
def initialize(someval = "hi")
@yeah = someval
end
b = Blah.new
now, without opening up the class again, try to set the value of yeah inside this instantiated Blah object (b).
You can't, becuase there is no "yeah=" method defined (manually, or by attr_writer)
The object itself cannot be changed.
Now, if we open up the class again, and give it a reader method
class Blah
def yeah
@yeah
end
Now, try as we might again, we STILL cannot modify the object that it points to.
HOWEVER, we CAN modify the object itself. This is implicit. Ruby is VERY flexible.
For instance, if we wanted to we could do the following:
b.yeah[0] = 'P'
then accessing b.yeah will yield 'Pi'
but if we query the object, it's still the same object, it's just been modified. Note, though, that it is still the same object!
So, sending the "" message to yeah is not actually modifying any of b's data. It's modifying some of b's ENCAPSULATED data, but not any of b's direct data.
This is a good thing. It goes hand in hand with dynamic typing (IMHO).
Ruby creates a world where it dares to give programmers the no-illusions awareness that they have the freedom and power to do as they please, and assumes they don't want to have any barriers to that freedom and power.
It turns out that programmers never do stupid things simply because they can, in much the same way that drivers of cars rarely crash cars on purpose.
Rules come out of fear.
I point you towards the Tao te Ching, one of the east's oldest texts, stanza 38.
38. Degeneration
The man of superior character is not (conscious of his) character.
Hence he has character.
The man of inferior character (is intent on) not losing character.
Hence he is devoid of character.
The man of superior character never acts,
Nor ever (does so) with an ulterior motive.
The man of inferior character acts,
And (does so) with an ulterior motive.
The man of superior kindness acts,
But (does so) without an ulterior motive.
The man of superior justice acts,
And (does so) with an ulterior motive.
(But when) the man of superior li acts and finds no response,
He rolls up his sleeves to force it on others.
Therefore:
After Tao is lost, then (arises the doctrine of) humanity.
After humanity is lost, then (arises the doctrine of) justice.
After justice is lost, then (arises the doctrine of) li.
Now li is the thinning out of loyalty and honesty of heart.
And the beginning of chaos.
The prophets are the flowering of Tao
And the origin of folly.
Therefore the noble man dwells in the heavy (base),
And not in the thinning (end).
He dwells in the fruit,
And not in the flowering (expression).
Therefore he rejects the one and accepts the other.
In particular, after tao is lost, arises humanity, after humanity is lost, arises justice.
Justice is rules. Now, do we need rules to bind us, or are we enlightened enough to follow a path where no rules are necessary, because we follow a way where our inner sense of naturalness and beauty guides us on our way?
Julian.
Learn Ruby on Rails! Check out the FREE VIDS (for a limited time) VIDEO #3 out NOW!
http://sensei.zenunit.com/
路路路
On 10/04/2008, at 8:22 AM, Hexren wrote:
A writable attribute is different from a mutable object. You can't set
the attribute to a new object, but the read operation does expose the
object behind the attribute -- so if that object is mutable, you can
mutate it.
And that doesnt sound strange to you ?
I see why the stuff is writable in a technical sense.
However that is not changing my opinion: Something called "attr_reader :foo" should not allow somebody to write to "private @foo".
And if it does make something writable it should say so in the api doc and not hope that everybody catches that fact by glancing at the example in the doc.
Which btw: is for the other case "writable=true".
Oliver