我在两种不同的方法中有两个循环,看起来非常相似。我想在Proc.new
此作品
def matches_base?
proc_exec = Proc.new do |subclass, breakpoint|
# next and return are meant to act inside the loop and quit it if needed
response = process_match(subclass)
next if response == :continue
return true if response == false
return response
end
subclasses(BASE_NAMESPACE).each do |subclass|
proc_exec.call(subclass)
end
false
end
这里显而易见的问题是proc_exec
是在方法本身内部定义的,但我想在另一种方法中使用它
def matches_breakpoints?
breakpoints.fetch.each do |breakpoint|
# I want to include the proc_exec here too
end
false
end
所以我只是尝试在类级别提取它
这不起作用
def proc_exec
Proc.new do |subclass, breakpoint|
response = process_match(subclass)
next if response == :continue
return true if response == false
return response
end
end
def matches_base?
subclasses(BASE_NAMESPACE).each do |subclass|
proc_exec.call(subclass)
end
false
end
然后我可以在两个实例方法中调用proc_exec.call
。目前它抛出
LocalJumpError:
unexpected return
我尝试了很多技巧,例如instance_eval
或instance_exec
但没有成功。我现在没有解决方案了。
易于执行,简化我想要的示例。
class MyLoops
def proc_exec
Proc.new do |num|
next if num == 1
# we want this `return` to act in the method context
# as it would do if I defined it inside a method directly
return if num == 4
puts "Current number : #{num}"
end
end
def method_a
[0,1,2].each do |num|
proc_exec.call(num)
end
false
end
def method_b
[3,4,5].each do |num|
proc_exec.call(num)
end
end
# this `false` below should never be reached ; that's the trick
false
end
loops = MyLoops.new
loops.method_a
loops.method_b
答案 0 :(得分:1)
你不能吃蛋糕也不能吃。如果你希望proc中的return
中止该方法,它必须在方法的词法范围*中(这是另一种说法“它必须在同一方法中定义”)。
另一种方法是让proc / lambda返回一个“stop”值,调用者将使用该值来中止其执行。
(遗憾的是,你对instance_eval / instance_exec的实验误导了。这些方法只改变当前的self
。这个问题与当前的self
无关,而是当前的词法范围,其中return
1}}被执行。)
*您收到的错误,原因是return
尝试从不再运行的方法(proc_exec
)返回。