簡體   English   中英

塊作為紅寶石方法的參數是一個謎嗎?

[英]block as argument to method in ruby is a mystery?

3.times {puts "Hello"}

輸出:

你好
你好
你好

我們將其理解為timesInteger類中的一個函數,該函數以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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM