Dive into Ruby

Features #

Quirks #

begin ... end while #

begin "code executed" end while false
"code not executed" while false

This is really anti-intuitive. And the creator of Ruby said not use it.

Don't use it please. I'm regretting this feature, and I'd like to remove it in the future if it's possible.

Because it's hard for users to tell begin [code] end while [cond] works differently from [code] while [cond]

loop do
  break if [cond]

-- matz. #

The return statement in proc created by will not only returns control just from itself, but also from the method enclosing it.

def some_method
	myproc = {return "End."}

	# Any code below will not get executed!
	# ...

Well, you can argue that inserts code into the enclosing method, just like block. But creates an object, while block are part of an object.

And there is another difference between lambda and That is their handling of (wrong) arguments. lambda complains about it, while ignores extra arguments or considers absence of arguments as nil.

irb(main):021:0> l = -> (x) { x.to_s }
=> #<Proc:0x8b63750@(irb):21 (lambda)>
irb(main):022:0> p = { |x| x.to_s}
=> #<Proc:0x8b59494@(irb):22>
ArgumentError: wrong number of arguments (0 for 1)
        from (irb):21:in `block in irb_binding'
        from (irb):25:in `call'
        from (irb):25
        from /usr/bin/irb:11:in `<main>'
=> ""
irb(main):049:0> 1, 2
ArgumentError: wrong number of arguments (2 for 1)
        from (irb):47:in `block in irb_binding'
        from (irb):49:in `call'
        from (irb):49
        from /usr/bin/irb:11:in `<main>'
irb(main):050:0> 1, 2
=> "1"

BTW, proc in Ruby 1.8 creates a lambda, while in Ruby 1.9+ behaves like, really confusing.

def does not create closures. #

Closures are simple in Python:

def a(x):
  def b():
    return x

This won't work in Ruby.

def a(x)
  def b

In Ruby, def starts a new scope, without access to outer variables. Only @var and $var can be accessed. And no extern keyword like in C. In Ruby, lambda creates closure:

def a(x)
  b = ->{ x }

Or define_method:

def a(x)
  define_method(:b) { x }

In Ruby 1.9, define_method is not availabel in main Object, you can use define_singleton_method instead.

Tutorial #

Ruby advertises its "Least Surprise" principle, thus I hope a basic understanding of the above features and quirks is enough to dive into Ruby. If you are unsure about something on Ruby, you can guess and try, and it usually works, except for quirks mentioned above.

If you prefer reading a tutorial before diving into Ruby, I would recommend why's guide to Ruby, a poignant introduction to a shiny language.


Use pry.

Make #

Use rake.

rake is a popular choice in Ruby.

rake is generally nice. But pathmap in rake uses rules hard to remember:


WTF is %{^sources/,outputs/}X? And what is the difference if we replace X with one of p, f, n, d, x?