attr_reader means you can get a reference to the cars collection, to which
then you are adding items. attr_reader doesn't imply that the thing it's
returning will be treated as read only. That it means is that the user is
not allowed to replace the collection itself.
···
On 7/25/05, EdUarDo <eduardo.yanezNOSPAM@nospamgmail.com> wrote:
Hi again,
I have this class:
class A
attr_reader :name, :cars
attr_writer :name
def initialize(name) @name = name @cars = Array.new()
end
end
a = A.new("xxxx")
a.cars << "vectra" << "megane"
puts a
output:
vectra
megane
Why can I access cars and modify it if I have not declared it how
attr_writer. Must I simply declare it private?
class A
attr_reader :name, :cars
attr_writer :name
def initialize(name) @name = name @cars = Array.new()
end
end
a = A.new("xxxx")
a.cars << "vectra" << "megane"
puts a
output:
vectra
megane
Why can I access cars and modify it if I have not declared it how
attr_writer. Must I simply declare it private?
a.cars = nil # This gives an error
The restriction is on the variable, not on the object that is bound to
the variable. To restrict that object, you can #freeze it, but that will
affect all access, including within the class A.
Making a writer for it would mean you could set cars with code like:
a.cars = Hash.new
The code you show is not changing cars, it's just calling methods on the Array cars holds.
If you want to disallow this, you'll need to do some forwarding, for the methods you wish to allow. However, I say think and make sure this is strictly necessary before you bolt down the gates. Don't kill yourself securing what doesn't strictly need securing. If I type a.cars.clear I either know what I'm doing or deserve to see things explode. It's my opinion that neither of those are your problem.
James Edward Gray II
···
On Jul 25, 2005, at 12:45 PM, EdUarDo wrote:
Hi again,
I have this class:
class A
attr_reader :name, :cars
attr_writer :name
def initialize(name) @name = name @cars = Array.new()
end
end
a = A.new("xxxx")
a.cars << "vectra" << "megane"
puts a
output:
vectra
megane
Why can I access cars and modify it if I have not declared it how
attr_writer. Must I simply declare it private?
Why can I access cars and modify it if I have not declared
it [with] attr_writer?
The code you show is not changing cars, it's just
calling methods on the Array cars holds. If you want
to disallow this, you'll need to do some forwarding,
for the methods you wish to allow. However, I say
think and make sure this is strictly necessary before
you bolt down the gates.
You might also ask yourself whether you really need to
expose the array object itself. You may be able to get away
with defining #each and including Enumerable, for instance.
class BunchaCars
include Enumerable
def initialize(name) @cars = Array.new @name = name
end
def each @cars.each { |x| yield x }
end
end
This approach may or may not be appropriate in your case.
(We'd need more information to be able to tell.)
···
--
Daniel Brockman <daniel@brockman.se>
So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.