Attribute helpers create small methods for reading and writing object state.

attr accessor `attr_reader`, `attr_writer`, and `attr_accessor` create common getter and setter methods.

Attr Readers Writers

level
attr_readers_writers.rb
Replay: real traced execution (multi-file project)
class Profile
  attr_reader :name
  attr_accessor :level

  def initialize(name, level)
    @name = name
    @level = level
  end
end

level = 2
profile = Profile.new("Ada", level)

puts "name=#{profile.name}"
puts "level=#{profile.level}"

profile.level = profile.level + 1

puts "next_level=#{profile.level}"
class Profile
  attr_reader :name
  attr_accessor :level

  def initialize(name, level)
    @name = name
    @level = level
  end
end

level = 1
profile = Profile.new("Ada", level)

puts "name=#{profile.name}"
puts "level=#{profile.level}"

profile.level = profile.level + 1

puts "next_level=#{profile.level}"
class Profile
  attr_reader :name
  attr_accessor :level

  def initialize(name, level)
    @name = name
    @level = level
  end
end

level = 5
profile = Profile.new("Ada", level)

puts "name=#{profile.name}"
puts "level=#{profile.level}"

profile.level = profile.level + 1

puts "next_level=#{profile.level}"
  1. level ← 2

    1class Profile2  attr_reader :name3  attr_accessor :level45  def initialize(name, level)6    @name = name7    @level = level8  end9end1011level→ 2 = 2  #@level=1, 512profile = Profile.new("Ada", level2)
  2. @name ← Ada, @level ← 2

    5def initialize(nameAda, level2)6  @name→ Ada = nameAda7  @level→ 2 = level28end
  3. profile ← ⟨Profile A @name="Ada", @level=2⟩, profile.level ← 3

    11level = 2  #@level=1, 512profile→ ⟨Profile A @name="Ada", @level=2⟩ = Profile.new("Ada", level2)1314puts "name=#{profile.nameAda}"15puts "level=#{profile.level2}"1617profile.level→ 3 = profile.level + 11819puts "next_level=#{profile.level3}"
    outputname=Ada
    level=2
    next_level=3
  1. level ← 1

    1class Profile2  attr_reader :name3  attr_accessor :level45  def initialize(name, level)6    @name = name7    @level = level8  end9end1011level→ 1 = 112profile = Profile.new("Ada", level1)
  2. @name ← Ada, @level ← 1

    5def initialize(nameAda, level1)6  @name→ Ada = nameAda7  @level→ 1 = level18end
  3. profile ← ⟨Profile A @name="Ada", @level=1⟩, profile.level ← 2

    11level = 112profile→ ⟨Profile A @name="Ada", @level=1⟩ = Profile.new("Ada", level1)1314puts "name=#{profile.nameAda}"15puts "level=#{profile.level1}"1617profile.level→ 2 = profile.level + 11819puts "next_level=#{profile.level2}"
    outputname=Ada
    level=1
    next_level=2
  1. level ← 5

    1class Profile2  attr_reader :name3  attr_accessor :level45  def initialize(name, level)6    @name = name7    @level = level8  end9end1011level→ 5 = 512profile = Profile.new("Ada", level5)
  2. @name ← Ada, @level ← 5

    5def initialize(nameAda, level5)6  @name→ Ada = nameAda7  @level→ 5 = level58end
  3. profile ← ⟨Profile A @name="Ada", @level=5⟩, profile.level ← 6

    11level = 512profile→ ⟨Profile A @name="Ada", @level=5⟩ = Profile.new("Ada", level5)1314puts "name=#{profile.nameAda}"15puts "level=#{profile.level5}"1617profile.level→ 6 = profile.level + 11819puts "next_level=#{profile.level6}"
    outputname=Ada
    level=5
    next_level=6

Follow the Attributes

  1. level starts as 2.
  2. Profile.new("Ada", level) stores @name = Ada and @level = 2.
  3. profile.name reads the name through attr_reader.
  4. profile.level reads the level through attr_accessor.
  5. Assigning profile.level = profile.level + 1 changes the level to 3. | read or write | value | | --- | --- | | profile.name | Ada | | starting profile.level | 2 | | after writer call | 3 |

Exercise: attr_readers_writers.rb

Reproduce name=Ada, level=2, and next_level=3, then use the pinned level variants 1 and 5 to predict next_level=2 and next_level=6.