Why does 6.times.map work in ruby 1.8.7 but not 1.8.6
In 1.8.7+ iterator methods like times
return an enumerator if they are called without a block. In 1.8.6 you have to do
require 'enumerator'
6.enum_for(:times).map {...}
Or for this specific use case you could simply do (0...6).map {...}
Upgrade ruby projects from 1.8.6 to 1.8.7
It should be mostly seamless, since it was mostly compatible changes to the api.
Still, check out the list of incompatibilities
If you start using the new methods offered by 1.8.7 (or newer!) but would like to remain compatible with 1.8.6, checkout my backports gem.
How to update to Ruby 1.8.7
The simplest answer is "don't". Ruby 1.8.7 was an attempt to create bridging release between 1.8 and 1.9, and the consensus of the community was that this was not necessary, so there was little support for it before 1.9 was finalized. The general recommendation is either to stick with 1.8 (the version is supplied with OS X 10.5), or use Ruby 1.9.
MacPorts has packages for Ruby 1.8.7 and Ruby 1.9, so that is probably the easiest way to get newer versions of Ruby without any risk of modifying OS X itself.
UPDATE: As ajhit406 noted, RVM is now the best option, rather than MacPorts.
Why doesn't each_slice work?
In ruby 1.8.6 you have to require 'enumerator'
(which is part of stdlib and has been merged into core in 1.8.7+) before using each_slice.
Sadly the ruby-doc lists methods that are added to core classes by stdlib without mentioning where the methods are from.
RVM doesn't work for 1.9.1 but works for 1.8.6 and 1.8.7
SOLUTION!!!!
I was able to get rvm to function by doing 3 things:
- Navigate to
usr/local/lib/
sudo rm -rf libsqlite3.dylib
(Caution this could be a really bad thing to do; but it worked to solve this problem)sudo port upgrade --force sqlite3 +universal
and got sqlite3 and all its dependencies to build x86_64/i386 universal libraries
How to map/collect with index in Ruby?
If you're using ruby 1.8.7 or 1.9, you can use the fact that iterator methods like each_with_index
, when called without a block, return an Enumerator
object, which you can call Enumerable
methods like map
on. So you can do:
arr.each_with_index.map { |x,i| [x, i+2] }
In 1.8.6 you can do:
require 'enumerator'
arr.enum_for(:each_with_index).map { |x,i| [x, i+2] }
Is there a reason Ruby 1.8.7 is still so widely used?
My understanding was that the 1.8.7 to 1.9.x transition broke rails and thus broke a lot of web sites.
As a result of this, many of those web sites stayed with Ruby 1.8.7 and (I'm less sure about this) Rails 3.x
This traumatic transition has been referenced by Matz and many others at various Ruby conferences over the years. It is used to underline the commitment of the Ruby development team to avoid ever doing that again.
Sorry, I don't have a reference for any of these videos.
Exponentiation in Ruby 1.8.7 Returns Wrong Answers
When calculating, Ruby is supposed to convert from Fixnum to Bignum when the numbers go beyond the bounds of Fixnum. For older versions of Ruby, this fails with the ** operator:
$ ruby --version
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
$ irb
>> 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808
>> 2 ** 64
=> 0
Where it fails depends on the word size of the architecture. 64-bit words on the iMac in this example. Internally, the Fixnum is cast to a long integer, and the operator is handled with longs. The longs overflow at word size, and Ruby is ungracefully handling this by returning 0.
Note that the * operator works correctly (converting to Bignum), where the ** fails:
>> a = 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808
>> a * 2
=> 9223372036854775808
>> 2 ** 64
=> 0
>> a * 4
=> 18446744073709551616
Moving to a newer version of Ruby will fix this. If you can't move to a newer version, then avoid using Fixnum and ** with large powers.
How to run code with enumerator in Ruby 1.8?
As mentioned in this answer to a different question, in Ruby 1.8.6, you can do
require 'enumerator'
6.enum_for(:times).map {...}
But I don't know if it'll allow you to do my_enum.next
.
I think the documentation is at http://ruby-doc.org/stdlib/libdoc/enumerator/rdoc/ , but it seems to be down right now.
Related Topics
Ruby Regex to Capture Everything Between Two Strings (Inclusive)
Cancan Abilities in Separate File
Writing Ruby Console Output to Text File
How to Figure Out Which Step I'Ve Just Executed in Cucumber's Afterstep Hook
How to Parse Xml Nodes to CSV with Ruby and Nokogiri
Differencebetween Unicorn and Unicorn_Rails
+= Operator Appears to Modify Frozen String
Is Ruby Any Good for Gui Development
Capybara Trouble Filling in Js Modal
Show Markers on Google Maps Dynamically -Rails 3.2
Validate That String Contains Only Allowed Characters in Ruby
Parsing Large Xml with Nokogiri
How to Create an Operator for Deep Copy/Cloning of Objects in Ruby
Does Anyone Have Parsing Rules for the Notepad++ Function List Plugin for Ruby and Rake
How to Simplify or Clean Up This Anagram Method