Roghue has asked for the wisdom of the Perl Monks concerning the following question:

Hy all,

I'm writing some code to allow a user to delete/create/update DNS records. I'm using Net::DNS for the hard work...
here's an excerpt from an example from the Net::DNS documentation
$update->push(update => rr_add('foo.example.com. 86400 A 192.168.1.2') +);
Now I have replcaed the 'rr_add' with '${var1}', but this doesn't seem to work; compilation errors

syntax error at ./djeezycl.pl line 120, near "{$var1}("

The only way it seems to interpolate is when I use concatenation, but than the rest of the line is treated as 1 string and Net::DNS can't locate that "class"
It should only look for 'rr_add', which doesn't interpolate when placed inside '$var1'.

I hope i'm making some sort of sense here...
Any help much appreciated :)

bye,
Roghue

Replies are listed 'Best First'.
Re: Interpolating inside Net::DNS
by sgifford (Prior) on May 10, 2004 at 23:43 UTC
    rr_add is the name of a function, right? And you're putting a different function name in $var1? This isn't a simple case of interpolation, because it modifies the flow of your program.

    That's not to say you can't do it, of course. You can either use eval, as in:

    $var1=rr_add $update->push(update => eval "${var1}('foo.example.com. 86400 A 192.16 +8.1.2'))");
    or else you can use a symbolic reference:
    no strict 'refs'; $var1=rr_add $update->push(update => $var1->('foo.example.com. 86400 A 192.168.1.2' +))");

    Both of these code snippets are untested, but they should get you pointed in the right direction.

      You were right, it worked like a charm with the symbolic reference.
      I never had the need to go further than using the ${} when interpolating in my scripts... untill now :)
      Thnx for that.
      bye,
      Roghue
Re: Interpolating inside Net::DNS
by Sidhekin (Priest) on May 10, 2004 at 23:47 UTC

    rr_add is a subroutine, and your $var1 contains its name.

    You are on your way to symbolic references. Which is probably a bad thing for someone who does not know the correct syntax for symbolic references ...

    To answer your question: If you want to use your symbolic reference to a subroutine as a function, you need to dereference it as a function.

    # Either deref with ->(): $var1->('foo.example.com. 86400 A 192.168.1.2') # ... or, less fancy, deref with sigil: &{$var1}('foo.example.com. 86400 A 192.168.1.2')

    ... and so I have probably given you enough rope to hang yourself ... :-\

    Actually, this is one of those places where I just might use symbolic references. If you can forever trust $var1, that is. If that is not the case, you might do better to use a lookup table with real references.

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

Re: Interpolating inside Net::DNS
by tachyon (Chancellor) on May 10, 2004 at 23:51 UTC

    What you are trying to do is use a symbolic reference. This is almost always a bad idea. You should use a dispatch table or even a series of if/elsif statements. You could do it using eval but that is dangerous unless you know what you are doing. You can do it like this provided you turn off strict:

    no strict 'refs'; my $var1 = 'foo'; &$var1('Roghue, symbolic refs are bad practice'); sub foo { print "Hello $_[0]\n" }

    cheers

    tachyon