[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