8 ms·
Ruby mistakes
- edu 14y agoWell, he prefers Python (https://github.com/alex https://github.com/alex). Perfect, I'll keep making my rubies shinier :)
- masklinn 14y ago> Well, he prefers Python More to the point, he comes from Python. He's also — I believe — working on a ruby (ish?) implementation (or something along those lines), which probably colors his view of what is or isn't annoying. Most of what he lists makes the life of an implementor a living hell.
- xentronium 14y ago> You can change the encoding of a string. Just jesus christ wow. erm, wat? Edit: To refute some of the points: > Why on earth does defined? return a string? Why not? Strings are perfectly valid in boolean context. > Using blocks for looping and callbacks again, wat? > break/next/return semantics in blocks extremely bizzare This is a somewhat valid point. Well, don't do it then, if you don't know what you're doing! > And they have different behavior in procs vs. lambdas > Mutable objects have a hash method and can go in Hashes. Why!!! Why not? It is possible to shoot yourself in the leg, but otherwise a very useful feature. > Special case of flip-flop and regexp in an if statement (only if it appears > syntactically though!) > Setting `$=` to something truthy causes all string operations to become > case-insensitive. This and other magic globals from perl are mind blowing. Perlisms. > `f {}`. Tell me what the parsing of that is. Calling f with empty block. > Ruby's module system makes namespacing optional (and off by default). So? > Regexp with named matches decompose into local variables. Dear lord why. No they don't necessarily, no. 1.9.3-p327 :006 > "abcdefg".match(/(?<x>abc)/) #<MatchData "abc" x:"abc"> 1.9.3-p327 :007 > x NameError: undefined local variable or method `x' for main:Object > Encoding system is beyond broken wat? > Scopes: constants, class vars, instance vars, methods, locals. wtf. Valid point. > Constants aren't constant. Truth in naming. So? > Thread locals are really fiber locals. Valid point. Overall, a very weak rant.
- lucian1900 14y agoChanging the encoding of a string effectively destroys the data inside. It's entirely useless and potentially very dangerous. Block-based loops in Ruby are pretty nice, but the semantics could be simpler. Rust gets this right. Hashable mutable objects are a giant liability. Ruby even has freezing of objects, so it should only allow hashing frozen objects at least. Ignoring scope by default is extremely stupid and dangerous. Namespacing is pointless if it's off by default.
- xentronium 14y ago> Hashable mutable objects are a giant liability. Ruby even has freezing of objects, so it should only allow hashing frozen objects at least. Well, of all dangerous things you can do with ruby, this is one of the least dangerous ones. How about "any gem can monkey patch any other gem or even core classes"? Isn't this a giant liability? Besides, it's not that difficult to make your custom hash that only allows immutable objects for keys.
- lucian1900 14y agoIndeed it is, but at least that liability is much more obvious and publicised.
- riffraff 14y ago> Changing the encoding of a string effectively destroys the data inside. You are assuming the string had the right pair of <encoding type, byte value> which is not guaranteed. For example, an old mysql binding wouldn't handle some of the encoding settings correctly, so you'd get a UTF-8 string with attached data in latin-something. This could be trivially fixed in client code by simply calling #force_encoding.
- lucian1900 14y agoThat is a bug that is more easily (and less dangerously) fixed by asking for bytes and then decoding them from latin-1.
- masklinn 14y agoUsing blocks for looping and callbacks * break/next/return semantics in blocks extremely bizzare Actually they're pretty sensible (return is anyway, break/next are a bit weird but no more so than the rest), the main issues with blocks is the — mentioned — Proc-v-lambda dichotomy and the — not mentioned — block-not-being-first-class issues. Although it's hinted at with further mentions of magical behaviors surrounding blocks. Blocks, in and of themselves, are a very good base for implementing flow control.
- seliopou 14y agoThe break/next/return behavior is not sensible at all. Anybody that comes to ruby with knowledge of other languages with first-class functions will be confused by it, in particular return. Having said that, once you learn the difference it's not that big a deal.
- masklinn 14y ago> The break/next/return behavior is not sensible at all. They are. Especially return. > Anybody that comes to ruby with knowledge of other languages with first-class functions will be confused by it, in particular return. Not necessarily, and especially not if they happen to understand what "block" means, and why Ruby uses "block" not "lambdas" for its core. Or if they have the slightest inkling of knowledge of Smalltalk and/or Self. And either way, unless they've already fossilized the difference is easy to learn (and solves important issues in imperative languages)
- seliopou 14y agoA return statement in a block is more or less a call to an escape continuation. So is break. Most programmers don't know what an escape continuation is, though once explained can use them. Even if they did, those escape continuations are captured implicitly. There's no reason to believe that people are just going to divine their meaning. And if they're new to Ruby, they're not going to understand what a block is, pretty much by definition. It's a feature that's pretty unique to Ruby.
- judofyr 14y agoShort version: "Ruby isn't Python!! wat?!?"
- dasil003 14y agoNot "wat?!?" but "why!!!". It's not a question, it's an exclamation of pure shock so intense that incredulity can not even register.
- nsmartt 14y agoI don't have an issue with most of these. In fact, to me, "ruby allows you to do X, and it shouldn't" is an annoying line of thought. If I want to make my language dance, I don't want it to cry-- I want it to sing along. There's one that I'll agree with, however, and that's "Inline rescue, no ability to specify what exception."
- paulodeon 14y agoMy first thought: That's a short list!
- jheriko 14y agoI don't get it... I thought ruby was supposed to be a mess like this? its one of its greatest strengths...
- darrencauthon 14y ago"Extremely complex grammar, makes barrier to entry for implementation much higher" Compared to... what?
- regularfry 14y agoThe average, or even more-complex-than-average, alternative language. He's right, the grammar is a complete pig.
- darrencauthon 14y agoExample? I don't understand what is meant by this.
- batiste 14y agoPython grammar http://docs.python.org/2/reference/grammar.html http://docs.python.org/2/reference/grammar.html Ruby grammar is hard to find but there it is http://www.ipa.go.jp/osc/english/ruby/Ruby_final_draft_enu_20100825.pdf http://www.ipa.go.jp/osc/english/ruby/Ruby_final_draft_enu_2...
- sepeth 14y agoIt seems that Ruby uses GNU Bison: http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/parse.y?view=markup http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/parse.y?vi... It is not so clear for documentation purposes, but grammar rules are in between 850-4988 lines. File/Line size does not tell much about Grammar complexity, but anyway, the whole parse.y file is bigger than cpython/Parser directory. BTW, Ruby's parse.y file is just the input to Bison.
- ch0wn 14y agoOne of my favorite things about Python 3 is that the grammar actually got smaller: http://docs.python.org/3/reference/grammar.html http://docs.python.org/3/reference/grammar.html It's only three lines, but still.
- 14y ago
- lampe 14y agoa rant without a solution to the rants... sry but why this post is voted up so high? do we wane start a ruby vs python war? both languages are good in there own ways. I don't even understand how someone can compare theme... "Look this Car is better then your Pineapple"
- batiste 14y agoNa, Ruby and Python are quite close to each other and quite comparable. Which other language would you compare it to?
- randomdata 14y agoPython and Ruby have somewhat comparable syntaxes, but Objective-C and Ruby are much more comparable in overall language design. If you feel the need to compare similar languages, it may be a better choice as a starting point. Or Smalltalk, but I suspect it wouldn't resonate quite as well, as much fewer people are familiar with it.
- rauljara 14y agoWhile there are a couple of things in there that annoy me about Ruby, the list basically feels like a stereotypical American pointing at a stereotypical Frenchman and saying, "Look at that French guy. He looks funny." Yes, different languages do things differently. I like discussions about the tradeoffs. I get a lot out of discussions like that. But these WTF sort of lists are pretty worthless. The implicit argument is that OMG this language is broken. Yet for any major language, people have been able to build some pretty complicated stuff with it. Clearly all these WTF things are at the very least surmountable. And a lot of them stop seeming so WTF if you actually make some effort to think about or learn why they're there.
- vidarh 14y agoIf it had been a "Ruby WTF's" list, I wouldn't have had any issues with it. While many of those items are like that for good reasons, I'd understand them causing someone reasonably new to Ruby to get confused, and worth discussing. When it's called "Ruby mistakes" on the other hand, it just gets silly.
- navyrain 14y ago100% agree. Bashing on other languages, as the author has done, makes him look childish, but worse, does the community a disservice. Professionals should be able to articulate and compare the merits of the decisions made by different languages. Even when the talking about more subjective topics, like syntax aesthetics, we can do better than simply calling them "bizarre." These are learning opportunities, not reasons to ridicule "the other team".
- norswap 14y agoRuby is not a "broken" langage. I use it and like it. But yes those are WTF things, and you have to know what they are. I remember that upon encountering it I couldn't wrap my head around throw/catch and raise/rescue. "Surely it can't that bad" I told myself. It was. The same goes for the so-called "module system". Spitting on java is very hip, but its module system is way better than Ruby is. And to the other commenter, yes those are mistakes. Calling them mistakes does not imply that the langage is beyond hope or unusable.
- jaimebuelta 14y agoMy favourite weird Ruby thing (is on the list, anyway) is that CONSTANTS can be changed, but it raises a warning... Of course, you can also set up a mutable CONSTANT (a hash, for example) and change it without a warning. So, my point is, why are they called CONSTANTS?
- nathan_long 14y agoFor the same reason private methods are called private, even though you can still access them with `send`. Ruby does not allow one programmer to handcuff another; it only allows you to put up warning signs. "I don't expect you to redefine this reference, and you shouldn't depend on the stability of this internal method."
- martinced 14y ago"Ruby does not allow one programmer to handcuff another..." That's not a valid argument. "Q: Why does your OS allow any program to write anywhere in memory?" "A: Because we believe in freedom. Our profound belief is that the OS should not allow to handcuff programmers. They must be free to do anything. They should be able to write anywhere in memory and anywhere to disk" How do you want people to be able to be able to reproduce state and to reason about a program if f*cking CONSTANTS can be modified!?
- vidarh 14y agoOf course it is a valid argument. You just don't like it. That's your right. But claiming the argument is invalid is just dumb. Your OS analogy is also poor. There's about two decades worth of discussions about memory protection in AmigaOS and it's spiritual successors (AROS, MorphOS etc.) for example, and while some people involved with those are strongly in favour of adding things like memory protection (though it is hard to do without severely breaking compatibility), there are also a lot of people for whom part of the appeal with these OS's still is that a user can hook into anything and everything: For AmigaOS there are user-level applications that can replace the task (process) scheduler, for example. There are user-level applications adding virtual memory. There's a library that gives any user-level application free reign to more easily manipulate the MMU. There OS itself provides API calls to allow user applications to replace the code used for ever library call (system wide - the equivalent of being able to override syscalls in Linux...). There are assemblers with explicit support to muck around with hardware registeres and OS structures. There are applications designed to trace everything that happens at the OS level. And a lot of these capabilities are in fairly common use by the (admittedly few) users of these systems. You might argue (and I'd agree with you) that this isn't a great basis for a modern OS. But that does not make it an invalid stance - most of these people don't want what we consider a modern OS. Many of them instead want something where they can do exactly those kind of things with nothing like a userland-kernel barrier to deal with etc.
- deleted 14y ago[deleted]
- martinced 14y ago"Mutable objects have a hash method and can go in Hashes. Why!" This is indeed terrible. It is broken beyond repair and it's probably because they thought Java doing something similar with their hashcode() method was "smart". It is not that mutability is "evil". It is that contracts provided by the language / APIs on top of mutability definitely is evil, because it's impossible to obey / respect the contracts. It is probably one of the biggest source of hard-to-find / hard-to-reproduce / hard-to-debug bugs. The problem goes way further than that in Java that said: the very presence of "hashcode()" and "equals()" at the very top of the hierarchy (in the Object class) is fundamentally broken. Even if you are using immutable objects in Java, you are still deeply fcked if your classes are non-final. Even if you classes are* only allowing to create immutable objects and are final, you are still deeply fcked if you use composition. Because it is impossible* to extend a class (or use composition) and satisfy the hashcode/equals contract. This was explained in "Effective Java" back in the days. Now it may even be possible that this very equals/hashcode/mutability SNAFU is, unconsciously for a lot people, at the heart of the current backlash and hatred towards mutability. The fact that it is so broken (and provably broken: the contracts CANNOT, as in RFC2119, be respected) may be the reason while functional programming is making a comeback. It certainly is for me and I'm not looking back.
- sproketboy 14y agoStop deflecting. Ruby is a piece of shit next to Java.
- pilif 14y ago> Encoding system is beyond broken I disagree. Due to some political issues[1], in Ruby's country of origin, Unicode is still not as widely used as it could be. Instead, local multibyte character sets are the norm. Normalizing to Unicode internally (like what Python 3 does) is impractical or not feasible as turning that Unicode data back into the original string is not reliably possible but might be required. Ignoring encodings all together and treating everything as byte strings (like 1.8.7 did) might be ok if you live in an english speaking country and you're not dealing with EBDIC. In all other cases, this means that you can't safely use any of the string manipulation built into the language. As such the second best way to deal with encodings is to have a distinct type for every possible encoding you support and have them incompatible with each other. Then the applications can decide what they want to do: Not deal with encodings at all (if you live in pure-ASCII land), unify everything to UTF-8 (or 16), or use whatever local character set the input data is in. The only thing I would be willing to argue might have been a wrong decision is adding the force_encoding method as more often than not calling that is not what you want, even though it might look as if it was. It has a huge shooting-your-own-foot potential. OTOH, sometimes libraries have mistakes or lie willingly at which point it might be a handy, albeit really dangerous, tool to have. Just like the -f flag for rm. Use it responsibly. 1) http://en.wikipedia.org/wiki/Han_unification http://en.wikipedia.org/wiki/Han_unification
- Xylakant 14y agocall it "cultural" instead of "political" and you're on the mark. force_encoding! is sometimes needed if you get data from inputs that pretend to be a different encoding than they actually are. It does offer a lot of rope to hang yourself with though.
- halostatue 14y agoIt's a bit of both. It's cultural insensitivity at the time it was done that resulted in the better part of a decade where Unicode was stalled in the East.
- jongold 14y ago— Original poster should have basic social skills but DOESN'T. Worst poster ever.
- gbog 14y agoI was in the hopes to find a deeper analysis on the problems encountered by ruby and rails recently. We get very interesting and obligatory postmortem analysis for every minute a popular site is down, but when a major framework is found to have holes, nobody tells us what could have been done to avoid them, what flaws in the tools our the team's allowed them, and here comes again the elephant in the room.
- mnarayan01 14y agoRuby makes a number of tradeoffs in favor of "expressibility" at the expense of readability (without a _high_ degree of ruby proficiency) and ability to reason about programs. You can disagree with these tradeoffs, but they're not mistakes. It also has some things which might be designed differently if the language started from scratch (e.g. string encoding), but I would still say its a stretch to call these mistakes. Ruby also has a number of things which make it "hard" (some would say impossible) to create fully equivalent alternative implementations. This is suboptimal, but it is what it is; at this point the level of change required to make it amiable to alternative implementation would be...prohibitive. I do agree, however, that the inline rescue with no ability to limit to anything other than StandardError was a mistake...I've just seen way too many cases where _far_ more than reasonable got caught. That said, I'm not sure there would be any great way to add matching on the inline rescue to the grammar -- I think it would have to be removed.
- danenania 14y agoMy ideal language would include: the intuitive-expressive power of ruby, the "explicit is better than implicit" mantra of python, the functional structure of clojure, the malleability and interactivity of lisp, and the unobtrusive static typing of go.
- decklin 14y agoIf you enjoyed this, I recommend the Unix-Haters Handbook: http://en.wikipedia.org/wiki/The_Unix-Haters_Handbook http://en.wikipedia.org/wiki/The_Unix-Haters_Handbook (I love Unix, and C, and Ruby, and yes, they're all awful, festering examples of "worse is better".)
- pcwalton 14y agoUsing blocks for looping (i.e. using callbacks) is actually a great feature. See Oleg Kiselyov's spirited defense of callbacks (as opposed to iterator objects) here: http://okmij.org/ftp/papers/LL3-collections-enumerators.txt http://okmij.org/ftp/papers/LL3-collections-enumerators.txt The fact that `break`, `next`, and `return` work the way they do in blocks is a remarkable simplification; it turns a set of constructs that work only on loops into functional constructs that work on functions, broadening their usefulness.
- atomical 14y agoI would be interested in seeing something on common Rails mistakes.
- ritchiea 14y agoThis list would be a lot more helpful with some description of why he thinks these are mistakes.