简体   繁体   中英

To @ or not to @ in Ruby on Rails

Why do you have to refer to your class properties sometimes with @ and sometimes without it? If I were to remove the '@completed' and replace with 'completed', the test fails. But in the Project class the tasks property is set the same way but can be used without the @.

class Task
  attr_accessor :size, :completed

  def initialize(options = {})
    @completed = options[:completed]
    @size = options[:size]
  end

  def completed?
    @completed
  end

  def mark_completed
    @completed = true
  end
end


class Project
  attr_accessor :tasks

  def initialize
    @tasks = []
  end

  def done?
    tasks.reject(&:completed?).empty?
  end

  def total_size
    tasks.sum(&:size)
  end

  def remaining_size
    tasks.reject(&:completed?).sum(&:size)
  end
end


describe "estimates" do
    let (:project) { Project.new }
    let (:done) { Task.new(size: 2, completed: true) }
    let(:small_not_done) { Task.new(size: 1) }
    let(:large_none_done) { Task.new(size: 4) }

    before(:example) do
      project.tasks = [done, small_not_done, large_none_done]
    end

    it "can calculate total size" do
      expect(project.total_size).to eq(7)
    end

    it "can calculate remaining size" do
      expect(project.remaining_size).to eq(5)
    end
  end

attr_accessor :tasks is equivalent to:

def tasks
  @tasks
end

def tasks=(val)
  @tasks = val
end

When you call tasks , you are calling the tasks method, which just returns the value of the @tasks variable. The accessor method will always be used from outside of the class (since the instance variable isn't visible), but you can use either from within the class, since they're functionally equivalent for this implementation of the tasks method . However, you may want to use the tasks accessor if you may ever do something other than just returning @tasks - by hiding the variable access behind a method, you are free in the future to do more complex work in that accessor, without having to change the places that you use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM