Support

If you have a problem or need to report a bug please email : support@dsprobotics.com

There are 3 sections to this support area:

DOWNLOADS: access to product manuals, support files and drivers

HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects

USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here

NEW REGISTRATIONS - please contact us if you wish to register on the forum

[Ruby] The splat operator (*) beginner's guide

Post any examples or modules that you want to share here

[Ruby] The splat operator (*) beginner's guide

Postby tulamide » Mon Apr 23, 2018 9:57 pm

Let me start by saying, that it is its official name. The splat operator. To understand why it is so great to have it, let me mention an array.

An array is an indexed list of objects. Because arrays are objects, too, an array can contain other arrays. And look at that word! An array is indeed a container.
Code: Select all
myarray = ["a", 1, 2.3, 4..6] #array containing following objects (in this order): String, Fixnum, Float, Range
myarray = [1, 2, [3, [4, 5]], 6]
#um, wow. Contains Fixnum, Fixnum, Array, Fixnum. But that last array again contains
#Fixnum, Array. Which contains Fixnum, Fixnum
#Arrays are cool motherf[peeeeeep]s!


Now there are situations, where you don't need all those layers of arrays in arrays, just the objects plain and simple. An array therefore has a method called ::flatten, which gets rid of all the layers and "flattens out" an array.
Code: Select all
[1, 2, [3, [4, 5]], 6].flatten #results in [1, 2, 3, 4, 5, 6]

Yes, KG, there's more to say about flatten, but that's not the topic here ;)

So, we flattened our array, but it is still an array. A container with an indexed list of objects. But there are occasions, where we need the objects themselves, not the array. For example, a method might define arguments.
Code: Select all
def mymethod(argument_a, argument_b, argument_c)
  return argument_a ** argument_b / argument_c
end


Back when programming languages were uncomfortable, we needed to call that method like so
Code: Select all
myarray = [1, 2, [3, [4, 5]], 6].flatten
result = mymethod(myarray[0], myarray[1], myarray[2]) #passes the fixnums at index 0, 1 and 2, ie the values 1, 2 and 3, as arguments to the method


But today's programmers are a lazy bunch of geeks, and so they say a prayer daily, thanking their God (they call him "Matz") for having created the splat operator. Because this little tool lets an array explode into its pieces (just like a water balloon splats): Bye, bye, array, and thank you for your service!
Code: Select all
myarray = [1, 2, [3, [4, 5]], 6].flatten
result = mymethod(*myarray[0..2]) ##myarray[0..2] creates a new array of exactly the first 3 objects, and the splat operator in front then creates three seperate objects from it: exactly what we need to pass


So basically it gets rid of the parentheses, and therefor creates a "non-arrayed", comma-seperated list of objects. It goes one step further than ::flatten does.
Code: Select all
*[1, 2, 3] # means 1, 2, 3 (which is not the same, the three values are now on their own, not part of an array anymore)


You can use the splat operator also, whenever you create a method that can accept any number of arguments. Normally, you have to define each and every argument of a method, as I showed above. But what if you need a method that sums any number of arguments passed? No matter if it's 1 or 100 arguments. Should we define 100 arguments? But then I would need to pass 100 objects, even if I just want to sum 3, for example. No, the solution of course is the splat operator
Code: Select all
def sum_it(*args)
  result = 0
  args.map { |n| result += n }
  return result
end


Copy the code above and paste it into an empty RubyEdit. Then add another line, calling the method with any number of arguments, for example
Code: Select all
sum_it(1, 2, 3)
sum_it(6, 8)
etc.


Cool? Yep! As you might have seen, this time the splat operator works in reverse. It takes all the arguments that we pass and builds an array from them. "Matz in Japan, holy thy name"

And so we can use it as free as you can imagine: by using the splat operator twice.
Code: Select all
def sum_it(*args)
  result = 0
  args.map { |n| result += n }
  return result
end

sum_it(*0..99) #TADAA!

WTF is going on, you ask? Well, the method is defined to accept as many arguments as we like to pass, due to the splat operator (*args). But then we pass a Range, preceded by the splat operator. This simply converts the range 0..99 to 100 individual arguments that we pass - and our method sums them all. Daoum! That Ruby guy has a point. Ruby IS cool! I will use it in my plugins way more often!
"There lies the dog buried" (German saying translated literally)
tulamide
 
Posts: 2686
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: [Ruby] The splat operator (*) beginner's guide

Postby Spogg » Tue Apr 24, 2018 8:58 am

Brilliant! :ugeek:

You’ve explained it much better than all the tutorials and reference documents I’ve found. I was struggling with this one.

Blocks is another subject that makes me feel a little uneasy. I know a bit in general, but my confidence level is low. So, if you are like a good DJ and allow requests…

Many thanks and cheers!

Spogg
User avatar
Spogg
 
Posts: 3318
Joined: Thu Nov 20, 2014 4:24 pm
Location: Birmingham, England


Return to User Examples

Who is online

Users browsing this forum: Google [Bot] and 32 guests