RailsCasts6 Shortcut Blocks with Symbol to_proc 将Symbol 转化为to_proc来简化block

下面代码find方法中这种看起来奇怪的语法,一个&符号后面跟着一个名字,叫做to_proc。是Rails对Ruby的一点功能扩充。

ruby
class Project < ActiveRecord::Base
  has_many :tasks

  def self.all_names
    find(:all).collect(&:name)
  end
end

我们通过Rails Console下的一个例子来解释。Rails script/console命令启动Rails控制台。首先,获取所有的Project

terminal
Laa-Laa:todo eifion$ script/console
Loading development environment (Rails 2.2.2)
>> projects = Project.find(:all)
=> [#<Project id: 1, name: "Write another ASCIIcast", created_at: "2008-12-29 09:32:47", updated_at: "2008-12-29 09:32:47">, #<Project id: 2, name: "Go out walking", created_at: "2008-12-29 09:33:04", updated_at: "2008-12-29 09:33:04">]

结果中包含两个项目对象以列表格式返回,如果我们想得到这两个对象的名字应该怎么做呢?第一种方法就是使用collect方法,在供回调的代码块中填写返回项目名称的逻辑。collect方法的作用是遍历列表,并让每一个项目中的对象执行代码块中定义的逻辑操作并得到返回值,这样将返回一个基于原来列表的返回值列表。

terminal
>> projects.collect { |p| p.name }
=> ["Write another ASCIIcast", "Go out walking"]

to_proc允许你给一段需要传递给代码块的逻辑起一个名字,这样写在代码块中的逻辑就可以定义在其他地方,代码块中只需传入&逻辑名字的参数了。就像下面的样子:

terminal
>> projects.collect (&:name)
=> ["Write another ASCIIcast", "Go out walking"]

当你需要链式调用的时候,这种格式的作用就更明显了。下面的代码是不是可读性更强了:

terminal
>> projects.collect(&:name).collect(&:upcase)
=&gt; ["WRITE ANOTHER ASCIICAST", "GO OUT WALKING"]

当然了,不仅仅局限于collect方法,所有代码块都可以使用to_proc。比如说可以为any方法定义检查项目是否正常开展的to_proc,为all方法可以定义保存的to_proc等等。

terminal
>> projects.all?(&:valid?)
=> true
>> projects.any?(&:valid?)
=> true
>> projects.each(&:save!)
=> [#<Project id: 1, name: "Write another ASCIIcast", created_at: "2008-12-29 09:32:47", updated_at: "2008-12-29 09:32:47">, #<Project id: 2, name: "Go out walking", created_at: "2008-12-29 09:33:04", updated_at: "2008-12-29 09:33:04">]

最开始可能觉得语法看起来怪怪的,但当你遇到需要使用链式调用时,它绝对是你的好帮手。


转自:http://railscasts.com/episodes/6-shortcut-blocks-with-symbol-to-proc?language=zh&view=asciicast

你可能感兴趣的:(RailsCasts6 Shortcut Blocks with Symbol to_proc 将Symbol 转化为to_proc来简化block)