views:

942

answers:

8

Possible Duplicate:
What are the Ruby Gotchas a newbie should be warned about?

What are some common programming mistakes made by Ruby developers, and how can they be avoided?

For example, requiring a gem and forgetting to require 'rubygems'.

(Inspired by Common programming mistakes for .NET developers to avoid?)

+7  A: 

This should answer your question - Ruby Gotchas for newbies

Chirantan
+5  A: 

Proper whitespace in ternary operator expressions

Private class (not instance) variables silently aren't private

rescue by itself is not a catch-all

Trying to nest a def in a def looks like it works but it doesn't achieve nested functions like you'd think

Not understanding the difference between && and and et al can bite you

Those are what come to mind at the moment.

J Cooper
+1  A: 

may be this may help ....

A list of common gotchas and other tips from Programming Ruby: The Pragmatic Programmer's Guide.

+1  A: 

depending on what language you did last, there're lots of ruby vs. X comparos (these aren't the greatest examples but the general principle of understanding deltas in your main language vs. what you're picking up now is a big time saver)

ruby v java

http://colmsmyth.blogspot.com/2007/06/why-java-developers-dont-have-ruby-envy.html


ruby v. python

http://news.ycombinator.com/item?id=157269

Gene T
+1  A: 

Common mistake for former Java developers: instance variables vs. class instance variables.

class Example
  @foo = 1
  @bar = 2
  attr_accessor :foo
  attr_accessor :bar
end

Example.new.foo #=> nil
Example.new.bar #=> nil

class Better
  attr_accessor :foo
  attr_accessor :bar
  def initialize
    @foo = 3
    @bar = 4
  end
end

Better.new.foo #=> 3
Better.new.bar #=> 4

Just remember that everything in Ruby is an object - including classes. So if all objects can have instance variables, classes can too.

The way to tell whose instance variables you're talking about is by checking the value of self

class WhoAmI
  p self #=> WhoAmI

  def initialize
    p self #=> #<WhoAmI:0x25788>
  end

  def self.a_class_method
    p self #=> WhoAmI
  end

  def an_instance_method
    p self #=> #<WhoAmI:0x25788>
  end
end
rampion
+8  A: 

A few quickies, especially if you come from Java or something similar:

  • private also don't work like you think. If method is private it means you can only call it on yourself. You can redefine it, and call it from subclasses, but you cannot call it on other objects of the same class. Normally you shouldn't be using private anyway, as it just makes unit testing harder and private and public methods live in a single namespace so you don't get too much protection.
  • @@class_variables - don't use them ever, their semantics are much more complicated than you think.
  • protected methods don't work like you think, don't use them ever. They also have very complicated semantics and don't work too well with metaprogramming.
  • classes are objects, and have separate set of methods, so Foo.bar and Foo.new.bar are completely unrelated.
  • Ruby syntax tries to be nice most of the time but sometimes it bites you. For example when you try to pass empty hash to a method you don't say obj.foo {} as that would be interpreted as a block, you need to say obj.foo({}). There are some more cases when you need to use explicit parenthesis.
  • Semantics of blocks vs lambdas are rather painfully complicated and change a lot between 1.8 and 1.9. They do what you want 99% of the time, but you will probably at some point stumble upon a bug caused by this.
  • There are some really absurd methods defined in Ruby 1.8, so things you would expect to throw an exception just work. For example 5[2] returns 1 (value of 2nd bit, starting from 0)
  • Symbols vs Strings. It's not simple to learn when to use which, especially since in 90% of cases both will be accepted, and in some cases you get nasty surprising errors.
  • In boolean context everything except nil and false is considered true, including 0, 0.0, "", [], {} etc.
taw
Would you please elaborate point no. 3 about protected methods?
Chirantan
Right now (and it wasn't always so) protected methods check class of caller's `self` against class where particular method was defined. First isn't used in Ruby for absolutely anything else. Second is only used for `UnboundMethod#bind`. Other than in this check, Ruby provides no access to either - it's really difficult to metaprogram anything with protected methods. You cannot delegate them, you cannot change them in subclass, protected methods are really horrible.
taw
+1  A: 

Don't rescue Exception, you'll catch stuff that ought to fail, like out-of-memory and exit. (Yes, exit works by throwing an exception.) Instead, rescue StandardError. "rescue" without an exception type catches only RuntimeError, and none of the standard exceptions use that.

Don't inherit Exception in your own error class, you'll be forced to catch it explicitly by name. Inherit RuntimeError, and plain "rescue" will catch it.

Library writers often don't know the above (even in the standard library). You will have to catch their exceptions explicitly.

Julian Morrison
You're able to inherit the exception from `StandardError` and still get caught by default.
Andrew Grimm
A: 

Avoid class variables - they prevent modularity and encapsulation.

Avoid designs that heavily rely on class methods - they are generally harder to read and more verbose then Object Oriented designs.

scottschulthess