gpt4 book ai didi

ruby - 在方法定义中使用 $1、$2 等全局变量

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

给定以下两段代码:

def hello(z)
"hello".gsub(/(o)/, &z)
end
z = proc {|m| p $1}
hello(z)
# prints: nil

def hello
z = proc {|m| p $1}
"hello".gsub(/(o)/, &z)
end
hello
# prints: "o"

为什么这两段代码的输出不同?有没有一种方法可以从方法定义外部将 block 传递给 gsub,以便变量 $1$2 将在相同的情况下进行评估好像 block 是在方法定义中给出的?

最佳答案

Why the output is different?

ruby 中的 proc 具有词法作用域。这意味着当它找到一个 undefined variable 时,它会在过程被定义的上下文中解析,而不是调用。这解释了您的代码的行为。

您可以看到 block 是在正则表达式之前定义的,这可能会造成混淆。该问题涉及一个神奇的 ruby​​ 变量,它的工作方式与其他变量完全不同。 Citing @JörgWMittag

It's rather simple, really: the reason why $SAFE doesn't behave like you would expect from a global variable is because it isn't a global variable. It's a magic unicorn thingamajiggy.

There are quite a few of those magic unicorn thingamajiggies in Ruby, and they are unfortunately not very well documented (not at all documented, in fact), as the developers of the alternative Ruby implementations found out the hard way. These thingamajiggies all behave differently and (seemingly) inconsistently, and pretty much the only two things they have in common is that they look like global variables but don't behave like them.

Some have local scope. Some have thread-local scope. Some magically change without anyone ever assigning to them. Some have magic meaning for the interpreter and change how the language behaves. Some have other weird semantics attached to them.

如果您真的想知道 $1$2 变量是如何工作的,我假设您会找到的唯一“文档”是 rubyspec ,这是 Rubinus 人员费力完成的 ruby​​ 规范。祝你玩得愉快,但要做好承受痛苦的准备。


Is there a way to pass a block to gsub from another context with $1, $2 variables setup the right way?

你可以通过下面的修改实现你想要的(但我打赌你已经知道了)

require 'pp'
def hello(z)
#z = proc {|m| pp $1}
"hello".gsub(/(o)/, &z)
end
z = proc {|m| pp m}
hello(z)

我不知道有什么方法可以即时更改 proc 的范围。但你真的想这样做吗?

关于ruby - 在方法定义中使用 $1、$2 等全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18550434/

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