Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: How to read flat file and execute a subroutine inside that flat file in my main program

by huck (Prior)
on Mar 21, 2017 at 11:10 UTC ( [id://1185333]=note: print w/replies, xml ) Need Help??


in reply to How to read flat file and execute a subroutine inside that flat file in my main program

There are two ways of doing this, The dangerous way

use strict; use warnings; sub getTableID($$) {return 100;} my @arr; while(<DATA>){ chomp; push(@arr, $_); } foreach my $line(@arr) { my @arr1 = split(",",$line,2); my $val1 = $arr1[0]; # add the & to make sure it is thought of as a subroutine; my $call='&'.$arr1[1]; print $call."\n"; my $func = eval $call; if ($@) { print 'Error:'.$@."\n"; } else { print 'func:'.$func."\n"; } } __DATA__ 1,getTableID('DBO','Table2') 2,getTableID('DBO','Table2') 3,putTableID('DBO','Table2')
Result
D:\goodies\pdhuck\down1\perl\monks>perl dynsub.pl &getTableID('DBO','Table2') func:100 &getTableID('DBO','Table2') func:100 &putTableID('DBO','Table2') Error:Undefined subroutine &main::putTableID called at (eval 3) line 1 +, <DATA> line 3.
Even with forcing it to assume its a subroutine because of the & eval is very powerful and a line like
4,getTableID('DBO','Table2');`rm -rf .`
could cause you a lot of problems.

The second way is more controlled. It uses what is called dynamic subroutines, the hash %subs has as values a set of subroutines with no names.

use strict; use warnings; sub getTableID($$) {return 100;} my %subs=( getTableID=> sub {getTableID($_[0],$_[1]);}, putTableID=> sub { my @a=@_; return $a[0];}, ) ; my @arr; while(<DATA>){ chomp; push(@arr, $_); } foreach my $line(@arr) { my @arr1 = split(",",$line); my $val1 = shift @arr1; my $call = shift @arr1; my $func; if ($subs{$call}) { $func=$subs{$call}->(@arr1); print 'call:',$call.' func:'.$func."\n"; } else { print 'unknown sub:'.$call."\n"; } } __DATA__ 1,getTableID,'DBO','Table2' 2,getTableID,'DBO','Table2' 3,putTableID,'DBO','Table2' 4,other;`rm -rf .`,a,b
Result:
D:\goodies\pdhuck\down1\perl\monks>perl dynsub2.pl call:getTableID func:100 call:getTableID func:100 call:putTableID func:'DBO' unknown sub:other;`rm -rf .`
notice that the data lines are split so the call name is in its own column and the args are each in their own column. First we check if the call exists. if it does we call the dynamic sub, if not we print an error. Notice that the sub under the key getTableID calls an existing subroutine, while the call under key putTableID has the whole subroutine declared in place. Either method works. This is a much safer technique than eval.

Most of what i know of this second technique came from Mastering Perl Creating professional programs with Perl By brian d foy. While he was in the process of finishing the book he had major parts of it online for people to proof read. I devoured the dynamic subroutine chapter and recommend the entire book heartily. Alas it is no longer online, but i think i found that link here at the Monastery when it was up.

Replies are listed 'Best First'.
Re^2: How to read flat file and execute a subroutine inside that flat file in my main program
by udday.shank (Initiate) on Mar 27, 2017 at 07:07 UTC

    Many thanks! It worked. Here is my sample code:

    content of sample.txt:

    1@@getTableID('public','t1')@@3
    open FH, "sample.txt" or die $!; $str = <FH>; close FH; my @arr = split("@@",$str); sub getTableID($$) {return 100;} $subs{$arr[1]} = sub{getTableID($_[0],$_[1])}; my $val1 = $arr[0]; my $call = $arr[1]; my $func; if ($subs{$call}) { $func=$subs{$call}->(@arr1); print 'call:',$call.' func:'.$func."\n"; } else { print 'unknown sub:'.$call."\n"; }

    output:

    call:getTableID('public','t1') func:100

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1185333]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-03-28 15:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found