Mike Slinn

Ruby Splat Operator and System Calls

Published 2025-06-09.
Time to read: 1 minutes.

This page is part of the ruby collection.

The family of Ruby methods that invoke external programs is well known, but one important way of invoking them is not well known.

One of the allowable syntaxes for Kernel.system is:

Ruby code
system('/bin/program', arg1, arg2, arg3)

The splat operator, also known as the spread operator or spread syntax, is a feature available in various programming languages. A splat operator composes or decomposes various types of collections, including tuples, arrays and dictionaries. Many programming languages have a splat operator, including CoffeScript, Julia, PHP, Python, Ruby, and Scala. The C# params operator and the CoffeScript ellipsis are similar.

One of the many things that Ruby’s splat operator can do is to destructure an array into individual arguments for a method call. The following code example yields equivalent code to the previous system call example:

Ruby code
array = ['/bin/program', 1, 2, 3]
system *array

This can be very helpful if the arguments are strings that would require escaping if converted to a string. Implementing an incantation that generates a correct escape sequence can be painful and is a common source of errors. The splat operator dispenses with the need to craft a properly escaped argument string. For example:

Ruby code
array = ['program_name', "abc'def 123"]
system *array

Let’s try this in irb:

irb
$ irb
irb(main):001> array = ["git", "status", "/path with/spaces"]
=> ["git", "status", "/path with/spaces"]
irb(main):002> system *array
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean => true

You can see the Ruby splat operator in action with a Kernel.system call in my commit Gem:

Ruby code
# @param command can be a String or an Array of String
def run(command, verbose: true, do_not_execute: false)
  if command.instance_of?(Array)
    puts command.join(' ') if verbose
    system(*command) unless do_not_execute
  else
    puts command if verbose
    `#{command}`.chomp unless do_not_execute
  end
end

For the curious, you might be interested to know that you can directly preface an array literal with a splat operator:

Ruby code
system *['program_name', "abc'def 123"]

Related Stack Overflow Answer

This Stack Overflow answer shows a similar approach that utilizes the splat operator in another way to invoke system.

* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.