[Ruby] Blocks and Yields in Ruby
Read More: http://stackoverflow.com/questions/3066703/blocks-and-yields-in-ruby
Yes, it is a bit puzzling at first.
In Ruby, methods may receive a code block in order to perform arbitrary segments of code.
When a method expects a block, it invokes it by calling the yield
function.
This is very handy, for instance, to iterate over a list or to provide a custom algorithm.
Take the following example:
I'm going to define a Person
class initialized with a name, and provide a do_with_name
method that when invoked, would just pass the name
attribute, to the block received.
class Person
def initialize( name )
@name = name
end
def do_with_name
yield( @name )
end
end
This would allow us to call that method and pass an arbitrary code block.
For instance, to print the name we would do:
person = Person.new("Oscar")
#invoking the method passing a block
person.do_with_name do |name|
puts "Hey, his name is #{name}"
end
Would print:
Hey, his name is Oscar
Notice, the block receives, as a parameter, a variable called name
(N.B. you can call this variable anything you like, but it makes sense to call it name
). When the code invokes yield
it fills this parameter with the value of @name
.
yield( @name )
We could provide another block to perform a different action. For example, reverse the name:
#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"
We used exactly the same method (do_with_name
) - it is just a different block.
This example is trivial. More interesting usages are to filter all the elements in an array:
days = ["monday", "tuesday", "wednesday", "thursday", "friday"]
# select those which start with 't'
days.select do | item |
item.match /^t/
end
=> ["tuesday", "thursday"]
Or, we can also provide a custom sort algorithm, for instance based on the string size:
days.sort do |x,y|
x.size <=> y.size
end
=> ["monday", "friday", "tuesday", "thursday", "wednesday"]
I hope this helps you to understand it better.
BTW, if the block is optional you should call it like:
yield(value) if block_given?
相关文章
- javascript、ruby和C性能一瞥(2)
- ruby正则表带式对象使用备忘
- ubuntu下无法编译ruby-2.1.5提示something wrong with CFLAGS -arch x86_64
- ruby TkPackage can't find package BWidget 之解决办法
- 如何让ruby中的ri起作用
- 写的一个inter类模仿ruby整数的行为
- ruby备忘录
- Centos7安装升级Ruby和集群搭建参考
- [Ruby] Modules -- Ex
- [Ruby] 1. Expression
- [Ruby] 1. Expression -- Ex
- editplus支持RUBY和运行[转]
- 大数据基础之Logstash(3)应用之file解析(grok/ruby/kv)
- [Ruby] LEVEL 2 Methods and Classes
- [Ruby] Modules
- Ruby: Count unique elements and their occurences in an array