微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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)

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

原文地址:https://www.jb51.cc/ruby/269646.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐