One Way 1.9 Drives Me Nuts
Published 2013-01-23 @ 12:00
Tagged thoughts, ruby
I raised a fuss when Matz proposed adding the ability to define !
and !=
on a class. The idea that you can contradict simple logic was
befuddling and seemed like a really bad design choice. Despite many of
my other proposals getting shot down with “that might confuse a
developer” or “that could cause problems in [obscure edgecase]”, this
one was defended with “I trust the developer to be smart”.
In 1.8, an unless
statement is normalized to a negated if
statement,
such that the following are all equivalent:
When ruby parses code, they all wind up being treated like the 3rd form. This makes sense. You apply simple logical transformations and normalize the code.
But, this has been thrown out the window in 1.9.
Instead, in 1.9 the first and the third are equivalent:
but in the second !
goes down an entirely different code path:
So if you have a mix of programming styles (or a mix of programmers) you can have entirely different results. Won’t that be fun to debug?
The same is true for !=
vs ==
. What was normalized in 1.8 as:
but in 1.9:
Again… a debugging nightmare. I don’t see why we have this feature. It simply seems like trouble waiting to happen.
If we’re going to allow you to contradict logic, we should at least do
it in a consistent manner. Everything should normalize towards !
.
Such that these are all equivalent:
The !=
vs ==
case makes less sense, honestly, since you can also
normalize towards ==
with !
… The fact that you can contradict
yourself 3 ways in a single class means that there isn’t any one way
to normalize. I don’t think there is a clean solution.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
require "minitest/autorun" class HaHa def == o HaHa === o end alias != == def ! true end end describe HaHa do it "must be as confusing as possible" do assert HaHa.new == HaHa.new assert HaHa.new != HaHa.new assert HaHa.new assert !HaHa.new end end |
passes with:
# Running tests:
.
Finished tests in 0.000615s, 1626.0163 tests/s, 6504.0650 assertions/s.
1 tests, 4 assertions, 0 failures, 0 errors, 0 skips