当块比功能(Ruby)更有用时?
-
16-12-2019 - |
题
我有两个给出相同结果的例子。
带块:
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
.
第二种解决方案似乎更加直接,但我发现了在我们的应用程序代码中的第一个用法。我的问题是:建议第一个情况?每个人的利弊是什么?
解决方案
根据您的示例的块和函数之间的主要区别在于块在调用函数的上下文中运行。
所以如果你的例子是:
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
.
如果块内的某些呼叫呼叫返回真值,则块将返回。这将退出块和流出剂量方法。 porkleworkle 不会得到输出。
在您的示例中,您不依赖于其中中的任何一个,所以使用函数调用可能会更清晰。
但是,在许多情况下,使用块允许您利用这些东西是宝贵的。其他提示
通常人们在他们想要在另一件代码内运行一块代码时使用块。示例:
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
.
在您的第一个示例中,使用块可能不合理(imho)。对于没有明显的原因来说太复杂了。
当您调用_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
...
.
如果块是相同的,或者_params()刚从一个地方调用,那么您可能会考虑消除块。
总结:如果要传递到方法不同位的代码(块)以及数据:嘿with_params,请携带此数据(object_id),然后运行此代码(块)在你的时候。
btw您在两个示例中正在执行不同的事物:with_params()返回
some_stuff(params_hash)
.
评估块后。和get_params()只是返回
params_hash
. 一块完全依赖于代码,但函数有自己的代码。
所以,如果您的代码通过情况变化情况,请使用块。 如果没有,构建函数并将其用作块框。