Skip to content

Punchlets Explained

Punchlet layout

A punchlet is a function transforming some input data. The following punchlet adds one filed to whatever input data is given:

1
{ [user][age] = 22; }

This syntax is short and easy. Here is how it actually works. A punchlet is a Java class instance. Its actual signature is defined as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/*
 * Your punchlet is an object implementing some interface. 
 * A punchlet is created and injected with some fields, in particular
 * resource JSON files, groks patterns, a so-called world Tuple to give your
 * Punch let access to the outside world,  etc .. . 
 * 
 * A punchlet must implement a single 'execute' function, the one that will be executed
 * with the input data.
 */
 class Punchlet {        
    /*
     * @param root : the root Tuple, containing the data (logs, events, whatever)
     */  
     void execute(Tuple root) {
         // your punchlet code
         root:[user][age] = 22;
     }
 }   

It is only to make it simpler that the Punch short notation is provided. When you write

1
{ [user][age] = 22; }

The Punch compiler will take care of filling the rest, and at runtime additional resources will be injected to your punchlet.

Local Variable scope

A punchlet can contain Tuple locally declared in the scope of your function. When you return from your punchlet, their content is discarded. They are extremely useful to work on JSON content without the burden of altering the root Tuple.

1
2
3
4
5
6
7
8
{ 
    Tuple tmp;
    // fill it the way you want 
    tmp:[name] = "bob";

    // "bob" does not affect the root input data. 
    // It will be discarded at function return
}

A last important point to note. In some case you want to alter a Tuple content from the top. I.e. you want to completely overwrites its content with something else. You need a way to refer to the top value of the Tuple. Here is how :

1
2
3
4
{  
    // the ":/" notation refers to the top value. 
    root:/ = "new content";
}

You might ask why not just write ?

1
2
3
{  
    root = "new content";
}

Because the root variable is a reference to a map structure. If you assign it a new value (here a reference to a String) it will not alter the content of the root Tuple passed to your punchlet. You simply altered the local reference passed to you as an argument.

Reference versus Deep Copies

Tuples are designed for performance. In particular Tuple operations work by reference. Basically you work with pointers, altering the content of a value from a pointer will make the change affect all the other pointers. You may sometimes need to get deep copies to avoid altering the original Tuple. Check out the following snippet of code to make sure it is clear to you:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    [along] = 3;
    [astring] = "hello world!";
    [user][name] = "bob";

    // References a pointer to that object
    Tuple pointer = root;

    // The next instruction will alter the value of root:[along]
    pointer:[along] = 5;

    // Instead the next instructions  are safe and leave the root Tuple unaltered
    Tuple deepCopy = root.duplicate();
    deepCopy:[along] = 5;
}