3 ms·
in Ruby you have to fail Oh, really? ;) > [1.0,2.0,Float::NAN].sort ArgumentError: comparison of Float with Float failed > # let's make NaN sortable
by moe 12y ago
in Ruby you have to fail
Oh, really? ;)
> [1.0,2.0,Float::NAN].sort
ArgumentError: comparison of Float with Float failed
> # let's make NaN sortable
> Float::NAN.class.send(:define_method, '<=>') { |x| -1 }
> [1.0,2.0,Float::NAN].sort
=> [1.0, 2.0, NaN]
- the_mitsuhiko 12y agoThat's just horrible. You just changed behavior globally.
- moe 12y agoI didn't say it's pretty. Merely chose that example to point out the absurdity of challenging Ruby on the grounds of flexibility (of all things). Obviously, in a real program you'd rather write a custom sort-comparator, use a wrapper-class, or monkey-patch only the specific NaN instances that you want to change the behaviour of.
- bshimmin 12y agoOr use refinements.
- klibertp 12y agoNo, it's beautiful. Being a Python programmer it took me a long time to appreciate the power to do things like this. Learning Elisp, Smalltalk, Io and JavaScript (well) certainly helped. Also, of course you can scope such a change however you want, for example to a single block (and with threadlocals it's going to be mostly safe).
- dkarapetyan 12y agoHe was just demonstrating that it is possible. You can in fact alias the method, do the sorting, and then restore the previous functionality of throwing errors. Plus, someone already mentioned that you can also use refinements.
- lambda 12y agoRight, and the Rust equivalent would be to define a newtype that wraps your floating point type and defines the ordering semantics you want; in Ruby, you have changed the behavior for everything that uses Floats (including other libraries that may depend on this behavior), while in Rust you can use your newtype, other libraries can use standard floating point behavior, and you won't have any confusion about who wants which semantics.
- moe 12y agoand the Rust equivalent would be to define a newtype Which you can do in Ruby as well, as I pointed out just two comments below the one you're replying to. The real advantage of Rust here was imho best explained by sanderjd; Rust can perform this check at compile time whereas in Ruby it's a runtime exception.