[ruby] Why use Ruby's attr_accessor, attr_reader and attr_writer?

It is important to understand that accessors restrict access to variable, but not their content. In ruby, like in some other OO languages, every variable is a pointer to an instance. So if you have an attribute to an Hash, for example, and you set it to be "read only" you always could change its content, but not the content of pointer. Look at this:

irb(main):024:0> class A
irb(main):025:1> attr_reader :a
irb(main):026:1> def initialize
irb(main):027:2> @a = {a:1, b:2}
irb(main):028:2> end
irb(main):029:1> end
=> :initialize
irb(main):030:0> a = A.new
=> #<A:0x007ffc5a10fe88 @a={:a=>1, :b=>2}>
irb(main):031:0> a.a
=> {:a=>1, :b=>2}
irb(main):032:0> a.a.delete(:b)
=> 2
irb(main):033:0> a.a
=> {:a=>1}
irb(main):034:0> a.a = {}
NoMethodError: undefined method `a=' for #<A:0x007ffc5a10fe88 @a={:a=>1}>
        from (irb):34
        from /usr/local/bin/irb:11:in `<main>'

As you can see is possible delete a key/value pair from the Hash @a, as add new keys, change values, eccetera. But you can't point to a new object because is a read only instance variable.