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}