分享 写 Block 的一些小结

匿名 · 2015年06月11日 · 最后由 Shadow 回复于 2015年06月12日 · 1920 次阅读

块在实际中会有许多看了吃力的写法,例如像这样的:

class A
  def initialize(val)
    @val = val
  end
end
b = ->(*a) { @val + a[0] + a[1] + a[2] + 123 }  #
A.new(123).instance_exec(10000, 1000, 100, &b)  #=> 11346

个人小结 :

  • 块其实是作用域的游戏,把代码相对不变化的那部分写在 -> { } 里面,其它的变化的都作为 caller
  • 参数本身是种 caller, 包括数字也是 caller(越大的数 call 的次数越高),负责把当前环境的变量带走至他方
  • 块的意义在于让你的原有的代码有更强的迭代性或者演算性,使得你能最快的直达计算的本质问题

lambda 最简单的表示法 : 定义是 -> { } ,call 是 [ ]

ab = -> a {
  -> b {
    a * b
  }
}
ab[5][6] #=> 30

一些例子:

lambda 和 &block 一同工作的例子:users 表 has_many 关联 posts 表,定义对指定关联的二级表进行操作的 hasmany_parse

hasmany_parse = -> obj, hasmany_table, &block {
  obj.send(:each) do |_spus|
    _products = _spus.send(hasmany_table)
    _products.each do |_spu|
      block.call(_spu) if block.is_a?(Proc) # 把_spu传出去,作为caller的一部分
    end
  end
}
hasmany_parse.(User.all, :posts) do |spua| # spua接收来自 `block.call(_spu)` caller发来的 _spus.posts.each{|..|}的单个post对象
  spua.content = "#{Time.now}#{'你的修改'}" if spua.content =~ /符合某条件/
  spua.save!
end

其它例子:lambda 演算

参考《计算的本质》的 第六章 : 主要写了如何用纯的 lambda 来实现 if,map, false/true 还有数字等,用 lambda 直达计算本质的问题

前排撑场👍

:thumbsup: 不错呀

占个排位,嘿嘿

需要 登录 后方可回复, 如果你还没有账号请 注册新账号