patrik
patrik

Reputation: 4558

How to use the eval statement in (g)awk?

Due to that awk does not seem to have callbacks, I was planning to use the eval statement for this. So I had a look at the GNU user guide,

https://www.gnu.org/software/gawk/manual/html_node/Viewing-And-Changing-Data.html

and then wrote this simple script.

BEGIN {
    args[1]="\"a\""
    args[2]="\"b\""
    args[3]="\"c\""
    args[4]="\"\""
    run_callback("printargs",args)
    print args[4]
}
function run_callback(callback,args)
{
    nargs=length(args)
    if (nargs>0)
    {   
        argstring=args[1]
        for (argn=2;argn<=nargs;argn++)
        {
            argstring=argstring","args[argn]
        }
    }   
    callbackstr = callback"("argstring")"
    print callbackstr
    eval callbackstr
}
function printargs(arg1,arg2,arg3,res)
{
    res=arg1","arg2","arg3
    print "res="res
}

However, the printout is not what I expected. I get this,

[~]-> gawk -f callback.awk
printargs(a,b,c,"")
""

And not the expected,

[~]-> gawk -f callback.awk
printargs(a,b,c,"")
res=a,b,c
"Not sure what is supposed to be here, but it is not relevant."

It feels as if nothing actually happens inside the eval statement. Anyone who knows what happens here?

gawk version is 4.1.3

BR Patrik

Upvotes: 4

Views: 1059

Answers (2)

Shawn
Shawn

Reputation: 52569

That's in the documentation for the gawk debugger. It's not a normal gawk function.

However, gawk does support calling a function whose name is in a string with the @var(args,...) notation (More information in the documentation):

BEGIN {
    args[1]="a"
    args[2]="b"
    args[3]="c"
    args[4]="\"\""
    run_callback("printargs",args[1],args[2],args[3],args[4])
    print args[4]
}
function run_callback(callback,arg1,arg2,arg3,res)
{
    @callback(arg1,arg2,arg3,res);
}
function printargs(arg1,arg2,arg3,res)
{
    res=arg1","arg2","arg3
    print "res="res
}

when run will print out

res=a,b,c
""

Note that args[4] isn't modified from this. From the documentation on function argument passing convention:

Instead, the passing convention is determined at runtime when the function is called, according to the following rule: if the argument is an array variable, then it is passed by reference. Otherwise, the argument is passed by value.

If you passed args directly and modified elements of it in the callback, you'd see the changes reflected.

Upvotes: 7

oliv
oliv

Reputation: 13259

awk doesn't have any eval keyword.

This can be check with gawk --dump-variables option

gawk --dump-variables -f callback.awk

It outputs the file awkvars.out and you'll find in it:

eval: uninitialized scalar

Upvotes: 2

Related Questions