20

I recently read Crockford's book "Javascript: The Good Parts" and one of the underlying premises was that programming languages can have bad sets of features which programmers should avoid.

I'm a Rubyist and whilst I love the language there's always value in getting perspective. So, what do you see as the worst feature (e.g. methods, classes, practices) in Ruby? My intention here is not to start an argument about the merits of the language itself or its speed and so on. Rather I'd prefer a discussion of what features you consider dangerous / troublesome / painful to use, based on past experiences.

8
  • 1
    I've never been a fan of having to use the word "end", and then the mixture of that with "{" and "}" gets even more annoying. It makes me appreciate either Python-style syntax or straight up { & }'s. Although one could argue back and forth on this, and ultimately it has a lot to do with personal preference. I heard someone say that Ruby takes the ugliest parts of Python and Perl and puts them together. I am enjoying learning Ruby, though.
    – Mark Nenadov
    Mar 26, 2011 at 11:40
  • I actually quite like this question and would be looking forward to answers, but nevertheless voted to close it. I don't think it's a good fit for Stack Overflow (due to potentially being too subjective/argumentative, open-ended, etc.).
    – stakx
    Mar 26, 2011 at 11:41
  • I think it's worth discussing as it could illuminate dangerous practices to avoid. I see your point though and edited the question to be more narrow.
    – Jack Kinsella
    Mar 26, 2011 at 11:44
  • 9
    I don't see how this question is distinct enough from, e.g. What are the things you would like improved in the Ruby language?, What are the Ruby Gotchas a newbie should be warned about?, What are the real-world problems with Ruby? or any of the other gazillion questions about the pain points of Ruby. Plus, even if this question is evolved to differentiate itself from those other ones, it would belong on Programmers.SE, not StackOverflow. Mar 26, 2011 at 12:27
  • 3
    I need to get my eyes checked--I thought the title of this question was "Ruby: The Brad Pitts".
    – oosterwal
    Mar 28, 2011 at 13:47

8 Answers 8

8

You should watch Python vs Ruby: A Battle to The Death by Gary Bernhardt. He makes the quote:

The very things I find ugly in Ruby are what make amazing Ruby software like RSpec possible, and that Python could never have (given the current implementation).

While he talks a lot about Python in particular, he touches on a lot of stuff that's just weird in Ruby. One of the big overarching subjects is monkey patching.

Ruby objects (unlike objects in some other object-oriented languages) can be individually modified. You can always add methods on a per object basis. In Ruby, the behavior or capabilities of an object can deviate from those supplied by its class.

While this provides a lot of flexibility and powers some of Ruby's most popular and complicated gems, it can bite you in the butt if you're trying to debug an issue without realizing that some library somewhere has modified a core method.

1
  • Javascript allows you to treat objects that way as well.
    – kingsfoil
    Nov 3, 2014 at 22:18
8

Some people only think of ruby in terms of ruby on rails and it's kinda annoying because the language stands on its own pretty well.

7

I think the worst feature is open classes which allow you to globally change the behavior of all current and future instances of the changed class.

The problematic part of this feature is, that theses (global) changes happen during runtime when the Ruby interpreter comes across the definition, which might be long after you already instantiated a couple of objects which now change their behavior all of a sudden.

In a large code base this can result in very, very hard to find bugs - especially as this gets compounded by Ruby's weak (as compared e.g. to the CLR or JVM) debugging story and use of other features (e.g. eval) in this context can make it quite hard to find the location where this global change occurred. i.e. if you already reached the point where you suspect the 'right' class causing the trouble! In my experience you usually start out with a wild goose chase, as the problems start to surface at an object using the real culprit.

So the best thing would be, either to stop using open classes (#extend and putting the changes in a Module is IMHO much safer, easier to understand and better to test) or if it can't be avoided to:

  • only extend classes with new behavior (i.e. not overriding existing behavior)
  • have a defined place in the source code tree, where all extensions using open classes have to be placed
  • do not use #eval and friends to create open classes
  • put all usages of open classes on a big visible chart, where all developers can see them - and make clear that any changes on them are 'architectural decisions' affecting the whole code base (which they do) and not the place for quick hacks useful for your current task
5

Biggest reason I don't use Ruby: It's slower than molasses in January at the North Pole during an ice age. Benchmarking languages is an inexact science, but Ruby appears drastically slower than even JavaScript and Python.

10
  • that was my experience too. Mar 28, 2011 at 1:04
  • 2
    what was the application you developed for which ruby was too slow ? I mean, I believe you when you say it is slow, but how did it stop you from reaching your goal ?
    – David
    Mar 28, 2011 at 11:20
  • 1
    I think Ruby is great when you want to make something like a prototype and want it done quickly, something that isn't huge and won't be doing massive number crunching. If you expect to be chewing a lot of CPU cycles constantly, any good programmer knows to use something like C or C++. Mar 28, 2011 at 11:33
  • 1
    @David: I would consider using Ruby for simple DNA sequence processing code, but I don't because Python fills a similar niche, has similar features and is much faster. If I'm willing to go lower level, D is even faster and still convenient.
    – dsimcha
    Mar 29, 2011 at 0:58
  • 1
    @Jeff: Agreed, but C and C++ are a pain to write in. The point of high-level languages like Ruby is to avoid dealing with this pain as much as possible. The slower they are, the less well they fulfill this goal. Ruby is slow even for a high-level dynamic language. That and NumPy/SciPy are why I use Python instead when I need a high-level dynamic language.
    – dsimcha
    Mar 29, 2011 at 1:00
4

If this can be extended to Ruby on Rails, then:

  1. The fact that the database logic gives every single table an auto_increment primary key, including tables that don't need them and shouldn't have them.

  2. The fact that compound keys aren't supported at all.

For just plain Ruby my gripe would be the same as for any language that trades safety for expressiveness; it's easy to do a lot with just a little code, but it's just as easy to make a huge mess with any amount of code.

5
  • Please see my edits as I've narrowed the scope of the question. I'll start another parallel one for Rails if this question with edits is approved.
    – Jack Kinsella
    Mar 26, 2011 at 11:48
  • 1
    Sorry, but you're mistaken, not every table in a Rails app is required to have an auto_increment id, notably join tables for has_and_belongs_to_many relationships are suggested to explicitly NOT have an id column. Mar 26, 2011 at 13:38
  • @Brett - Are those relatively new additions? When I was playing with it back in early 2008 it definitely did not have those features. In any case, it's great that they're available now.
    – aroth
    Mar 26, 2011 at 13:49
  • 1
    @aroth: I'm not sure that everyone else would consider "relatively new" to mean "within the last three years" :-)
    – nickgrim
    Mar 26, 2011 at 14:33
  • There's an alternative to Rails' ActiveRecord called DataMapper, which is not as opinionated as ActiveRecord. May 4, 2011 at 11:30
3

Ruby embraces metaprogramming (reflection, introspection), multi-paradigm programming, and dynamism at an uncommon level. It's easy to shoot yourself in the foot with power and flexibility.

Troublesome? Ruby has the ability to be extremely readable or inscruptable. I've seen code that looks like it belongs in a Bash script.

Bad Practices? Some Rubyist value cleverness over wisdom. They write and share tricks that show off their cleverness, but this creates unreadable and fragile code.

As an aside: Javascript was a disaster by design, and "The Good Parts" book tries to extract it's hidden beauty. Perl, a language which popularized "There's More Than One Way To Do It" (that is, flexibility), has a similiar book in "Perl, Best Practices". Perl's history is one of experimentation and hard won experience, "Best Practices" represents its knowledge. Perl 6 will be, I think it's fair to say, a reboot of the language based on that knowledge and more. Ruby may suffer from similar issues.

@James and for loops... When you do a for loop in ruby, it then calls ".each". Therefore, "for" is syntactic sugar for people more comfortable with C style loops. But as a Rubyist, you're going to use iterators like .map, .inject, .each_with_object, all the time. You'll never have to write a for loop with something like "i=0;i>6;i++" in ruby, and so you end up dropping the habit. @andrew... eloquent ruby doesn't endorse for loops.

-1

This is more about the programmers than the language, but why do Ruby programmers hate for loops so much?

I realise Ruby has:

someCollection.each do |item|
   ...
end

but I've never seen that used in situations where a for loop would not do exactly the same thing.

I've asked several times and never gotten a good answer to this one.

If it's just a style thing, I'm happy to accept that, but I've seen Ruby programmers get really worked up about this and I'm really curious.

10
  • 1
    Once I even got the answer "It's less key presses", which is clearly false ... :-)
    – James
    Mar 28, 2011 at 9:38
  • 2
    Two theories: 1) Using for loops is something n00bs do. People who are programming C in Ruby. 2) Blocks are used a lot in Ruby, so using something not block-like is just extra mental effort. Mar 28, 2011 at 10:36
  • 3
    While I just started to learn Ruby, blocks are something that I really like and miss when I try to use Python. Would a for loop do the same thing? Of course, to me, this kind of style just suits my preferences more than a for loop.
    – Jetti
    Mar 28, 2011 at 12:50
  • 2
    @andrew To be honest, your 1st answer is exactly the kind of rubbish I got back when I've asked before. No real reason, with a subtle insult on top. @Wayne, @Jetti and @andrews 2nd answer: thanks. Fair enough then.
    – James
    Apr 14, 2011 at 21:51
  • 1
    If you mean "enhanced" for loops (aka. for <value> in <expression> do ...) there is no difference apart from #each being in use and appearance closer to its commonly used cousins #inject, #collect, #reject etc. If you're talking about 'C' style indexed loops (aka. for int i = 0; i < whatever; ++i) the difference is, that a) "off by one" errors are impossible and b) that it makes the intention of your loop clear - #each meaning "for each element produce a side effect". A for loop requires you to read the whole loop just to get the 'gist' of its purpose. May 4, 2011 at 13:05
-1

I'd generally avoid things that were added just to be backwards-compatible with other languages. For example, Perlisms and for x in y.

1
  • I just posted an answer about Ruby Programmers and for loops, and if you can explain I'd be grateful :-)
    – James
    Mar 28, 2011 at 9:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.