On Jun 24, 2016, at 8:14 PM, Tom Copeland <tom@thomasleecopeland.com> wrote:
I agree that rand() shouldn’t have to handle any type as an argument. And generally it doesn’t, for example:
=====
ruby-2.3.0> $ ./ruby -e "rand({})"
-e:1:in `rand': no implicit conversion of Hash into Integer (TypeError)
from -e:1:in `<main>’
ruby-2.3.0> $ ./ruby -e "class Foo ; end ; rand(Foo.new)"
-e:1:in `rand': no implicit conversion of Foo into Integer (TypeError)
from -e:1:in `<main>'
That seems about right to me.
I guess I’m surprised to see the change in behavior with BasicObject though. I would have expected Ruby to bail out immediately when it can’t introspect on the argument to see if it is a Range… instead, it determines that the argument *is* a Range and carries on until it runs into a “harder” failure later on in rb_range_values.
FWIW, this all stemmed from a Rails 4.1 upgrade from 2.2.3 to 2.3.0; I had some code like this:
=====
rand(10.minutes)
and that turned up this (to me) oddity. The fix is easy, just:
=====
rand(10.minutes.to_i)
Anyhow, not a big deal, just something I found surprising. Maybe I can write it up a little more in a blog post.
On Jun 24, 2016, at 6:35 PM, Xavier Noria <fxn@hashref.com <mailto:fxn@hashref.com>> wrote:
In general, I'd say the behaviour of methods when passed bad arguments is left undefined.
If I call rand(invoice), Ruby is free to fail in different ways as a side-effect of internal changes because there is no contract to guarantee. It is even free to succeed and return a number, because undefined behaviour includes returning something.
On Friday, 24 June 2016, Tom Copeland <tom@thomasleecopeland.com <mailto:tom@thomasleecopeland.com>> wrote:
I’m surprised by this difference between Ruby 2.2.3 and 2.3.0:
====
$ ./ruby -e "puts RUBY_DESCRIPTION ; rand(BasicObject.new)"
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
-e:1:in `rand': undefined method `respond_to?' for #<BasicObject:0x007fa2d719bf78> (NoMethodError)
from -e:1:in `<main>'
$ ./ruby -e "puts RUBY_DESCRIPTION ; rand(BasicObject.new)"
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin14]
-e:1:in `rand': undefined method `begin' for #<BasicObject:0x007fe0be4cb548> (NoMethodError)
from -e:1:in `<main>'
Tracing it around in 2.3.0 leads to vm_respond_to, where method_entry_get is returning NULL, and that’s resulting in true being returned.
Has anyone seen any notes around this behavior change?
Thanks,
Tom
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org <javascript:;>?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
--
Sent from Gmail Mobile
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>