Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

How can I create a procedure

by ozgurp (Beadle)
on Jun 10, 2003 at 01:23 UTC ( #264512=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks, How can I:

1. Make the bodies of my if statements into procedures.

2. Have, at the very beginning of my program, my if statements. Rather than have them execute the procedures, have them build an array of procedure references.

3. In the body of my script, for each row of data, call each procedure in the array.

Instead of having following code:

while(<FH>){ if($_ =~ C B A R){ do something This bit is not the same for all elements and it is average 100 +lines long } if($_ =~ Q U A D){ do something This bit is not the same for all elements and it is average 100 +lines long } if($_ =~ C R O D){ do something This bit is not the same for all elements and it is average 100 +lines long } if($_ =~ C B E A M){ do something This bit is not the same for all elements and it is average 100 +lines long } if($_ =~ C E L A S 1){ do something This bit is not the same for all elements and it is average 100 +lines long } ... }
I could have for example C B A R if statement in the while loop because the user selects only CBAR.
while(<FH>){ if($_ =~ C B A R){ do something This bit is not the same for all elements and it is average 100 +lines long } }

Replies are listed 'Best First'.
Re: How can I create a procedure
by sauoq (Abbot) on Jun 10, 2003 at 01:46 UTC

    First, you do realize that the syntax if ($_ =~ C B A R) { ... } is unlikely to even compile for you¹, right?

    The way you create functions (procedures/methods/subroutines, pick your terminology) is with the sub keyword.

    sub my_sub { print "I'm a sub!\n"; }
    Arguments to a sub are passed via the special array variable named @_.
    sub my_sub_with_args { my @args = @_; print "I'm in a sub that was called with these args: @args\n"; }
    The way we call those subs is simply by invoking their name. If you didn't declare them before you invoke them, you must supply parens. Generally speaking, parens are a good idea anyway.
    my_sub(); my_sub_with_arguments("some", "arguments");
    This is perhaps the most basic of basic introductions. For more information, read perldoc persub. One thing you should know right off the bat though... don't use "prototypes" until you really understand them. (And don't think that you really understand them until you read Tom Christiansen's article about them.

    1.Unless you have some whacky packages and methods names, anyway.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: How can I create a procedure
by educated_foo (Vicar) on Jun 10, 2003 at 01:52 UTC
    Not quite sure what you're trying to do, but one nice way to delay execution is to use an anonymous sub:
    my @procs; my @actions = ([qr/test 1/, sub { thing if true; }], [qr/test 2/, sub { thing if true; }]); for my $x (@actions) { my ($re, $sub) = @$x; if (/$re/) { push @procs, $sub; } } while (<INPUT>) { for my $f (@procs) { $f->($_); } }
    /s
Re: How can I create a procedure
by NetWallah (Canon) on Jun 10, 2003 at 04:39 UTC
    Here is a code segment I used in a similar situation:
    # Partial list from http://www.iana.org/assignments/ethernet-numbers my %Ethernet_Type_Name = ( (ETH_TYPE_IP) =>{NAME=>'IP', DECODER => \&Decode_IP} +, (ETH_TYPE_ARP) =>{NAME=>'ARP', DECODER => \&Decode_AR +P}, (ETH_TYPE_APPLETALK) =>{NAME=>'APPLETALK', DECODER => 0}, 0x8035 =>{NAME=>'RARP', DECODER => \&Decode_ARP}, # (E +TH_TYPE_RARP is NOT exported!!!) (ETH_TYPE_SNMP) =>{NAME=>'SNMP', DECODER => 0}, (ETH_TYPE_IPv6) =>{NAME=>'IPv6', DECODER => 0}, (ETH_TYPE_PPP) =>{NAME=>'PPP' ,DECODER => 0} ); ...snip ... if (&Dispach_Decoder_If_Any(\%Ethernet_Type_Name, $eth_obj->{type}, $eth_obj,\$buf)){ # Decoder call failed.. ....snip .... ############################################################### sub Dispach_Decoder_If_Any(){ # Call the appropriate decoder, depending on pkt type my ($NameRef, $index, $Parent_obj, $bufref) = @_; my $Decode_Subroutine = $NameRef->{$index}{DECODER}; if ($Decode_Subroutine){ # Decoder for this proto has been specified !!, call it &$Decode_Subroutine($Parent_obj, $bufref); return 0; # Found the decoder & called it }; return 1; # Did not find a decoder.. }
    As you can see, the subroutine called depends on the type of packet recieved. Hope this helps provide direction...
Re: How can I create a procedure
by aquarium (Curate) on Jun 10, 2003 at 01:56 UTC
    i think what you're after is a kind of perlish "ON $VAR GOTO" kind of thing (from BASIC language). build a hash of the text constants you're testing for as keys with values being references to anonymous subroutines. then it's a case of dereferencing the hash with $_ to execute the code. this will work as long as your current matching =~ is realy meant to be an eq operator. if it is meant to scan whole lines for the pattern than my suggestion will not work. good luck.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2022-05-20 10:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (73 votes). Check out past polls.

    Notices?