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

I am working on a library module to replace an aging shell script. It (among a few other things) reads in a variety of FTP commands from a file and then performs the given FTP transaction. The system in question doesn't have Net::FTP, so that won't work much as I would prefer using that. My module will read in the config files, set up a hash with all the relevant information and return it upon request. The problem I am having is that the FTP commands in the file include variables which are set in the module. In my calling program, I call various methods in the module, print the relevant FTP transaction to a file and then call FTP passing in that file. Easy enough usually. I have a few lines of code like so:
while (my $command = $ftpgizmo->next_ftp_command ) { print OUT "${command}\n"; }
Now $command is going to be a string like:
cd $FTPPath or type ${TransferMode}
This is exactly what prints out though. How would I go about making sure that these variables are interpolated so that it prints out
cd /my/ftp/path or type ASCII
Currently, in the next_ftp_command, I define and set these variables before returning the given string, but this doesn't work.
Thanks,
Doug

Replies are listed 'Best First'.
Re: Interpolating strings within strings
by ccn (Vicar) on Sep 29, 2004 at 16:21 UTC

    while (my $command = $ftpgizmo->next_ftp_command ) { print OUT eval qq{"$command\n"}; }
      Awesome, you guys are great. Thanks a lot.
      Doug

        If your variables are in a hash, the following doesn't compile the string at runtime. It's safer and possibly faster. I've even added an esacpe sequence (${$}) in case you need to use $!

        %vars = ( FTPPath => '/my/ftp/path', TransferMode => 'ASCII', ); s/(\$(\w+|{(\$|\w+)}))/ my $var = defined($3) ? $3 : $2; $var eq '$' ? '$' : (defined($vars{$var}) ? $vars{$var} : $1); /eg;

        Test code:

Re: Interpolating strings within strings
by diotalevi (Canon) on Sep 29, 2004 at 16:18 UTC

    Use sprintf.

    return sprintf "cd %s", $FTPPath;
Re: Interpolating strings within strings
by amphiplex (Monk) on Sep 29, 2004 at 16:33 UTC
    eval should do it, but you have to make sure that the command string gets double-quotes left and right.
    an example:
    my $FTPPath = "/my/ftp/path"; my $command = 'cd $FTPPath'; my $command_new = eval "\"$command\""; print "$command_new\n";

    ---- amphiplex