瞎扯淡 关于 block (一)

riskgod · 2015年12月09日 · 最后由 piecehealth 回复于 2015年12月10日 · 2042 次阅读

应该说在不改变返回值的前提下,方法的作者给方法的使用者抛出这个方法中的一些字段的值,具体的字段在 yield 后定义。 这里 test(your_proc) 抛出 user_ids,后面 block 中 do|users_ids|来获取 users_ids, 方法 test(your_proc) 的最后结果 true 不变。

def test(your_proc)
  user_ids = User.where("name like '%z%'").pluck(:id)
  User.where(id: user_ids).find_each{|x| x.update_columns(name: "name_#{x.id}")}
  your_proc.call()
  yield :x, user_ids if block_given?
  yield :y, [] if block_given?
  puts 'done'
  true
end

test(Proc.new{ puts 'this is proc' })
test(lambda{ puts 'this is lambda' })


result = test(->{ puts 'this is ->' }) do |operate, user_ids|
  if operate == :x
    Rails.logger.debug "user_ids: #{user_ids}"
  end
  if operate == :y
  end
  puts 'this is block'
end

if result
  302
else
  500
end

这样耦合太紧了吧,我要是调用者我会疯的

#1 楼 @piecehealth 只是个例子说明功能网上好多都说的不清楚

实现上面的功能我会这么写

def test(your_proc, behaviors = {})
  user_ids = User.where("name like '%z%'").pluck(:id)
  User.where(id: user_ids).find_each{|x| x.update_columns(name: "name_#{x.id}")}
  your_proc.call()
  behaviors.each do |operate, behavior|
    case operate
    when :x
      behavior.call user_ids
    when :y
      behavior.call []
    else
      # default behavior
    end
  end
  puts 'done'
  true
end

# 调用
result = test(
  ->{ puts 'this is ->' }, 
  {
    x: lambda {|user_ids| Rails.logger.debug "user_ids: #{user_ids}"}, 
    y: lambda {}
  }
)

方法作者只需要提供支持的 behaviors 说明就行了,如果你那种实现,你怎么给调用者写文档……

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