2016-05-18 15 views
-1

我不能夠理解這個代碼的邏輯:「每個」和「注入(符號)」方法如何在下面的代碼中工作?

class VowelFinder 
    include Enumerable 
    def initialize(string) 
    @string = string 
    end 

    def each 
    @string.scan(/[aeiou]/) do |vowel| 
     yield vowel 
    end 
    end 
end 

vf = VowelFinder.new("the quick brown fox jumped") 
vf.inject(:+) # => "euiooue" 
  1. 如何對象vf.inject(:+)調用該程序的方法each

  2. each方法在這個程序中如何工作,因爲在函數定義中沒有提到塊參數?

  3. 如果我只是打電話vf.each,爲什麼我會收到以下錯誤?

    vowel_finder.rb:8:in `block in each': no block given (yield) (LocalJumpError) 
    from vowel_finder.rb:8:in `scan' 
    from vowel_finder.rb:8:in `each' 
    from vowel_finder.rb:13:in `<main>' 
    

之一幾件事情,我理解的是,在這個類的each方法覆蓋從包含Enumerable模塊each方法。除此之外,我不明白任何關於each和塊。

有人可以請解釋我的邏輯和它是如何工作的內部?

+1

可能重複的[在Ruby中的塊和產量](http://stackoverflow.com/questions/3066703/blocks-and-yields-in-ruby) –

+0

可能會通過文章[在Ruby中構建枚舉和枚舉器](https://www.practicingruby.com/articles/building-enumerable-and-enumerator)會讓事情變得清晰 –

回答

1

inject方法來自Enumerable類,它包含在VowelFinder中。作爲inject的實施的一部分,它調用稱爲each的方法。

inject期望的是,它被稱爲所述對象具有限定的each方法中,作爲Enumerable確實提供一種each方法。通常,inject被稱爲容器類的實例,例如ArrayHash,它們根據其容器設計確定each

因此,當vf.inject(:+)呼叫each,它結束調用VowelFinder#each,被操作的對象是vfeachVowelFinder定義。

在Ruby中,您可以聲明一個隱式接受塊的方法,如each所做的那樣。從技術上講,Ruby中的所有方法都接受一個塊,但只有一些方法調用塊。 yield語句用於調用該塊。

Ruby有一個名爲block_given?的內置函數,用於檢測塊是否已傳遞給方法。 ArrayHash上的許多方法使用block_given?來確定是調用塊還是返回Enumerator。檢查block_given?允許塊被有條件地調用,像這樣:

def each 
    if block_given? 
    @string.scan(/[aeiou]/) do |vowel| 
     yield vowel 
    end 
    else 
    # Do something interesting here, or better yet, return an Enumerator 
    end 
end 

在這種情況下,each可以稱爲這種方式:

vf = VowelFinder.new("the quick brown fox jumped") 
vf.each {|vowel| puts "Found the vowel: #{vowel}" } 

或這種方式:

vf.each 

的在VowelFinder#each方法中的else用於學習練習以返回枚舉數,如同約定。

Enumerators and Enumerables章節RubyMonk對此主題有非常好的報道。

+0

@NarayananKrishnan如果已回答您的問題,請點擊答案旁邊的複選標記以接受它。複選標記會將顏色更改爲綠色。 Upvotes也是非常值得讚賞的。 :d –

相關問題