Ruby Integer and Fixnum unexpexted behavior - ruby

I want to use gcd function of the Integer class. Using the example from Ruby Doc as a test it fails:
irb(main):001:0> 72.gcd 168
NoMethodError: undefined method `gcd' for 72:Fixnum
from (irb):1
I have the windows one click installer ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]. On other PCs with the same version of ruby this works correctly.
Any ideas?

Try
require 'rubygems'
72.gcd 168

require 'rational'

Related

Differentiate between Module and Class

The following yields an error:
require 'test/unit'
Test::Unit.setup_argv(["tests"])
$ run_tests.rb:4: undefined method `setup_argv' for Test::Unit:Module (NoMethodError)
How can I make Ruby use the Test::Unit class instead of the Test::Unit module for the method call?
EDIT Ruby 1.8.7
The reason for the error is that setup_argv is not available in Ruby 1.8.7.
Test::Unit is always a module. There is no class.
See the 1.8.7 docs here for how to use:
http://apidock.com/ruby/v1_8_7_330/Test/Unit

"NameError: uninitialized constant User::MongoMapper" trying to MongoMapper 'Getting Started'

Here's my irb session:
irb(main):001:0> class User
irb(main):002:1> include MongoMapper::Document
irb(main):003:1> key :name, String
irb(main):004:1> key :age, Integer
irb(main):005:1> many :hobbies
irb(main):006:1> end
NameError: uninitialized constant User::MongoMapper
from (irb):2
irb(main):007:0>
which is right off of http://mongomapper.com/
I'm in windows 7, ruby 1.8.7 patchlevel 249. My gem list includes mongo, mongo_mapper, bson, and bson_ext (among others). I tried 'require'ing 'mongo_mapper' and/or 'mongo', and just got error messages about those 'require's.
I'm sure it's something simple, but as a ruby newbie, I'm stumped.
TIA
You have to
require "rubygems"
first on 1.8.7.
Ruby 1.9.2 automatically does it for you.
On 1.8.7 you can set an environment variable called "RUBYOPT" to do this for you.
See here.
Then after you have RubyGems loaded, you can load MongoMapper and everything should work.
require "mongo_mapper"

Why doesn't each_slice work?

I am trying to use the Enumerable#each_slice. It doesn't work on my computer, stating that method is not found.
I am running ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
API: http://ruby-doc.org/core/classes/Enumerable.html#M003142
Example:
(1..10).each_slice(3) {|a| p a} # I get NoMethodError: undefined method `each_slice' for 1..10:Range
What am I doing wrong?
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.
just compared 1.8.6 to 1.9 and it looks like
(1..10).respond_to? :each_slice
is true in 1.9 and false in 1.8.6. So, the doc you are using is not for 1.8.6. if you can upgrade to a newer version of Ruby easily it should give you that method on the Range.

undefined method ‘bytes’ for for String in Ruby

I am working with ruby 1.8.6 (2007-03-13 patchlevel 0) [x86_64-linux] and I get
undefined method `bytes' for #<String:0x2a95ec2268> (NoMethodError)
even though my code works on ruby 1.8.7. patchlevel 249
I saw somewhere that you need to add require "jcode" for a similar method not defined error with each_byte. I tried adding that but it still does not work. Any suggestions are very appreciated.
In Ruby 1.8.6, you can use my backports gem:
require 'backports/1.8.7/string/bytes'
Ta-da, you now have access to String#bytes.
You also have all the many other changes introduced in 1.8.7. And most of 1.9.1, and all of the upcoming 1.9.2, etc...
Ruby 1.8.6 doesn't have String#bytes. That's a 1.9 addition that was backported to 1.8.7.
You can roughly implement it yourself like this:
class String
require 'enumerator'
def bytes(&block)
return to_enum(:each_byte) unless block_given?
each_byte &block
end
end unless ''.respond_to?(:bytes)
[Note: I haven't checked whether this actually fulfills the contract of String#bytes 100%, but it is close enough for my use.]

Why does 6.times.map work in ruby 1.8.7 but not 1.8.6

The following code snippet works fine in 1.8.7 on Mac OS X, but not in 1.8.6 on Ubuntu. Why? Is there a workaround?
Works in 1.8.7:
$ ruby --version
ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0]
ltredgate15:eegl leem$ irb
>> 6.times.map {'foo'}
=> ["foo", "foo", "foo", "foo", "foo", "foo"]
>>
But not in 1.8.6:
# ruby --version
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-linux]
Ruby Enterprise Edition 20090610
# irb
irb(main):001:0> 6.times.map {'foo'}
LocalJumpError: no block given
from (irb):1:in `times'
from (irb):1
irb(main):002:0>
Why is there a difference? What's the workaround for 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 {...}
In Ruby 1.9, the library was changed so functions that did iteration would return an Enumerator object if they were called without a block. A whole host of other language features were also changed, and it was widely known that compatibility would be broken between Ruby 1.8.x and Ruby 1.9 in the interests of improving the language as a whole. Most people didn't find this too distressing.
The Ruby development team decided that Ruby 1.8.7 should be a transition release adding some of the library features that Ruby 1.9 introduced. They took a lot of criticism for the decision, and many enterprise Ruby users remained (and many still remain) running Rails on Ruby 1.8.6, because they feel the changes introduced 1.8.7 are just too large, and too risky. But nevertheless, 1.8.7 remains, and having iteration functions return Enumerators is one of the features that was incorporated.
It is this migration feature that you're seeing in 1.8.7, which is not present in 1.8.6.
sepp2k's answer gives a good workaround. There's not much for me to add on that count.
Because 1.8.6 #times yields on the given block, while 1.8.7 returns an Enumerator object you can keep around and implements Enumerable.
Ruby 1.8.7 introduces many changes. If you want to use them in Ruby 1.8.6, simply
require 'backports'
That's it. This gives you many methods of 1.9.1 and the upcoming 1.9.2 as well, although it's possible to require 'backports/1.8.7' for just the changes of 1.8.7, or even just the backports you need, e.g. require 'backports/1.8.7/integer/times'

Resources