当块比函数(ruby)更有用时?

san*_*xus 6 ruby ruby-on-rails block proc

我有两个例子给出相同的结果.

带块:

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    some_stuff(params)
  end
end

def self.with_params(object_id, &block)
  find_object_by_id
  calculate_params_hash
  block.call(params_hash)
end
Run Code Online (Sandbox Code Playgroud)

并与方法:

def self.do_something(object_id)
  some_stuff(self.get_params(object_id))
end

def self.get_params(object_id)
  find_object_by_id
  calculate_params_hash
  params_hash
end
Run Code Online (Sandbox Code Playgroud)

第二个解决方案似乎更直接,但我在应用程序代码中找到了第一个解决方案的一些用法.我的问题是:在哪种情况下推荐第一个?每个人的利弊是什么?

Mon*_*ong 2

根据您的示例,块和函数之间的主要区别在于块在调用函数的上下文中运行。

所以如果你的例子是这样的:

def self.do_something(object_id)
  x = "boogy on"
  self.with_params(object_id) do |params|
    some_stuff(params)
    puts x
  end
end
Run Code Online (Sandbox Code Playgroud)

块内的代码可以访问块外定义的变量 x。这称为闭包。如果您只是按照第二个示例调用函数,则无法执行此操作。

关于块的另一个有趣的事情是它们可以影响外部函数的控制流。所以可以这样做:

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    if some_stuff(params)
        return
    end
  end

  # This wont get printed if some_stuff returns true.
  puts "porkleworkle"
end
Run Code Online (Sandbox Code Playgroud)

如果块内的 some_stuff 调用返回真值,则块将返回。这将从块和 dosomething 方法中返回。porkleworkle不会得到输出。

在您的示例中,您不依赖于其中任何一个,因此使用函数调用可能更干净。

然而,在很多情况下,使用块来让您利用这些东西是非常有价值的。