2010-08-10 119 views
2

我學習Ruby(使用鎬書)和我遇到一個塊操作有點混亂是去有點像這樣:在評論存在紅寶石混淆塊

class CsvReader 
    def initialize 
    @book_in_stock = [] 
    end 

    def read_in_csv_data(csv_file_name) 
    CSV.foreach(csv_file_name, headers: true) do |row| # 1. 
     @book_in_stock << BookinStock.new(row["ISBN"], row["Amount"]) # 2. 
    end 
    end 
end 

我的困惑「#1」和「2號」,我不明白我們如何得到「123」和「456」,從「test.csv」一csv_file_name包含數據:

"ISBN","Amount" 
"123","456" 

它是如何排[「ISBN」]知道下一行對應於它?所有的街區都是這樣的嗎?他們真的叫什麼?有人能解釋他們好一點嗎?

+1

見下文塊的討論我的答案,但進一步明確,因爲它有點獨立的問題,未來該行作爲一個哈希所以'行[「ISBN」]'被調用ISBN鍵處理這是第一次通過塊設置,因爲您將標題設置爲true作爲CSV foreach選項之一。所以ISBN的關鍵值是123. Ruby語法看起來像「isbn」=>「123」或key =>值。 – 2010-08-10 23:20:26

+0

這幾乎可以解答所有的問題:)謝謝。 – asdf 2010-08-10 23:22:54

+0

那麼,每行/每行都有一個新的散列? – asdf 2010-08-10 23:24:45

回答

2

塊是用於描述閉包的紅寶石成語,代碼塊有自己的範圍(它不需要知道代碼的其他部分)。塊有兩種風格,如果代碼繼續多行,您可以使用做語法(給定的數據結構或某些枚舉命名@entries)

@entries.each do |entry| 
    #do something 
end 

如果是在一行上可以簡化塊這樣

@entries.each{|entry| execute something here}

明確,無論是什麼代碼塊的作用是通過在一個時間一個條目,分配給進入並對其再做一次手術。這就像一個匿名的內部功能。

他們是有點難以在第一理解,但真正有用的和遍佈世界的紅寶石。我們有時會發生阻塞炎。

其使用情況,認爲我們想要做的事,以每個值在數組中。

[1,2,3].map{|item| item+1} #=> takes each item in the array gets one added to it 

什麼是不那麼明顯的是,這個功能,因爲內部函數負責迭代通過數據結構返回數組[2,3,4]。這比使用另一個在數組上運行的函數和另一個函數還要爲每個項添加一個函數要方便得多並且聲明得多。

在csv示例中,您正在將每行都添加到一個名爲@books_in_stock的數據結構中,但它並不那麼明確,我認爲這是我給出的示例。查看Enumearble類http://apidock.com/ruby/Enumerable,瞭解使用塊的很多好例子。

+0

這是非常有趣的,我也從中學到了很多東西而已,但它並沒有真正回答問題,這個問題我不要以爲 - 謝謝! – asdf 2010-08-10 23:23:28

0

這是ruby自帶的csv模塊的一個功能。當您創建CSV對象時,您會在標題中傳遞:true標誌,它告訴csv對象名稱或列以及存在多少列。之後,在cvs類上定義的foreach方法爲表中的每一行設置別名行。然後用每行中的數據填充散列行。

+0

我試圖理解,我認爲我做了一個對象,但你不是很連貫。謝謝! – asdf 2010-08-10 23:06:51

+0

它是草草寫的,所以我編輯它,希望它更有意義。 – ennuikiller 2010-08-10 23:11:03

1

沒有親自使用Ruby的CSV類,但它看起來像,因爲它是被告知「標題:真正的」它假定第一行包含頭文件和每個以下行是對應於它上面的標題數據。

0

好了,只要你創建使用do...end或塊{...}你有效地創建一個匿名方法:

my_method do |arg1,arg2| 
    ... 
end 

是同一種東西

def ... arg1, arg2 
    ... 
end 

的一點是,在您撥打的方法(foreach)可以隨時調用您的do...end塊中的代碼,並使用它選擇的任何參數。對於foreach方法,它會調用一次你的格擋它具有處理每一行,該行會提供的row變量(不同的每個時間)內,就好像它是一個方法的參數

編輯

您的具體問題的答案在於類型的變量傳遞到行中。它看起來像是一個CSV :: Row對象,它定義了一個方法row.[],它允許您獲取出現在您傳遞的標題下方的那一行的值。

+0

似乎很複雜,但我猜迄今爲止這是最正確的答案。由於 – asdf 2010-08-10 23:18:08

+0

所以,它是一個散列或者是定義爲一個方法「行。[]」 :) – asdf 2010-08-10 23:23:56

+0

說實話,差異並不重要,只要你關心。通過[]進行「哈希式」訪問是許多充當集合的ruby類中的常見習慣用法。如果需要,可以隨時調用的地方輸出row.class,看到返回什麼... – Gareth 2010-08-11 06:22:44

0

進來的行被視爲散列,因此row["ISBN"]正在調用通過塊第一次設置的ISBN鍵,因爲您將標頭設置爲真正的CSV foreach選項之一。因此對於ISBN密鑰值是123的Ruby語法看起來像"isbn" => "123"key => value

在這種情況下各行進來的被視爲其中鍵是由標題行設置並且該值被從載置得到的單獨的散在csv行內。