我有两个例子可以得到相同的结果。
使用块:
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
并使用方法:
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
第二个解决方案似乎更直接,但我在应用程序代码中找到了第一个解决方案的一些用法。我的问题是:在哪种情况下推荐第一个?每个人的利弊是什么?
答案 0 :(得分:3)
通常人们在想要在另一段代码中运行一段代码时会使用块。例子:
DB.with_shard_for_user(user_id) do |db|
# perform operations on a user's shard
end # shard is reverted back to original value
File.new(filename) do |file|
# work with file
end # file is closed automatically
User.transaction do
# run some operations as a single transaction
end
这些块在它们的词汇上下文中被关闭(它们从块的声明位置捕获变量,并在调用块时将它们传递到该位置)。
接受块的方法的示意结构。
def transaction
open_transaction # pre- part
yield if block_given? # run provided code
commit_transaction # post- part
rescue
rollback_transaction # handle problems
end
在你的第一个例子中,使用一个块可能是不合理的(恕我直言)。没有明显原因太复杂了。
答案 1 :(得分:2)
根据您的示例,块和函数之间的主要区别在于块在调用函数的上下文中运行。
所以如果你的例子是:
def self.do_something(object_id)
x = "boogy on"
self.with_params(object_id) do |params|
some_stuff(params)
puts x
end
end
块中的代码可以访问在块外部定义的变量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
如果块中的some_stuff调用返回true值,则块将返回。这将退出块并退出dosomething方法。 porkleworkle 无法获得输出。
在您的示例中,您不依赖于其中任何一个,因此使用函数调用可能更清晰。
然而,在许多情况下,使用块来让你利用这些东西是非常宝贵的。
答案 2 :(得分:1)
当您调用with_params()时,您不仅要发送数据,还要提供一些代码来运行。查看是否将不同的块发送到with_params()调用:
...
self.with_params(object_id) do |params|
some_other_stuff()
some_stuff(params)
end
...
以及其他地方:
...
self.with_params(object_id) do |params|
even_more_stuff(params)
end
...
如果块都是相同的,或者只是从一个地方调用with_params(),那么你可以考虑删除这些块。
总结一下:如果你想将不同的代码(块)以及数据传递给方法,请使用块:hey with_params,获取此数据(object_id),顺便说一句,运行此代码(块)当你在它的时候。
顺便说一下,你在两个例子中做了不同的事情:with_params()返回
some_stuff(params_hash)
评估块后。并且get_params()只返回
params_hash
答案 3 :(得分:1)
一个块完全依赖于你的代码,但一个函数有自己的代码。
因此,如果您的代码因情况而异,请使用block。 如果没有,请构建一个函数并将其用作块框。