Ruby on rails 什么时候块比函数更有用(ruby)?
我有两个例子给出了相同的结果 带块:Ruby on rails 什么时候块比函数更有用(ruby)?,ruby-on-rails,ruby,block,proc,Ruby On Rails,Ruby,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 方法:
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
第二种解决方案似乎更简单,但我在应用程序代码中发现了第一种解决方案的一些用法。我的问题是:在哪种情况下推荐第一种?每种方法的优点和缺点是什么?当人们想要在另一段代码中运行一段代码时,通常使用块。示例:
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|
even_more_stuff(params)
end
...
如果块是相同的,或者只是从一个地方调用了(或)PARAMS.(),那么你可以考虑删除块。< /P> 总而言之:如果您想将不同的代码位(块)和数据传递到方法中,请使用块:嘿,使用参数,获取此数据(对象id),顺便说一下,在执行此代码(块)时运行此代码(块)
顺便说一句,在这两个示例中,您正在做不同的事情:使用_params()返回 在评估块之后。而get_params()只返回params_hash
根据您的示例,块和函数之间的主要区别在于块在调用函数的上下文中运行 如果你的例子是:
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调用返回真值,则块将返回。这将返回到块外和剂量测定法外。porkleworkle无法获得输出
在您的示例中,您不依赖于这两个函数,因此使用函数调用可能更干净
但是,在许多情况下,使用块来利用这些功能是非常宝贵的。块完全依赖于代码,但函数有自己的代码 所以,如果您的代码因情况而异,请使用block。
如果没有,则构建一个函数并将其用作块框。在您的示例中,我认为没有理由使用Proc对象。Proc对象的全部目的是使它们在词法环境中持久化,并将它们作为参数传递给其他函数。
some_stuff(params)
做什么,它返回什么?在ruby中是“方法”,而不是“函数”。
def self.do_something(object_id)
x = "boogy on"
self.with_params(object_id) do |params|
some_stuff(params)
puts x
end
end
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