![](/img/trans.png)
[英]In Ruby is there an alternative and more elegant way to call a method than 'case - when'?
[英]When blocks are more useful than functions (ruby)?
我有兩個例子給出相同的結果。
帶塊:
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
在您的第一個示例中,使用塊可能是不合理的(恕我直言)。 太復雜了,沒有明顯的理由。
根據您的示例,塊和函數之間的主要區別在於塊在調用函數的上下文中運行 。
所以如果你的例子如下:
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不會得到輸出。
在您的示例中,您不依賴於其中任何一個,因此使用函數調用可能更清晰。
但是,在許多情況下,使用塊來讓您利用這些東西是非常寶貴的。
當您調用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
塊完全依賴於您的代碼,但函數有自己的代碼。
因此,如果您的代碼因情況而異,請使用block。 如果沒有,請構建一個函數並將其用作塊框。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.