[Denver-pm] Dispatch Lists?

Stuart Johnston saj at thecommune.net
Wed Apr 20 08:41:45 PDT 2016


You are right that it is not an improvement performance-wise. I'd say  
it is easier to read and maintain but I suppose that is subjective.  
The problem is that you can't use a regex as hash key so you can't use  
a traditional dispatch table lookup.

Also, you have to call the sub with the $Line param inside the loop,  
not in the hash.


Quoting "Robert L. Harris" <robert.l.harris at gmail.com>:

>    With the for-each walking through the dispatch list, that seems to just
> be about the equivalent of the chain of if then statements.  I started a
> simple tester and came up with this:
>
> Input Lines:
>    This is Line1.
>    This is Line3.
>    This is Line2.
>
> And this script:
>
> #!/usr/bin/perl -w
> $| = 1;
>
> use strict;
> use diagnostics;
>
> my $User=$ENV{"LOGNAME"};
>
> # GetOpt
> use vars qw( $opt_f );
> use Getopt::Mixed;
> Getopt::Mixed::getOptions("f=s ");
>
>
> my $Line;
> my @Lines;
> my %DispatchHash = (
>   qr/Line1/ => \&Line1($Line),
>   qr/Line2/ => \&Line2($Line),
>   qr/Line3/ => \&Line3($Line),
> );
>
>
> open(INPUT, "<$opt_f") || die "Can't open $opt_f $?\n";
> while(<INPUT>) {
>   chomp;
>   $Line=$_;
>   print "\$Line :$Line:\n";
> #  print "\$_ :$_:\n";
>
> #  push(@Lines, $_);
>
>   exit 0;
> }
>
> exit 0;
>
> #
> # Subs
> #
> sub Line1 {
>   my $InputLine=$_[0] ||= "Undefined1";
>   print "  Sub 1 :$InputLine:\n";
> }
>
> sub Line2 {
>   my $InputLine=$_[0] ||= "Undefined2";
>   print "  Sub 2 :$InputLine:\n";
> }
> sub Line3 {
>   my $InputLine=$_[0] ||= "Undefined3";
>   print "  Sub 3 :$InputLine:\n";
> }
>
>
> Unfortunately, my output looks like this:
> Sub 1 :Undefined1:
> Sub 2 :Undefined1:
> Sub 3 :Undefined1:
> $Line :Line1:
>
> Where it should be:
>
> This is Line1.
>    Sub 1 :This is Line1:
> This is Line3.
>    Sub 3 :This is Line3:
> This is Line2.
>    Sub 2 :This is Line2:
>
> Robert
>
> On Tue, Apr 19, 2016 at 5:25 PM Stuart A Johnston <saj at thecommune.net>
> wrote:
>
>> Here's a simple example. I've just used $ARGV[0] as the input but you
>> could add another loop for your multi-line input.
>>
>> #!/usr/bin/perl
>>
>> use strict;
>> use v5.10;
>>
>> sub sub_foo {
>>      say "foo: $_[0]";
>> }
>>
>> sub sub_bar {
>>      say "bar: $_[0]";
>> }
>>
>> my @dispatch = (
>>      [ qr/foo/, \&sub_foo ],
>>      [ qr/bar/, \&sub_bar ],
>> );
>>
>> foreach my $d (@dispatch) {
>>      my ($r, $sub) = @$d;
>>
>>      if ($ARGV[0] =~ $r) {
>>          $sub->($ARGV[0]);
>>          next;
>>      }
>> }
>>
>>
>>
>> On 04/19/2016 02:28 PM, Robert L. Harris wrote:
>> >
>> > Anyone have a straight forward script using dispatch lists?  I have one
>> > ( 4500 lines by now ) which effectively does this:
>> >
>> >  1. Open input file
>> >  2. while<input> {
>> >  3.      $Line=<INPUT>
>> >  4.      &Sub1("Line") if ( $Line =~ /<regex pattern 1>/ );
>> >  5.      &Sub2("Line") if ( $Line =~ /<regex pattern 2>/ );
>> >  6.      &Sub3("Line") if ( $Line =~ /<regex pattern 3>/ );
>> >  7.      ... about 25 patterns now ...
>> >  8. }
>> >
>> > Yeah, it's ugly, it started out as a 30 line data munger about 2.5 years
>> > ago and I'm looking to speed and clean it up.   Each Sub performs
>> > various actions based which can't be simplified or condensed more than
>> > they have.
>> >
>> >     I've created my DispatchHash for subs/patterns but I think I'm
>> > confusing myself on actually doing the match and dispatch including
>> > passing $Line to the sub.
>> >
>> > Any examples would be very welcome.
>> >
>> > Robert
>>
>> _______________________________________________
>> Denver-pm mailing list
>> Denver-pm at pm.org
>> http://mail.pm.org/mailman/listinfo/denver-pm
>>
>




More information about the Denver-pm mailing list