2013-09-24 180 views
0

我剛剛從1.9鎬叢書中找到了一個例子,我很困惑爲什麼在csv_reader.rb文件中沒有使用attr_accessor就能成功運行下面的程序。Ruby:爲什麼我們不需要`attr_accessor`?

book_in_stock.rb

class BookInStock 
    attr_accessor :price, :isbn 

    def initialize(price, isbn) 
    @price = Float(price) 
    @isbn = isbn 
    end 
end 

我們是不是通過添加新BookInStock對象將其寫入csv_reader對象的實例變量?

csv_reader.rb

require 'csv' 
require_relative 'book_in_stock' 

class CsvReader 
    def initialize 
    @book_in_stock = [] 
    end 

    def read_in_csv_data(csv_file) 
    CSV.foreach(csv_file, headers: true) do |row| 
     @book_in_stock << BookInStock.new(row["price"], row["isbn"]) 
    end 
    end 

    def total_value_in_stock 
    sum = 0 
    @book_in_stock.each {|book| sum += book.price} 
    sum 
    end 
end 

test_data.csv

"price","isbn" 
"44.12",'asdf34r13' 
"74.12",'asdf34r13' 
"14.12",'asdf34r13' 
"42.12",'asdf34r13' 
"4774.12",'asdf34r13' 
"04.19",'asdf34r13' 

的軟件驅動程序

require_relative 'csv_reader' 

reader = CsvReader.new 

ARGV.each do |csv_file_name| 
    STDERR.puts "Processing the thing" 
    reader.read_in_csv_data(csv_file_name) 
end 

puts "Total Value = #{reader.total_value_in_stock}" 

是在read_in_csv_data方法做同樣的工作作爲一個存取方法?

+1

在'total_value_in_stock'方法中,您可以調用'BookInStock#price',這是沒有'attr_accessor'的情況下不可用的。因此,如果您不打電話,我強烈懷疑您的計劃有效。 –

+0

我想現在我明白了這個問題,但是我指的是@book_in_stock實例變量,我的主要困惑是爲什麼我們能夠寫入/設置它,而沒有在類的頂部聲明類似'attr_writer:book_in_stock'的東西。但是,馬克斯在下面澄清了我的困惑。 –

回答

3

attr_accessor創建了兩個方法,看起來大致是這樣的,如果你用手把它們寫:

def price 
    @price 
end 

def price=(new_price) 
    @price = new_price 
end 

你永遠不會調用任何的那些方法,因此他們是否存在,或者它是不是無關緊要的。

+0

我在'total_value_in_stock'中調用price方法。所以,我想這可能就是'attr_reader'。但是,我指的是'csv_reader.rb'文件,如果我理解正確,它正在寫入該對象的實例變量。如何在不使用訪問器方法的情況下執行此操作?這是我誤解。 –

+2

你不是在調用這個方法。您正在分配給一個變量。 –

+1

實例變量始終在類內部,因此您不需要訪問器方法來讀/寫它們。您可以直接使用這些變量。 – Max