number conversion - Fixnum / Bignum - ruby

I thought Ruby automatically converts to Bignum. I found confirmation here
However, it is not happening:
ruby 1.8.7 (358) [universal-darwin12.0]
>> 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808 #why minus - how about automatic Bignum conversion?
>> 2 ** 64
=> 0 #- how about automatic Bignum conversion?

Use a Newer Ruby Version
Ruby 1.8.7 is (in Internet terms) ancient. Use something more recent. For example:
[1] pry(main)> RUBY_VERSION
=> "2.0.0"
[2] pry(main)> 2 ** 63
=> 9223372036854775808
[3] pry(main)> 2 ** 64
=> 18446744073709551616

That is probably a bug in the old version of Ruby. Switch to a newer version, the problem is gone. Today is the release day for Ruby 2.0. Ruby 1.8 will be dead soon. On my Ruby 1.9.3, I just did 2**1000000 without any problem except that it goes on for a while, so I had to terminate it.

Most likely a bug specific to the build you're using. For example, when I do ruby -v I get:
ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-darwin12.2.1], MBARI 0x6770, Ruby Enterprise Edition 2011.03
...and in an irb session I get:
1.8.7 :006 > 2 ** 64
=> 18446744073709551616
1.8.7 :007 > (2 ** 64).class
=> Bignum
1.8.7 :008 > RUBY_VERSION
=> "1.8.7"
I also don't get this problem if I use newer versions. If you can post your output from ruby -v that would shine some light on the situation. For example Ruby REE vs. MRI vs. JRuby, etc.
Also, and this is just an opinion so take it for what it's worth, but I don't think Apple is very good about keeping their built-in version of Ruby updated, so just in case you're using the built-in version then consider moving to another build.

Related

Ruby 2.4 Enumerable#sum breaks in Rails 5.1

In Rails 5.1.4 using Ruby 2.3.5, I get this behavior:
>> [].sum
#> nil
I'd like to upgrade to Ruby 2.4, where Enumerable#sum is implemented natively. Testing this in IRB using Ruby 2.4.2, I get this result:
>> [].sum
#> 0
That's OK, and I can handle the different result. But going back to the Rails console in Rails 5.1.4 using Ruby 2.4.2, I get this:
>> [].sum
#> NoMethodError: undefined method `each' for nil:NilClass
However, in a newly created Rails 5.1.4 project, I don't get this error. What's going on here?
Looking at the source for the Active Support enumerable extensions it definitely seems like something odd is going on because you shouldn't have been getting the behaviour you described for Rails 5.1.4 using Ruby 2.3.5 i.e. you should have been getting 0 not nil there too.
Active Support's Array#sum checks if Ruby's own sum can be used by checking first.is_a?(Numeric). This will be false for an empty array so the call to super will call Enumerable#sum and both implementations of that have a default of 0.
Try [].method(:sum).source_location in the Rails console of your existing project to see if Array#sum is being overridden somewhere.
if that returns the expected line from active_support/c‌​ore_ext/enumerable.r‌​b then the next step will be to check [].method(:sum).super_method.source_location and see if a customised Enumerable#sum is the culprit.
I think that your application have some overhidden on sum method. Look the example below with 2 new applications using the 2 different versions of ruby
/testapp# ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
/testapp# rails --version
Rails 5.1.4
/testapp# rails c
irb(main):001:0> [].sum
=> 0
and the other version
/testapp# ruby --version
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux]
/testapp# rails --version
Rails 5.1.4
/testapp# rails c
irb(main):001:0> [].sum
=> 0

How do I set the language mode for Rubinius?

I'm trying to set the language mode in Rubinius, and it doesn't seem to work. I tried using the switch suggested by the Rubinius team in April 2012 in https://stackoverflow.com/a/10165964/38765
$ ruby --version
rubinius 2.0.0.n203 (1.9.3 4d75a146 2013-07-22 JI) [x86_64-apple-darwin11.4.2]
$ ruby -X18
irb(main):001:0> RUBY_VERSION
=> "1.9.3"
irb(main):002:0> exit
$ ruby -X20
irb(main):001:0> RUBY_VERSION
=> "1.9.3"
Is it possible to set language mode any more for Rubinius?
You have to enable the language modes when compiling rubinius. From the docs:
For example, to enable both 1.9 and 2.0 modes, with 1.9 the default,
use the follwing configure options:
./configure --enable-version=1.9,2.0 --default-version=1.9

Ruby concat strings with UTF-8 characters results in strange ordering

1.9.3-p194 :059 > arabic
=> "أَبْجَدِيَّة عَ"
1.9.3-p194 :065 > arabic.encoding
=> #<Encoding:UTF-8>
1.9.3-p194 :068 > "begin #{arabic} end " + " Goodbye "
=> "begin أَبْجَدِيَّة عَ end Goodbye "
1.9.3-p194 :067 > "#{arabic} end " + " Goodbye "
=> "end Goodbye أَبْجَدِيَّة عَ"
I want the last output to read " أَبْجَدِيَّة عَ end Goodbye ".
What character encoding hoops do I have to go through to get ruby to ignore that the arabic is a RTL language?
UPDATE:
I was able to reproduce this in the following rubies:
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
jruby 1.7.3 (1.9.3p385) 2013-02-21 dac429b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_15-b03 [linux-amd64]
jruby 1.7.4 (1.9.3p392) 2013-06-07 fffffff on Java HotSpot(TM) 64-Bit Server VM 1.7.0_15-b03 [linux-amd64]
Here is a gist with the code from above
This is a bug that has been fixed. Ruby has no idea that Arabic is a RTL language. Can't replicate it on either 2.0.0-p0, 1.9.3-p392, or any other Ruby I have installed. Try upgrading to a recent version of 1.9.
Simple solution could be to use Left-to-right mark, here is html example:
"#{arabic_str1}"+" ‎"+"#{arabic_str2}"
Works well for me (1.9.3p392 ruby version).

Ruby 1.8 BigDecimal

I remember the words said by Matz: Ruby 1.8 will be dead soon. But I have no option. Here, I am using Ruby 1.8.7. Big Decimal is behaving differently compare to later version of Ruby.
For example:
ree-1.8.7-2011.12 :001 > require 'bigdecimal'
=> true
ree-1.8.7-2011.12 :002 > b=BigDecimal('0.0')
=> #<BigDecimal:9ce7148,'0.0',4(8)>
ree-1.8.7-2011.12 :003 > b
=> #<BigDecimal:9ce7148,'0.0',4(8)>
ree-1.8.7-2011.12 :004 > b==0
=> true
ree-1.8.7-2011.12 :005 > [b,b,0,0].uniq
=> [#<BigDecimal:9ce7148,'0.0',4(8)>, #<BigDecimal:9ce7148,'0.0',4(8)>] #Integer 0 is removed
ree-1.8.7-2011.12 :008 > [b,b,0,0].uniq.uniq
=> [#<BigDecimal:9ce7148,'0.0',4(8)>] #Applying two times uniq gives desired result for given array
Is there any patch to fix this issue? Sorry I don't have option to upgrade Ruby. Any help?
Thank you.
You might try https://github.com/marcandre/backports, which claims to provide "The latest features of Ruby backported to older versions". I didn't see anything in there regarding BigDecimal, at a glance, but who knows what it might be using internally. I've used it before for arrays, it's at least worth a shot.

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