I have absolutely no clue what you're talking about WRT throw/catch and raise/rescue being confusing and bad. It's not. They do different things and have different purposes. I can't think of any time that I have used throw/catch, but I absolutely know its purpose, and its parallel nature to exceptions make frameworks like Sinatra fairly elegant.
Ruby also doesn't have a so-called "module system", so I have no clue what you or the OP are talking about.
Both classes and modules in Ruby can be used for namespacing purposes. Modules tend to fill the default "pure namespace" role, but that isn't their purpose—it just happens to be convention. The purpose of a module is an interface (per Java) with implementation—a mixin.
If, however, you're referring to the way that ruby programs are structured and how Kernel#require works…you're still barking up the wrong tree.
Yes, Ruby has mistakes—these two items that you've mentioned are not. Neither are most of the things that the OP's gist mentions. Some things on the list are confusing (break/next/return semantics; Yehuda Katz has a good article highlighting it that I found after a discussion with Reg Braithwaite [raganwald] and others on Twitter that had started the night before at a bar); most of them are simply the author's ignorance—and I don't mean that disparagingly. I am ignorant of many things about Python and JavaScript, because they are not my primary programming languages.
Ignorance can be easily cured. Arrogance is much harder to cure.
By "module system", I mean a way to handle namespacing.
I checked a few facts out, and it's actually less bad than I thought. The main problem I see is that it doesn't warn you of collisions when including modules. But if you catch a collision yourself, you can resolve it.
About throw/catch and raise/rescue. First, why have throw/catch and not have it do what it does in every single other langage? I guess this is debatable.
Secondly, a problem with throw/catch is that there is no "clean" way to know if you exited via a throw or normally (the hackish way involves a boolean variable). I guess you could argue that it isn't the intended use. I'm missing this because of the following point.
My real grief with raise/rescue is that it acts exactly like Java's throw/catch, while it could be so much more. Why couldn't we throw arbitrary objects? And pass arbitrary objects to rescue, which would have a special method (lets call it "catches?(e)") that would check if the objects "matches" a thing that was thrown. Exception classes would have this as a class method, and it would match its own instances.
This, incidentally, is exactly how the ruby case statement works. In that case, the special method is "===". So that's an inconsistency in the langage right there I'd say. Or at the very least, a missed opportunity.
So ok, maybe not "mistakes" if that's too strong of a word for you. But "things that should change"? Definitely.
1. You shouldn't be including modules without knowing what you're including.
2. throw/catch isn't an exception handling system. You do have a clean way to know whether you exited via throw or normally; see http://rubylearning.com/blog/2011/07/12/throw-catch-raise-re... for details (it's a nice little summary). The problem is that you seem to think that throw/catch is for exception handling because everyone else uses those terms for exceptions.
My understanding is that throw/catch (while used less often) is cheaper to set up than begin/raise/rescue/ensure/end.
3. raise/rescue does behave like Java's throw/catch in that it's explicitly for exception handling. As far as throwing arbitrary objects, let me share a beauty from C++:
try
{
throw 0;
}
catch (...) // The only thing that catches 0.
{
}
C++ doesn't restrict what objects can be thrown. It's a horrendous disaster for the language. Exceptions—including stack unwinding, etc.—are hideously expensive (and they're worse in Java with checked/unchecked exceptions) and should be used only for the worst possible things.
You want raise/rescue to work like throw/catch. If you want that, use throw/catch and save raise/rescue for real exception handling. Or even ignore both of them.
I think that what you've described are neither mistakes, inconsistencies, missed opportunities, or things that should change.
4. I didn't use an argument from ad hominem. I carefully deconstructed the argument on technical merits and noted that these sorts of arguments come from ignorance—of which I have in spades on many topics. I also noted that it is harder to swallow the arrogance that deems arguments from ignorance as "mistakes". Both of these statements are factual.
True story: like many people who discovered Ruby after having used a number of different languages, I had substantive amounts of ignorance about why the language was what it was. In 2002—having just picked up the language, I suggested that nil should act like NULL in SQL (e.g., only tested through special case handling). This was ignorance. It was also arrogance to suggest this for a language that at the time I had been using for less than a month.
I thought I argued the point very well and looking at the follow-ups, it wasn't as bad as I remembered, but the proposal wasn't very…Rubyish. (Going back through to find a few other examples, I found this gem <http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/...; and I can think of several cases, including the original PDF::Writer, where I had to do just that.)
It is harder to correct a problem of arrogance than a problem of ignorance. The person who wrote the original list was both ignorant (new to Ruby, to be expected, and explicitly Not A Problem) and arrogant (labelling them as mistakes with Ruby as opposed to decisions/behaviours that weren't understood). There's a lot that I don't understand about Python, but I am (at this point, past 40) no longer so arrogant that I declare the explicit self or the way that len(x) is implemented to be mistakes in the design of the language (even though I think they are warts that make Python much less pleasant for me to use).
Ruby also doesn't have a so-called "module system", so I have no clue what you or the OP are talking about.
Both classes and modules in Ruby can be used for namespacing purposes. Modules tend to fill the default "pure namespace" role, but that isn't their purpose—it just happens to be convention. The purpose of a module is an interface (per Java) with implementation—a mixin.
If, however, you're referring to the way that ruby programs are structured and how Kernel#require works…you're still barking up the wrong tree.
Yes, Ruby has mistakes—these two items that you've mentioned are not. Neither are most of the things that the OP's gist mentions. Some things on the list are confusing (break/next/return semantics; Yehuda Katz has a good article highlighting it that I found after a discussion with Reg Braithwaite [raganwald] and others on Twitter that had started the night before at a bar); most of them are simply the author's ignorance—and I don't mean that disparagingly. I am ignorant of many things about Python and JavaScript, because they are not my primary programming languages.
Ignorance can be easily cured. Arrogance is much harder to cure.