yield
私はブロックとそれが Ruby でどのように機能するかを理解しようとしています。
どのように使用されるのでしょうかyield
? 私が調べた Rails アプリケーションの多くはyield
奇妙な方法で使用されています。
誰か私に説明してくれませんか、または理解するにはどこに行けばよいか教えてくれませんか?
ベストアンサー1
はい、最初は少し戸惑います。
Ruby では、メソッドはコード ブロックを受け取り、任意のコード セグメントを実行できます。
メソッドがブロックを必要とする場合は、yield
関数を呼び出すことによってそれを呼び出すことができます。
例:
属性とメソッドPerson
を持つクラスを取ります。メソッドが呼び出されると、属性がブロックに渡されます。name
do_with_name
name
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