Why ruby? part three – method arguments

by Ochronus on August 26, 2009

This is the third part of my series: “Why ruby” – this time I quickly run through using method arguments, their types and some examples.

Basically there are two kinds of arguments in ruby – required arguments and optional ones.

Required argumens are your plain old arguments:

def the_method(arg1, arg2, arg3)

Here all three arguments are required, which means ruby will complain if you try to call the method like the_method(“alpha”, “beta”) – missing out the third argument. There isn’t much more to this.

Optional arguments are denoted by an asterisk before their names, like:

def the_method(*arglist)
  arglist.each { |arg| print "#{arg} " }
end
 
the_method("a", "b", 3)   # produces  "a b 3"

Here you can call the_method with any number (and “type”) of arguments, as you see – the optional argument becomes an array with the given arguments as elements.

Mixing required and optional arguments is also possible – it works kind of like basic pattern matching.

The trivial form (and most used) is:

def the_method(alpha, beta, *arglist)
  arglist.each { |arg| print "#{arg} " }
end
 
the_method("a", "b", 3, "ruby", "rules")    # produces "3 ruby rules"

So ruby “matches” the given list of arguments to the method argument definition, and lets the last “joker” argument, the optional one, collect all non-matched parameters.

In ruby 1.9 only you can have required arguments after the optional one:

def the_method(alpha, *arglist, beta)
  arglist.each { |arg| print "#{arg} " }
end
 
the_method("a", "b", 3, "ruby", "rules")  # produces "b 3 ruby"

Neat. The pattern is matched nicely, having the last argument variable get the value of the last given argument, the first argument variable getting the first, and all between going into the collector array (optional parameter).

Ruby supports default argument values

Up to ruby 1.8 : if default arguments are present, they have to be the last arguments:

def the_method(alpha, beta=2, gamma=4)
  print alpha
  print beta
  print gamma
end
 
the_method("a", "b")   # produces "ab4"

So this is invalid:

def the_method(alpha, beta=2, gamma)
end

Ruby 1.9 allows it though:

def the_method(alpha, beta, gamma=5, *collector, delta)
end
 
the_method(1, 2, 3) # alpha = 1 ; beta = 2, gamma=5, collector = [] ; delta = 3

but this is invalid:

def the_method(alpha, beta, gamma, *collector, delta=5)
end

Why? Think about it. It’s like having two optional arguments at the end – nonsense.

Using hashes as arguments

For a simple use case, there is no difference between passing an Integer or a String and a hash:

def the_method(alpha, hash, beta)
  p alpha
  p hash
  p beta
end
 
the_method 1, {:this=>"is", :a=>"hash"}, 2  # alpha = 1 ; hash = {:this=>"is", :a=>"hash"} ; beta = 2

But if you pass a hash as the last argument, you can omit the {} from around it:

def the_method(alpha, beta, hash)
  p alpha
  p hash
  p beta
end
 
the_method 1, 2, :this=>"is", :a=>"hash"  # alpha = 1 ; beta = 2 , hash = {:this=>"is", :a=>"hash"}

You see a lot of this in rails – this makes code much more readable in my opinion. Using this feature and having a single (hash) argument can create self-documenting and much neater method calls – you don’t have to care about the order of the arguments, just use named hash values, like this:

def the_method(args)
  if args[:i_am_a_flag]
    puts args[:print_me]
  end
end
 
the_method :i_am_a_flag => true, :print_me => "Heyheyhey"   # prints "Heyheyhey"

This is about all I can recall about arguments in ruby, I hope it’s been useful to some of you :)

  • http://twitter.com/railsindia railsindia

    Why ruby? part three – method arguments http://bit.ly/b8gJL

    This comment was originally posted on Twitter

  • http://yelirekim.com Mike Riley

    I don’t understand how default arguments function differently in ruby than they do in any other language.

    • http://www.iamnolegend.com ochronus

      They don’t differ. Default arguments are almost exactly the same as in other modern languages. What’s unique (as far as my knowledge goes) is hash arguments and pattern matching.

  • Pingback: Ennuyer.net » Blog Archive » Rails Reading - August 30, 2009

Previous post:

Next post: