我在 Ruby2.7 中有一些看起來像這樣的代碼
#assume data is either an ActiveRecord::Relation or a plain array. If it's an ActiveRecord, use :find_each instead, but set batch_size => 5000
if data.respond_to?(:find_each)
method_to_call = :find_each
arguments_to_send = [{:batch_size => 5_000}]
else
method_to_call = :each
arguments_to_send = []
end
data.__send__(method_to_call, *arguments_to_send) do |item|
#do stuff in each iteration
end
然而,這段代碼在 Ruby3 中不再有效,因為關鍵字引數不能像那樣轉發。
如何在 Ruby3 中使用元編程來完成同樣的任務?
uj5u.com熱心網友回復:
這是由于 Ruby 3.0 中位置引數和關鍵字引數的分離(參見https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments- in-ruby-3-0/ )
這是您的代碼的 Ruby 3 版本的樣子:
if data.respond_to?(:find_each)
method_to_call = :find_each
arguments_to_send = []
keyword_arguments_to_send = {:batch_size => 5_000}
else
method_to_call = :each
arguments_to_send = []
keyword_arguments_to_send = {}
end
data.__send__(method_to_call, *arguments_to_send, **keyword_arguments_to_send) do |item|
# do stuff in each iteration
end
上面的代碼是處理常規引數和關鍵字引數的更通用的版本。在你的情況下,find_each只接受關鍵字引數(至少在 Rails 7 中——我沒有檢查早期版本)并且each不接受任何引數,所以如果你愿意,你可以擺脫這個:
if data.respond_to?(:find_each)
method_to_call = :find_each
keyword_arguments_to_send = {:batch_size => 5_000}
else
method_to_call = :each
keyword_arguments_to_send = {}
end
data.__send__(method_to_call, **keyword_arguments_to_send) do |item|
# do stuff in each iteration
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/529719.html
標籤:轨道上的红宝石红宝石
