%w(hashrockets spaceships bangbangs)

> non-optimized bits & pieces <

Module#attr_accessor & Friends

Have u ever find urself writing simple reader & writer like this:

1
2
3
4
5
6
7
8
class Thing
  def size=(size)
    @size = size
  end
  def size
    @size
  end
end

You should probably be using Module#attr_accessor:

1
2
3
4
5
6
7
class Thing
  attr_accessor :size
end

t = Thing.new
t.size = :xl
puts t.size # >> xl

If u want to keep the writer private, while still having the reader as public, you can do the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Thing
  attr_accessor :size
  private :size=

  def cheat(size)
    self.size = size
  end
end

t = Thing.new
#puts t.size = :xl # >> NoMethodError
t.cheat(:xl)
puts t.size        # >> xl

Besides Module#attr_accessor, we also have Module#attr_reader & Module#attr_writer, each generating just the reader/writer that u need.

Using the above accessor generators not only improve the readability of ur code, the generated accessors are also more performant. Here’s a quick benchmark:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class AA
  attr_accessor :size
end

class BB
  def size        ; @size        ; end
  def size=(size) ; @size = size ; end
end

require 'benchmark'
Benchmark.bm do |x|
  [AA, BB].each do |klass|
    x.report do
      1000000.times do
        aa = klass.new
        aa.size = 2
        aa.size
      end
    end
  end
end

#>> user     system      total        real
#>> 0.410000   0.000000   0.410000 (  0.412785)
#>> 0.450000   0.000000   0.450000 (  0.456264)

The difference is there, but it isn’t too much for just a pair of accessors. It would be more significant as the number of accessors increases. Anyway, i’ll leave it as an exercise for the reader.

ruby, tips

Comments