[Denver-pm] Dispatch Lists?

Stuart Johnston saj at thecommune.net
Wed Apr 20 09:15:57 PDT 2016


I should clarify that you *can* use a regex as a hash key but you  
can't do a direct hash lookup based on the regex match so you'd still  
have to loop on the keys.

I also found an interesting solution in Perl Hacks, #98, if you happen  
to have a copy of that book. It uses Regexp::Assemble to combine  
pattern strings into a single regex. There is an example under  
"TRACKING REGULAR EXPRESSION MATCHES" in  
http://cpansearch.perl.org/src/RSAVAGE/Regexp-Assemble-0.37/README

I don't think it is really worth the trouble though. Even with 25  
patterns, you are not likely to see a significant difference in  
performance.


Quoting Stuart Johnston <saj at thecommune.net>:

> 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
>>>
>>
>
>
> _______________________________________________
> 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