2014-02-28 130 views
-1

如果有人能爲我闡明一個燈,或者用PHP風格的代碼展示一個等價的(如果存在的話),我真的很喜歡它。塊做什麼?

這段代碼:

require 'sqlite3' 
SQLite3::Database.new("metadata.db").execute("SELECT * from BOOKS") do |row| 
     puts row 
end 

使用execute方法來發出SQL查詢。它正在做一個循環,但在什麼?在該查詢的返回值?你可以追加一段代碼到任何表達式,它會在其返回值上工作嗎?似乎循環沒有連接任何東西,並且從零開始出現|row|

爲了進行比較,在PHP訪問數據庫時我會寫

$db = new mysqli('details'); 
$results = $db->query("SELECT * FROM books"); 
while ($row = $results->fetch()) { 
    echo $row[0]; 
} 

它說創建一個數據庫,存儲查詢作爲results的結果,然後開始一個循環,其中該結果的每一行被轉換成一個數組來訪問數組符號。那不是Rubyrian會怎麼做的嗎?這裏發生了什麼?

+0

這不是紅寶石主義者會怎麼做的,因爲它冗長而醜陋。塊不會自動在返回值上工作。這種類型的操作在很多Ruby教程中都有討論,也許最好從這裏開始。你也可以搜索諸如「編寫範圍塊的ruby方法」之類的東西,這樣你就可以看到如何做你自己的,這可能更具教育意義。 –

+0

許多JS庫使用類似的技術,順便說一句,但有一個功能,而不是一個塊。它非常相似。 –

+0

考慮將塊作爲參數傳遞給方法的算法,方法可以執行它。塊可能有一些參數,方法應該在調用時傳遞值來阻止。爲什麼不讀一些關於Ruby的書? – taro

回答

1

它正在做一個循環,但在什麼?在該查詢的返回值?

沒錯。在您的例子row是無論是通過

SQLite3::Database.new("metadata.db").execute("SELECT * from BOOKS")

產生在這種情況下row一件合理的事打電話這一點,因爲你做任何行動,該塊將基於從數據庫該行,但你可以選擇把這個'塊參數'稱爲任何你想要的。

這是發生在Ruby中的事情嗎,你可以在那裏立即追加一段代碼給任何表達式,它會在它的返回值上工作嗎?

不是,沒有。有一些方法需要塊參數 - each就是一個很好的例子。

如果您在動物醫院擁有貓的集合,您可以通過它們循環並對每隻貓進行操作,因爲each需要塊參數。

#pretend these cats are objects and not just a string name 
cats = [ "mrs. muffin face", "princess cupcake", "deathlord 666", ...] 

cats.each do |cat| 
    #do stuff with each cat here. print their name, find their shoe size, etc 
end 

塊是一個非常基本的概念,紅寶石,因此它可能是值得一讀多一點關於他們 - this answer鏈接Why's (poignant) guide to ruby這通常是一個很好的基本參考。我還建議使用Eloquent Ruby以獲得更完整的Ruby示例。

+0

感謝您的意見和鏈接,我想我現在就明白了。我將在週末開始閱讀這些網站。 – GreenTriangle

0

你似乎認爲塊是循環結果的東西,但這不一定是正確的。 Ruby中的塊與參數相反。在執行main方法之前評估參數,而不預先評估塊。是否要評估這個塊,在什麼樣的約束下進行評估,評估什麼時間以及評估多少次,都取決於主要方法。 | |中的塊變量是主方法傳遞給塊的參數。通常情況下,主方法返回的值不包含塊,這些元素會一個接一個地傳遞,這是您的想法,但情況並非總是如此。

0

這裏是如何execute可能在Ruby中

編碼
class SQLite3::Database 
    def execute(query_str) 
    results = db.query(query_str) 
    while (row = results.fetch) 
     yield row 
    end 
    end 
end 

(假設db.queryresults.fetch的工作,你會從PHP期望)。正如你所看到的,除了奇怪的yield之外,這與你從PHP中使用的幾乎完全相同。由於該方法遍歷結果的各行,因此yield會將每行傳遞給該塊。

這可以讓您專注於重要的東西(如何處理每行),同時隱藏附帶的細節(例如遍歷result變量)。