Posted on

Reaper, Lua & Function Management

If you’ve never written code before, let me introduce you to a wonderful principle which you should get to know forever.  It goes by the acronym DRY

Don’t Repeat Yourself.

Don’t repeat yourself.

Sounds simple – but how many times have you told a story twice in the same telling of the story?  All the time.

How many times have you written a paragraph for a paper or blog, two different ways because you weren’t quite sure how to say it?

Coding is no different.  You’ll write something twice trying to figure something out.  Perhaps you’ll have forgotten you even wrote a function in the first place!

This is why most programming languages allow you to re-use code – so you don’t have to write it twice!

Thanks to Christian Fillion (author of Reapack), for dropping knowledge on me as to how to do this with Lua and Reaper specifically.

Here’s how to do it:

A basic definition of functions

If you’ve never written a function before, we can define it as such:

A function is a specifically defined section of a program that performs a specific task, and sometimes returns a value

Maybe it sounds a little complicated, but let’s look at a basic function in Lua.

function thisNewFunction(parameter)
-- This is a comment about the function
-- Code here will exectue when you call the function

Let me explain what you’re looking at there.

First, we tell the code we’re defining a function with the word function.  Then we give the function a name, in this case, thisNewFunction.  Within the parenthesis are any parameters we want the function to receive when we use it (or, “call” it), in this case, parameter.  The code between the words function and end are what constitutes the function itself.  End is the literal end of the function.

The cool thing about functions

The best part about functions is that they’re meant to be utilized as simple, single, reusable tasks.

So say you’re programming a Reascript and you want to get all of the selected Media Items in a session.  That code doesn’t exist, you’ll have to use other API functions and build it.

But hold the phone — this also sounds like code you could re-use over and over in multiple scripts, right?

Now, the Word-Document-writer-non-programmer in you is going to say “hey, this is easy!  Copy/Paste!”

No.  No, no, no, no, a million times NO!

Please don’t do this.  Instead, make your life easy and DRY.

What to do with multi-use functions

So instead of copy/pasting your fancy new shiny code over and over, write it once.  You should stick this code in one of two places:

  1. A single file, named after your function, that contains only your function
  2. A single file that contains all of your functions for a given project that you’re going to re-use multiple times

There’s merit to both of these ways of working.  Realistically if you have a function you use all the time, you want the first option.  But if you have some specialized code you only use in a certain project but use it regularly, option 2 is fine also.

But when you’re in your main Reascript/Lua program, how do you use this?  Here are the steps and the magic code:

  1. Write your function in a new file
  2. Save that file in the same directory as your main Reascript program
  3. Use the code snippet below to call the function from your main program
    Keep in mind, you want this code to go where you would’ve otherwise written said function in your program (probably at or near the top)
directory = ({reaper.get_action_context()})[2]:match("^(.*[/\\])")
dofile(directory .. 'thisNewFunction.lua')

When you use this code, replace thisNewFunction with the name of your file.

Now, you’ll never have to write a function more than once again!


Copyright 2016-2017, Adam T. Croft, all rights reserved.