Ya, pada awalnya agak membingungkan.
Di Ruby, metode dapat menerima blok kode untuk melakukan segmen kode yang sewenang-wenang.
Ketika metode mengharapkan blok, ia memanggilnya dengan memanggil yield
fungsi.
Ini sangat berguna, misalnya, untuk mengulangi daftar atau untuk menyediakan algoritma kustom.
Ambil contoh berikut:
Saya akan mendefinisikan Person
kelas yang diinisialisasi dengan nama, dan memberikan do_with_name
metode yang ketika dipanggil, hanya akan meneruskan name
atribut, ke blok yang diterima.
class Person
def initialize( name )
@name = name
end
def do_with_name
yield( @name )
end
end
Ini akan memungkinkan kami untuk memanggil metode itu dan melewati blok kode arbitrer.
Misalnya, untuk mencetak nama yang akan kita lakukan:
person = Person.new("Oscar")
#invoking the method passing a block
person.do_with_name do |name|
puts "Hey, his name is #{name}"
end
Akan mencetak:
Hey, his name is Oscar
Perhatikan, blok menerima, sebagai parameter, variabel yang disebut name
(NB Anda dapat memanggil variabel ini apa pun yang Anda suka, tetapi masuk akal untuk menyebutnya name
). Ketika kode memanggil yield
itu mengisi parameter ini dengan nilai @name
.
yield( @name )
Kami dapat menyediakan blok lain untuk melakukan tindakan yang berbeda. Misalnya, balikkan nama:
#variable to hold the name reversed
reversed_name = ""
#invoke the method passing a different block
person.do_with_name do |name|
reversed_name = name.reverse
end
puts reversed_name
=> "racsO"
Kami menggunakan metode yang persis sama ( do_with_name
) - itu hanya blok yang berbeda.
Contoh ini sepele. Penggunaan yang lebih menarik adalah memfilter semua elemen dalam array:
days = ["monday", "tuesday", "wednesday", "thursday", "friday"]
# select those which start with 't'
days.select do | item |
item.match /^t/
end
=> ["tuesday", "thursday"]
Atau, kami juga dapat menyediakan algoritme pengurutan khusus, misalnya berdasarkan ukuran string:
days.sort do |x,y|
x.size <=> y.size
end
=> ["monday", "friday", "tuesday", "thursday", "wednesday"]
Saya harap ini membantu Anda untuk memahaminya dengan lebih baik.
BTW, jika bloknya opsional Anda harus menyebutnya seperti:
yield(value) if block_given?
Jika tidak opsional, aktifkan saja.
EDIT
@hmak membuat repl.it untuk contoh-contoh ini: https://repl.it/@makstaks/blocksandyieldsrubyexample