何时使用块

Mon*_*ong 23 ruby

我喜欢Ruby块!他们背后的想法非常简洁.

我刚刚回顾了过去一周左右的代码,这基本上是我写过的每一个ruby函数,我注意到它们中没有一个返回值!我总是使用一个块来传回数据,而不是返回值!

我甚至发现自己正在考虑编写一个小的状态类,这将允许我编写如下代码:

something.do_stuff do |status|
  status.success do 
    # successful code
  end

  status.fail do
    # fail code
    puts status.error_message
  end
end
Run Code Online (Sandbox Code Playgroud)

我是否过多使用积木?是否有时间使用块和时间来使用返回值?

有什么问题需要注意吗?我有多大时间使用积木来咬我吗?

klo*_*ner 16

整个事情将更具可读性:

if something.do_stuff
  #successful code
else
  #unsuccessful code
end
Run Code Online (Sandbox Code Playgroud)

或者使用共同的轨道成语:

if @user.save
  render :action=>:show
else
   @user.errors.each{|attr,msg| logger.info "#{attr} - #{msg}" }
   render :action=>:edit
end
Run Code Online (Sandbox Code Playgroud)

恕我直言,避免返回布尔值是过度使用代码块.

如果,块是有道理的...

它允许代码使用资源而无需关闭该资源

 open("fname") do |f|
  # do stuff with the file
 end #don't have to worry about closing the file
Run Code Online (Sandbox Code Playgroud)

调用代码必须对结果进行非平凡的计算

在这种情况下,您可以避免将返回值添加到调用范围.对于多个返回值,这通常也是有意义的.

something.do_stuff do |res1, res2|
   if res1.foo? and res2.bar?
      foo(res1)
   elsif res2.bar?
      bar(res2)
   end
 end #didn't add res1/res2 to the calling scope
Run Code Online (Sandbox Code Playgroud)

必须在收益之前和之后调用代码

你在一些铁路助手中看到了这一点:

 <% content_tag :div do  %>
     <%= content_tag :span "span content" %>
  <% end -%>

当然,迭代器是一个很好的用例,因为它们(被ruby-ists认为)比for循环或列表推导更漂亮.

当然不是一个详尽的列表,但我建议你不要只使用块,因为你可以.

  • 我不喜欢`if do_something_with_side_effects_and_possibly_long_delays`成语.基于块的回调很好,因为它将基于副作用的方法与基于计算的方法分开.随着并行性变得更大,它也将变得更加有用 - CPS版本允许`do_stuff`异步执行,并且在知道它是否成功之后仍然有成功失败逻辑被调用. (2认同)

Chu*_*uck 13

这就是函数式编程人们所说的"延续传递风格".这是一种有效的技术,尽管在某些情况下,它会使事情复杂化而不是它的价值.重新查看一些你正在使用它的地方可能是值得的,看看你的代码是否就是这种情况.但它没有任何内在错误.


Mat*_*chu 5

我喜欢这种风格.它实际上非常类似于Ruby,通常你会看到项目重组他们的代码以使用这种格式而不是可读性较低的东西.

返回值在返回值有意义的地方是有意义的.如果您有Article对象,则需要article.title返回标题.但对于这个回调的特殊例子,它是一流的风格,你知道如何使用它们是好的.我怀疑Ruby的许多新手永远不知道如何做得好.