Ruby’s grenade operator

October 3, 2007 at 13:56

Filed under: Computing — Pistos @ 13:56

Some time ago, I started calling Ruby’s unary * operator the “grenade operator”. After all, the glyph looks like an explosion, and the metaphorical operation is the taking of a container packed with stuff and blasting the container open so that the contents are strewn about, ready for more direct use. People seem to get a tickle out of the term when use it in IRC, and I have been coaxed into submitting to the urge to make a blog post about it, in order to concretize my claim to its coinage. So here’s the blog post.

You can apparently do a number of nifty things with the grenade operator. Here are the two that I tend to do most often.

Converting an array to a syntactic list

There’s probably some more appropriate and correct terminology for this operation, but I like to think of it as taking the elements of an array, and turning them into a list, as though that list were “typed out”, as it were, into your code. For example:

def tell_family_story( father, mother, child )
  puts "#{father} married #{mother} and "
  puts "they loved each other so much that "
  puts "#{child} was born."
end
family = [ "John", "Marsha", "Jack" ]
tell_family_story( *family )
John married Marsha and
they loved each other so much that
Jack was born.

Methods with a variable number of parameters

Sometimes you want to craft a method that can have a different number of parameters from call to call. You would then use the grenade operator to collect many method parameters into a single array, like so:

def list_favourites(
  format_str, *data
)
  format_str.scan( /\w/ ) do |fmt|
    per = data.shift
    fav = data.shift
    case fmt
      when 'l'
        puts "#{per} likes #{fav.downcase}"
      when 'u'
        puts "#{per} likes #{fav.upcase}"
      else
        puts "#{per} likes #{fav}"
    end
  end
end
 
list_favourites(
  "nlu",
  "John", "Fishing",
  "Marsha", "Shopping",
  "Jack", "Grenades"
)
John likes Fishing
Marsha likes shopping
Jack likes GRENADES

Other uses

There are other feats of wizardry that some coders perform with the grenade operator, such as some assignment acrobatics, as described in the Pickaxe Book:

a = [1, 2, 3, 4]
b,  c = a
# b == 1,  c == 2
b, *c = a
# b == 1,  c == [2, 3, 4]
b,  c = 99,  a
# b == 99, c == [1, 2, 3, 4]
b, *c = 99,  a
# b == 99, c == [[1, 2, 3, 4]]
b,  c = 99, *a
# b == 99, c == 1
b, *c = 99, *a
# b == 99, c == [1, 2, 3, 4]
 
b, (c,*d), e = 1,[2,3,4],5
# b == 1, c == 2, d == [3, 4], e == 5

Final notes

You might get confused as to which side of the operand you should toss the grenade operator toward. Just keep in mind that if it were on the right side, it would be the binary * operator, and Ruby would expect something on the other side of the operator. Therefore, always throw to the left.

Have fun with your new explosives, but also note that, no matter how you interpret the first example, I am by no means suggesting that you hurl grenades at families trapped in boxes.

Share This

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

You may use Markdown syntax in your comment.

Powered by WP Hashcash

Powered by WordPress.
Close
E-mail It
Socialized through Gregarious 42