The following script doesn’t work…
Do you have any idea of what is wrong?
Is it a ruby bug? (ruby version: ruby 1.9.1p243 (2009-07-16 revision
24175) [i386-darwin9])
require ‘time’
Time.parse(“1999-10-31 16:46:50”) # this works
class String
alias_method :old_sub!, :sub!
def sub!(*args, &block)
old_sub!(*args, &block)
end
end
Time.parse(“1999-10-31 16:46:50”) # this crashes
=>
ArgumentError: argument out of range
from /opt/local/lib/ruby1.9/1.9.1/time.rb:202:in `local’
from /opt/local/lib/ruby1.9/1.9.1/time.rb:202:in `make_time’
from /opt/local/lib/ruby1.9/1.9.1/time.rb:261:in `parse’
The following script doesn’t work…
Do you have any idea of what is wrong?
There are loads of sub! calls in date/format.rb, but I have no idea why
delegating sub! in this way would break it.
I note that the same error occurs in 1.8.6 too:
ArgumentError: argument out of range
from /usr/lib/ruby/1.8/time.rb:184:in local' from /usr/lib/ruby/1.8/time.rb:184:inmake_time’
from /usr/lib/ruby/1.8/time.rb:243:in `parse’
from (irb):19
I copied time.rb to my local directory and modified it to puts the
arguments to local. I see that it is calling
“abc”.sub!(/(.)/, “z”)
p $1 # nil
“abc”.old_sub!(/(.)/, “z”)
p $1 # “a”
When sub! calls old_sub!, the $n variables inside sub! are not set,
but the ones in old_sub! are. When the date parser hits _parse_iso (or
whichever of that family of methods it hits), there are calls to sub!
followed by usage of the $n variables, which are actually not set
because they’re two methods removed.
A more generic example:
def y(str)
/(.)/.match(str)
p $1
end
def x(str)
y(str)
p $1
end
x(“abc”)
=> “a”
nil
David
–
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com
It is not possible to make it work. I have written on this previously,
but it’s a particular ugly wart of Ruby that the $_ and $~ variables
(and related vars like $1, $&, etc) are “special”, and only certain
core class methods are able to modify them (in the caller’s scope)
while no Ruby code can. It is for this reason that you can’t alias and
wrap any of those methods without breaking them.
To be honest, Ruby would be far better off if $_ and $~ went away,
since I believe they’re overreaching by modifying the caller’s scope
without your knowledge.