Modifying a variable of type Fixnum passed to a method
I had a need to pass in a variable of Fixnum type to a method and use the method to update its value. This wasn’t quite as straightforward as I had hoped.
The first question I needed to answer was how arguments were passed into methods – call by reference or call by value?
I found a lot of discussion about this in post such as void foo(int &x) -> Ruby? Passing integers by reference? and Are arguments passed to methods by reference or value?
My takeaway was that variables are passed by value, but that those variables are references to objects. With an object such as an Array or Hash, you can modify elements of the object using the passed (immutable) reference. The problem with a Fixnum, as pointed out in the post ruby and references. Working with fixnums, is that a Fixnum object lacks any methods that allow you to mutate the value.
Using a binding to solve the problem
I found the solution to my problem in the post ‘pass parameter by reference’ in Ruby?
I was working on a Rails project and needed to parse some dates, obtaining the times in seconds since the Epoch (January 1, 1970).
I was using code such as in the following snippet using examples from the documentation for Class: DateTime
date_time = DateTime.strptime("01-01-1930", '%m-%d-%Y')
secs = date_time.strftime('%s')
This worked fine in ruby 1.9.3p392 which I was using on a production server, returning the time in seconds as -1262304000
Using an older version of Ruby on my development machine, I was getting a positive number. After some searches I found that a bug had been found and submitted with the title “DateTime#strftime(“%s”) overflow on 32-bit platform”. The fix was made in revision r36265.
Latest ruby 1.9.3 release has inconsistent file revision
I downloaded Ruby 1.9.3-p448 which corresponds to revision 41675. All well and good?
Not quite – I was still seeing the same issue with older dates before 12/24/1935.
After some digging, I discovered that the file ext/date/date_core.c in this download does not match what should be in revision 41675. After a lot of searching, I was unable to find an exact match for this file in its revision history, but the closest revision to what was included in the download seemed to be 35002.
Ruby Bug filed on 1.9.3 release. Ruby 2.0 has the proper fix.
I filed bug 8580 to report the issue. I checked the latest Ruby 2.0 release (Ruby 2.0.0-p247) and found that the fix made in r36265 was present in date_core.c. I’ve successfully switched to using 2.0.0-p247 and now my code is happy again 🙂