Carsten Nielsen

Rubyisms That Ruby Programmers Should Know

There are a few things that I know now and take for granted which used to blow my mind. If only someone took the 10 minutes to explain these concepts to me back when I started programming I would have been in the know so much sooner. Hopefully I can be that someone for you if you are stuck on any of these yourself.

The Splat


def stuff(*args)
  args.inspect
end

stuff 1, 'neck', :blog # => [1, 'neck', :block]

Splats are basically like telling your method to take as many arguments as it wants and put them in an array called, in this case, args. You can name your splat anything you’d like. Splats can also appear along with other arguments in a method definition like this:


def say_jobs(person, *tasks)
  puts "#{person} will: #{tasks.join(', ')}."
end

say_jobs 'Carsten', 'clean floor', 'make dinner', 'bake a pie'
# => 'Carsten will clean floor, make dinner, bake a pie.'

You might also see a splat appear backwards in the form of a list assignment like this:


malted_battery_acids = ['Coke', 'Pepsi', 'RC Cola']
coke, pepsi, rc_cola = *malted_battery_acids

Array of Words


%w[cat dog bat hat]      # => ['cat', 'dog', 'bat', 'hat']
%w[carsten\ nielsen hat] # => ['carsten nielsen', 'hat']

This is a simple macro which creates an array of strings. It is whitespace sensitive, so it treats everything between spaces as a separate word. You can escape spaces to create words with spaces in them but just keep in mind that it can get confusing for others to read when you start doing stuff like that.

It should also be noted that I chose to use square brackets as start and end delimiters, but you can use curly braces, quotes, bars, most anything you’d like for all the percent-style literals.

Alternative String Literals


%{greetings good sir}  # <- Allows interpolation.
%q{greetings good sir} # <- No interpolation.
%Q{greetings good sir} # <- Allows interpolation.

You can think of these as the heredoc for minimalists. If you use a lowercase q it behaves like a single quoted string, otherwise you have full interpolation like a double quoted string.

Shelling Out


`which ruby`   # => '/opt/local/bin/ruby'
%x{which ruby} # => '/opt/local/bin/ruby'

Whatever you place between the back-ticks is sent to the shell, the results are returned as a string. There is an alternate style too that behaves the same.

Block Arguments


def quote(&block)
  "&ldquo;#{block.call}&rdquo;"
end

quote { 'Johnny Walker Black' }
# => '&ldquo;Johnny Walker Black&rdquo;'

Block arguments are useful when you want to capture a block to pass it to another method, or to store it for use later. When you pass a block argument to another method with the & intact the called method will receive the block as a closure.

Here we have a method that accepts a description and a block, it then executes the block and reports the time that it took to do so.


def time(desc)
  raise ArgumentError, 'block required' unless block_given?
  start = Time.now.to_i
  yield
  secs = (Time.now.to_i - start)
  s = secs % 60
  m = (secs / 60) % 60
  h = (secs / 60 / 60) % 60
  "#{desc} completed in: #{h}h#{m}m#{s}s"
end

time 'Counting to two' do
  sleep 2
end
# => "Counting to two completed in: 0h0m2s"

We could also do the same thing this way:


count_to_two = lambda { sleep 2 }
time 'Counting to two', &count_to_two
# => "Counting to two completed in: 0h0m2s"

This is effectively the same thing as above, and you can do the same thing with a splat:


args = ['Counting to two']
count_to_two = lambda { sleep 2 }
time *args, &count_to_two
# => "Counting to two completed in: 0h0m2s"