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

前端之家收集整理的这篇文章主要介绍了ruby – 在方法定义中使用$1,$2等全局变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
给出以下两段代码
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"

为什么这两段代码输出不同?有没有办法从方法定义外部将块传递给gsub,以便以与在方法定义中给出块的方式相同的方式计算变量$1,$2?

解决方法

Why the output is different?

ruby中的proc具有词法范围.这意味着当它找到一个未定义的变量时,它会在上下文中解析proc被定义,而不是被调用.这解释了代码的行为.

您可以看到在regexp之前定义了块,这可能会导致混淆.这个问题涉及一个魔法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,这是rubin人员艰难地完成的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)

我不知道有办法在飞行中改变过程的范围.但你真的想这样做吗?

猜你在找的Ruby相关文章