以下是代码:
params[:controller_id].select(&check_if_controller_exists)
params[:controller_id].select(&check_controller_permissions)
这很有效。我有一个数组,我正在将Proc转换成块。
我不知道该怎么做才能将它们结合起来 - 有些人可能会说这更适合代码审查,但在我看来,我有一个关于如何编写代码的问题。
是否可以在不修改单个过程的情况下组合上述内容?或者我应该只是组合成一个Super Proc而不是两个不同的块?
要求提供更多信息:
def check_if_controller_exists # in case they pass an array of controllers
Proc.new { |c| raise CanCan::AccessDenied.new("One or more of the specified controllers does not exist for this site") unless Controller.find_by_id(c) }
end
def check_controller_permissions # in case they pass an array of controllers
Proc.new { |c| raise CanCan::AccessDenied unless can? :read, Controller.find_by_id(c) }
end
与大多数编程一样,这个结构是从移动其中一个被复制的异常,然后移动另一个,然后看到我有两个基本相同,并希望将它们合并为一个调用而演变而来的,但由于它们已经被渲染为Procs,我偶然发现了如何合并Procs。
这在技术上是这篇文章的目标 - 学习如何合并几个Procs。
显然,对于这两件事,我不需要多次点击数据库。
答案 0 :(得分:1)
或者您可以避免Symbol#to_proc
转换并使用
params[:controller_id].select do |p|
p.check_if_contoller_exists && p.check_controller_permissions
end
提供相同的功能。 Symbol#to_proc
已被证明更快,但我不确定它是否适用于多次迭代,也许我会对它进行基准测试。
好的,即使在背靠背通话Symbol#to_proc
更快。
require 'benchmark'
a = (1..500).to_a
num_times = 1000
proc1 = proc {|a| a.to_s.is_a?(String)}
proc2 = proc {|a| a.to_s.to_i == a}
Benchmark.bm do |x|
x.report('Symbol#to_proc') { num_times.times{ a.select(&proc1).select(&proc2) } }
x.report('block') { num_times.times{ a.select{ |e| proc1.call(e) && proc2.call(e) } } }
end
#=> user system total real
Symbol#to_proc 0.343000 0.000000 0.343000 ( 0.343475)
block 0.453000 0.000000 0.453000 ( 0.445722)
答案 1 :(得分:0)
如果通过"结合"你的意思是得到&&
结果的结果,你可以:
result = params[:controller_id].select(&check_if_controller_exists)
.select(&check_controller_permissions)
它将在枚举中旋转两次,根据您的情况,这可能是也可能不是问题。
答案 2 :(得分:0)
如果我们只是代码审核你,我的第一个建议是两个写一个方法同时检查两个条件。这样你只需要迭代你的params Hash一次。
result = params[:controller_id].select(&:check_controller_presence_and_permissions)
private
def check_controller_presence_and_permissions
check_if_controller_exists && check_controller_permissions
end
尽管如此,如果不了解check_if_controller_exists
或check_controller_permissions
的实施情况,我很难提供好的建议。如果您可以编辑您的问题并包含更多代码,我们可以帮助您重构此问题。