在方法定义中使用 $1、$2 等全局变量 [英] Using $1, $2, etc. global variables inside method definition

查看:38
本文介绍了在方法定义中使用 $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 are the outputs of these two pieces of code different? Is there a way to pass a block to gsub from outside of the method definition so that the variables $1, $2 would be evaluated in the same way as if the block was given inside the method definition?

推荐答案

为什么输出不同?

Why the output is different?

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

A proc in ruby has lexical scope. This means that when it finds a variable that is not defined, it is resolved within the context the proc was defined, not called. This explains the behavior of your code.

您可以看到块是在正则表达式之前定义的,这可能会引起混淆.这个问题涉及一个神奇的 ruby​​ 变量,它的工作原理与其他变量完全不同.引用@JörgWMittag

You can see the block is defined before the regexp, and this can cause confusion. The problem involves a magic ruby variable, and it works quite differently than other variables. Citing @JörgWMittag

这很简单,真的:$SAFE 行为不像您对全局变量所期望的那样的原因是因为它不是全局变量.这是一只神奇的独角兽thingamajiggy.

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.

Ruby 中有不少神奇的独角兽 thingamajiggies,但遗憾的是它们没有很好的文档记录(实际上根本没有文档记录),因为替代 Ruby 实现的开发人员发现了困难的方法.这些 thingamajiggies 的行为都不同且(似乎)不一致,而且它们几乎唯一的两个共同点是它们看起来像全局变量,但行为却不像它们.

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,这是 ruby​​ 的规范由鲁比努斯的人.有一个不错的黑客攻击,但要为痛苦做好准备.

If you are really up to find exactly how the $1 and $2 variables work, I assume the only "documentation" you will find is rubyspec, that is a spec for ruby done the hard way by the Rubinus folks. Have a nice hacking, but be prepared for the pain.

有没有办法以正确的方式设置 $1、$2 变量,将块从另一个上下文传递给 gsub?

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

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

You can achieve what you want with this following modification (but I bet you already know that)

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

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

I'm not aware of a way to change the scope of a proc on the fly. But would you really want to do this?

这篇关于在方法定义中使用 $1、$2 等全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆