Rubyのブロックとyield 質問する

Rubyのブロックとyield 質問する

yield私はブロックとそれが Ruby でどのように機能するかを理解しようとしています。

どのように使用されるのでしょうかyield? 私が調べた Rails アプリケーションの多くはyield奇妙な方法で使用されています。

誰か私に説明してくれませんか、または理解するにはどこに行けばよいか教えてくれませんか?

ベストアンサー1

はい、最初は少し戸惑います。

Ruby では、メソッドはコード ブロックを受け取り、任意のコード セグメントを実行できます。

メソッドがブロックを必要とする場合は、yield関数を呼び出すことによってそれを呼び出すことができます。

例:

属性とメソッドPersonを持つクラスを取ります。メソッドが呼び出されると、属性がブロックに渡されます。namedo_with_namename

class Person 
    def initialize( name ) 
         @name = name
    end

    def do_with_name   # expects a block
        yield( @name ) # invoke the block and pass the `@name` attribute
    end
end

これで、このメソッドを呼び出して任意のコード ブロックを渡すことができます。

person = Person.new("Oscar")

# Invoking the method passing a block to print the value
person.do_with_name do |value|
    puts "Got: #{value}"
end

次のように印刷されます:

Got: Oscar

ブロックは という変数をパラメータとして受け取ることに注意してくださいvalue。コードがyieldそれを呼び出すと、 の値が引数として渡されます@name

yield( @name )

同じメソッドを別のブロックで呼び出すことができます。

たとえば、名前を逆にするには次のようにします。

reversed_name = ""

# Invoke the method passing a different block
person.do_with_name do |value| 
    reversed_name = value.reverse
end

puts reversed_name

=> "racsO"

その他の興味深い実生活の例:

配列内の要素をフィルタリングします。

 days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]  

 # Select those which start with 'T' 
 days.select do | item |
     item.match /^T/
 end

=> ["Tuesday", "Thursday"]

または、名前の長さで並べ替えます:

 days.sort do |x,y|
    x.size <=> y.size
 end

=> ["Monday", "Friday", "Tuesday", "Thursday", "Wednesday"]

ブロックがオプションの場合は、以下を使用できます。

yield(value) if block_given?

オプションでない場合は、単に呼び出します。

これらの例をコンピュータで試すことができますirbインタラクティブ Ruby シェル

以下に、コピー/貼り付け可能な形式のすべての例を示します。

class Person 
    def initialize( name ) 
         @name = name
    end

    def do_with_name   # expects a block
        yield( @name ) # invoke the block and pass the `@name` attribute
    end
end


person = Person.new("Oscar")

# Invoking the method passing a block to print the value
person.do_with_name do |value|
    puts "Got: #{value}"
end


reversed_name = ""

# Invoke the method passing a different block
person.do_with_name do |value| 
    reversed_name = value.reverse
end

puts reversed_name



# Filter elements in an array:    
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]  

# Select those which start with 'T' 
days.select do | item |
    item.match /^T/
end



# Sort by name length:     
days.sort do |x,y|
   x.size <=> y.size
end

おすすめ記事