Rob*_*b N 6 ruby pseudo-globals
我正在学习Ruby(2.0),这让我感到惊讶:
s = "1234"
s =~ /\d+/
$& ==> "1234" # as expected, $& contains the matched string
$&.slice!(-2..-1) # should mutate string
$& ==> "1234" # what?
s.slice(-2..-1)
s ==> "12" # as expected
Run Code Online (Sandbox Code Playgroud)
该slice!方法应该改变字符串.其他mutator方法的行为方式相同.我的问题:为什么这不会引发错误,这是我所期望的,当一个函数无法完成它所说的那样的事情时?这是在某处记录的吗?有理由吗?
更新
所以,我认为这$&不是一个全局变量.每次引用都会给出一个新对象,就好像它实际上是一个无参数函数:
irb> $foo = "1234"
=> "1234"
irb> $foo.object_id
=> 70205012205980
irb> $foo.object_id
=> 70205012205980 # the same
irb> $&.object_id
=> 70205003531300
irb> $&.object_id
=> 70205011619040 # different object
Run Code Online (Sandbox Code Playgroud)
所以......我的问题变成了:这只是解释器中的"魔术",或者$&实际上是一个无法使用的函数,正如我在Ruby中定义的那样def ... end?而且,我怎么能分辨出来呢?在Python中,我可以foo通过使用它的名称来引用一个函数:
>>> foo
<function foo at 0x10d3117d0>
Run Code Online (Sandbox Code Playgroud)
有没有办法在Ruby中做到这一点?然后我可以看看$&"真的"是什么(如果它不是魔术).
Ruby C API包括钩子和虚拟变量.来自README.EXT:
您可以定义钩子变量.访问函数(getter和setter)在访问钩子变量时被调用.
Run Code Online (Sandbox Code Playgroud)void rb_define_hooked_variable(const char *name, VALUE *var, VALUE (*getter)(), void (*setter)())如果你需要提供setter或getter,只需为你不需要的钩子提供0.如果两个钩子都是0,则rb_define_hooked_variable()的工作方式与rb_define_variable()相同.
getter和setter函数的原型如下:
Run Code Online (Sandbox Code Playgroud)VALUE (*getter)(ID id, VALUE *var); void (*setter)(VALUE val, ID id, VALUE *var);您还可以定义没有相应C变量的Ruby全局变量.变量的值只能通过钩子设置/获取.
Run Code Online (Sandbox Code Playgroud)void rb_define_virtual_variable(const char *name, VALUE (*getter)(), void (*setter)())getter和setter函数的原型如下:
Run Code Online (Sandbox Code Playgroud)VALUE (*getter)(ID id); void (*setter)(VALUE val, ID id);
$&在虚拟变量的一个例子,它被定义在re.c,相应的吸气剂是last_match_getter并没有assocoated设定器.
所以$&就是,从某种意义上说,一个无参数的功能,只是它是用C实现你不能(据我所知)在纯Ruby这样定义自己的虚拟全局(你可以,如果您创建拥有C扩展名).
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |