[英]block as argument to method in ruby is a mystery?
3.times {puts "Hello"}
輸出:
你好
你好
你好
我們將其理解為times
是Integer
類中的一個函數,該函數以block
作為參數。
我試圖深入研究,發現它不是那么簡單。
如果情況是times
是一個函數,並且方法調用中的括號是可選的,我嘗試使用以下方法對其進行驗證:
3.times({puts "Hello"})
它顯然引發了一個錯誤:
語法錯誤:(irb):3:語法錯誤,意外的tSTRING_BEG,期望keyword_do或'{'或'('3.times({puts“ Hello”}))^(irb):3:語法錯誤,意外的'}',預期來自/home/ashish/.rvm/rubies/ruby-2.0.0-p353/bin/irb:12:in`'中的輸入時間3.times({puts“ Hello”})^
進一步調查:
a = 3.times
puts a.class
輸出Enumerator
,其言下之意是3.times是一個Enumerator
類對象。
有人可以用這背后的確切概念來解釋整個事情嗎?
正如Sawa所說,塊不是對象,因此不會作為參數傳遞。 塊是Ruby中的特殊事物。 它們具有特殊的語法(僅允許我們將一個塊傳遞給方法)和專用於調用它們的特殊關鍵字。 這是Ruby中times
的示例實現:
def times
if block_given?
i = 0
while i < self
yield i
i += 1
end
# times returns the number that was executing times,
# so we need to return self here
self
else
enum_for :times
# ^^ This is where the Enumerator comes from if
# you don't pass a block.
end
end
塊給block_given?
方法測試是否有與當前方法關聯的塊,並且yield
關鍵字調用該塊。
塊不是參數,甚至不是對象。 將其放在括號中是沒有意義的,因為它不是對象。
Block是一個位置參數(如果已定義,則總是最后一個參數),具有用於傳遞值的特殊規則, times
可以定義為:
def times(&block)
block.call(...)
end
要調用它,您需要一個可以轉換為Proc
類實例的對象,並且應該在&
加上它:
3.times(&Proc.new { puts "Hello" })
像這樣的通話times
3.times { puts "Hello" }
只是上述形式的語法糖。
更新 :我不得不承認,它不是一個語法糖,塊是速度更快,只需添加&block
參數times
確實慢下來的東西,即使它永遠不會被調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.