I'm learning Ruby (2.0) and this just surprised me:
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
The slice!
method is supposed to mutate the string. Other mutator methods behave in the same way. My questions: why is this not throwing an error, which is what I expect when a function can't do what it says it will do? Is this documented somewhere? Is there a rationale?
Update
So, I see that $&
is not acting like a global variable. Each reference to it gives a new object, as if it's really a no-arg function:
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
So... my question becomes: is this simply "magic" from the interpreter, or is $&
actually a no-arg function just as I could define in Ruby using def ... end
? And, how could I tell the difference? In Python I could refer to a function foo
by just using it's name:
>>> foo
<function foo at 0x10d3117d0>
Is there way to do this in Ruby? I could then look at what $& "really" is (if it's not magic).