A Cool Way of Passing Arguments in Ruby
As I was programming the game engine for Ruby Tower Defense, I realized something: Sometimes you want to pass arguments out of order (So you can leave certain default parameters, but skip past others). It appears that in Ruby, there is no built-in way to do this. To give an example:
class Text < Engine::GameObject
def initialize x=0, y=0, text="TEST STRING", size=20, \
color=[255,255,255], font="FreeSans.ttf", aa=true
# initialization code here
end
end
So if I wanted to have the text “Hi!” at 200, 50:
Text.new(200, 50,"Hi!")
But what if I want to change anti-aliasing (aa) to false? So far, I’d been entering everything in order. I remembered back to when I was using Python, where I could pass arguments out of order, if I specified the variable names. I tried this in Ruby:
Text.new(x=200, y=50, text="Hi!", aa=false)
and size would become equal to false, not what I wanted…
Then after messing around for a little while, I found out that you can pass a hash to a method, in a way that looks about right from the outside:
Text.new(:x => 200, :y => 50, :text => "Hi!", :aa => false) # It looks event better if you leave off the parenthesis, # but if I don't wordpress turns x into a smily
But has some problems on the inside:
class Text < Engine::GameObject
# Creates a new Text object
#
# Parameters are in hash format (i.e. Text.new(:x => 30, :y => 500) )
# Takes:
# * x position (:x)
# * y position (:y)
# * the text to display (:text)
# * Life (:life)
# * color (:color)
# * Anti-Aliasing (true or false) (:aa)
# * Font Size (:size)
# * Font file to use (must be ttf) (:font)
def initialize settings={}
# ||= is the ruby conditional assignment
# operator, only if the variable has no value
# is it assigned the value
settings[:x] ||= 0
settings[:y] ||= 0
settings[:text] ||= "TEST STRING"
settings[:life] ||= 1
settings[:color] ||= [255,255,255]
settings[:aa] ||= true # Anti-Aliasing
settings[:size] ||= 20
settings[:font] ||="FreeSans.ttf"
# ...
end
end
This works, but with two drawbacks:
- More to type (but I could create a function to make this better)
- We lose auto documentation, and have to write it ourselves
Update: See comments
It’d be much better, IMO, if Ruby supported this internally… But this’ll have to do for now!

One of my favorite ways to handle this is to define a default_settings hash in the method, then use “settings = default_settings.merge( settings )”. If the list of settings isn’t too long, I’ll also often copy it into the arguments list for auto-documentation purposes.
def initialize( settings = {:x => 0, :y => 0} ) default_settings = {:x => 0, :y => 0} settings = default_settings.merge( settings ) # ... endDidn’t know hashes had a merge method (I didn’t check the docs…). Thanks for letting me know!
I’ll go and add that now… hack hack hack hack