gpt4 book ai didi

ruby: block 可以影响方法中的局部变量吗?

转载 作者:数据小太阳 更新时间:2023-10-29 06:43:54 24 4
gpt4 key购买 nike

我只是在学习 ruby​​ 并试图理解 block 中执行的代码的范围。例如,我希望能够创建一个 block 来影响它附加到的方法,如下所示:

def test(&block)
block.call() if block_given?
puts "in test, foo is #{foo}"
puts "in test, bar is #{bar}"
end

test() {
foo="this is foo"
bar="this is bar"
}

在这种情况下,我根本不想修改 block ——我希望能够使用简单的变量引用而不使用参数来编写它。 只有修改上面例子中的'test'方法,才能访问block中定义的变量吗?

同样,目标是不修改 block ,但能够在 block 执行后从“test”中访问创建的变量。

最佳答案

首先,block.call() 是通过 yield 完成的,那样您不需要 &block 参数。

一般情况下不能为所欲为,block在创建的时候就绑定(bind)了,在block内部可以看到当时定义的局部变量;做你想做的最简单的方法,这不是你通常使用 block 的方式,是这样的:

def test()
foo = yield if block_given?
puts "in test, foo is #{foo}"
end

test() {
foo="this is foo"
}

但这只是副作用,因为 foo 被 block “返回”。如果您改为这样做:

def test()
foo = yield if block_given?
puts "in test, foo is #{foo}"
end

test() {
foo="this is foo"
"ha ha, no foo for you"
}

您会注意到它做了一些不同的事情。

这里有更多的魔法:

def test(&block)
foo = eval "foo", block.binding
puts foo
block.call
foo = eval "foo", block.binding
puts foo
end

foo = "before test"
test() {
foo = "after test"
"ha ha, no foo for you"
}

那会有点工作,但是如果您删除 foo = "before test" 它会中断,因为 foo 成为 block 中的局部变量并且不存在于绑定(bind)。

总结:您不能访问 block 中的局部变量,只能访问定义 block 的局部变量和 block 的返回值。

即使这样也行不通:

def test(&block)
eval "foo = 'go fish'", block.binding
block.call
bar = eval "foo", block.binding
puts bar
end

因为绑定(bind)中的 foo 与 block 中的本地不同(我不知道这一点,谢谢)。

关于ruby: block 可以影响方法中的局部变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/422536/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com