Ruby 一个区块如何检测到它在另一个区块内?
这是我的代码:Ruby 一个区块如何检测到它在另一个区块内?,ruby,Ruby,这是我的代码: def block puts "from block" yield end block do puts "from command line" block do end end 以下是输出: from block from command line from block 我想知道第二个块是如何检测到它在另一个块(相同方法)内的 因此,输出将改为: from block 1 from command line from block 2 这可能吗?因为我
def block
puts "from block"
yield
end
block do
puts "from command line"
block do
end
end
以下是输出:
from block
from command line
from block
我想知道第二个块是如何检测到它在另一个块(相同方法)内的
因此,输出将改为:
from block 1
from command line
from block 2
这可能吗?因为我希望嵌套块知道这一点,并运行一些额外的代码
谢谢 您可以使用实例变量跟踪块级别,在输入块时递增,在离开块时递减:
def block
@block_level ||= 0
@block_level += 1
puts "from block #@block_level"
yield
@block_level -= 1
end
这个答案主要是为了好玩,我不建议你使用它 Ruby允许您以回溯的形式检查调用堆栈,但仅当引发异常时。因此,让我们提出一个例外,然后伸出我们的手臂,在它传递给其他人之前抓住它,然后:回溯是我们的 然后,您所需要做的就是在回溯(数组)中搜索对名为“block”的方法的任何方法调用,并对它们进行计数
class InspectBacktrace < Exception
end
def block
raise InspectBacktrace
rescue InspectBacktrace => e
level = e.backtrace.count { |x| x =~ /in `block'/ }
puts "from block #{level}"
yield
end
block do
puts "from command line"
block do
puts "from command line"
block do
puts "from command line"
end
end
end
Edit:我后来遇到了Kernel#caller
方法,它只提供当前的执行堆栈,没有任何麻烦。因此,只要在同一个文件中没有两个名为“block”的方法相互调用,以下代码可能是可以接受的:
def block
level = caller.count { |x| x =~ /^#{ Regexp.escape(__FILE__) }:\d+:in `block'$/ } + 1
puts "from block #{level}"
yield
end
yjerem说,只要使用
确保避免异常问题,它听起来像一个全局变量,而不是实例变量
def block
begin
$block_level ||= 0
$block_level += 1
puts "from block #{$block_level}"
yield
ensure
$block_level -= 1
end
end
有没有更好的方法来构造代码,这样就没有必要了?我喜欢你的创造性=)
def block
begin
$block_level ||= 0
$block_level += 1
puts "from block #{$block_level}"
yield
ensure
$block_level -= 1
end
end