qiezi的学习园地

AS/C/C++/D/Java/JS/Python/Ruby

  C++博客 :: 首页 :: 新随笔 ::  ::  :: 管理 ::
这是ActiveSupport扩展的一个方法。原代码如下:

class Symbol
  def to_proc
    Proc.new { |*args| args.shift.__send__(self, *args) }
  end
end

它扩展出这种用法:

(1..5).map(&:to_s)

map原本是要接受一个block参数,普通的用法是:

(1..5).map{|e| e.to_s}

或者:

proc = Proc.new{|e| e.to_s}
(1..5).map(&proc)

上面这个(1..5).map(&:to_s)用法可以拆成3步来解释:
sym = :to_s
proc = Proc.new{|*args| args.shift.send(sym, *args)}
(1..5).map(&proc)

有个疑问,经过yanping.jia解释,map(&:to_s)因为出现了&符号,所以:to_s会执行to_proc方法,然后与&一起合成&proc交给map处理。虽然说得通,不过我总觉得这个解释中,&这个符号做了2次工作,是否合理?

这种用法原本是Ruby Extensions Project发明的,在RoR中作了点修改。原来的版本是:

class Symbol
    def to_proc
      proc { |obj, *args| obj.send(self, *args) }
    end
end

它使用2个参数来分出一个参数,而RoR版本则使用shift分出来。


刚才又想了一下,yanping.jia的解释应该是合理的,解释器看到&:id时,先会判断是否是一个方法调用,如果是则需要把:id转成一个proc。否则就是语法错误了。
posted on 2006-07-11 15:40 qiezi 阅读(288) 评论(0)  编辑 收藏 引用 所属分类: Ruby