Ruby/Method/yield
Материал из Wiki.crossplatform.ru
after yield executes, control comes back to the next statement immediately following yield.
def gimme if block_given? yield else puts "Oops. No block." end puts "You"re welcome." # executes right after yield end gimme { print "Thank you. " } # => Thank you. You"re welcome.
contain two yields, then call it with a block. It executes the block twice.
def gimme if block_given? yield yield else puts "I"m blockless!" end end gimme { print "Say hi again. " } # => Say hi again. Say hi again.
execute the yield statement any number of times
def greeting() yield yield yield end greeting {puts "Hello there!"}
Generating a Sequence of Numbers
def fibonacci(limit = nil) seed1 = 0 seed2 = 1 while not limit or seed2 <= limit yield seed2 seed1, seed2 = seed2, seed1 + seed2 end end fibonacci(3) { |x| puts x } # 1 # 1 # 2 # 3 fibonacci(1) { |x| puts x } # 1 # 1 fibonacci { |x| break if x > 20; puts x } # 1 # 1 # 2 # 3 # 5 # 8 # 13
How do you reach the code in the block from inside the method?
# You use the yield statement, which is designed for exactly that purpose. def greeting() yield end greeting {puts "Hello there!"}
So not only can you pass arguments to a method, you can also pass code blocks - and the method can even pass arguments to that code block.
def greeting() yield "Hello", "there!" yield "Bye", "now." end greeting {|word_one, word_two | puts word_one + " " + word_two}
Write a simple function that returns members of the Fibonacci series up to a certain value.
def fib_up_to(max) i1, i2 = 1, 1 # parallel assignment (i1 = 1 and i2 = 1) while i1 <= max yield i1 i1, i2 = i2, i1+i2 end end fib_up_to(1000) {|f| print f, " " }
yield method automatically detects any passed code block and passes control to it
def each_vowel %w{a e i o u}.each { |vowel| yield vowel } end each_vowel { |vowel| puts vowel }
yield with proc parameter
#!/usr/local/bin/ruby def return_block yield end def return_proc( &proc ) yield end return_block { puts "Got block!" } return_proc { puts "Got block, convert to proc!" }
You can pass data to code clocks used with methods simply by passing that data to the yield statement.
def greeting() yield "Hello", "there!" end greeting {|word_one, word_two | puts word_one + " " + word_two}