Reducing amount of repetative code

Discussion in 'Perl Misc' started by Brad, Oct 27, 2004.

  1. Brad

    Brad Guest

    Hello,

    I'm trying to reduce some code which repeats itself
    in my program, but I can't find a clever way to do it.
    I'm parsing a file which looks like this:

    ____
    ; Key1: Value1
    ; Key2: Value2 22:33
    ; Key3: Value3

    and so on
    ____

    The "\d\d:\d\d" with Key2 will always appear.

    I'm parsing this file by using this loop:

    _____
    while (<>)
    {
    if (/^;\s+Key1: (.*)/)
    {
    $object->method('a string connect with Key1' => $1);
    }

    if (/^;\s+Key2: (.*) \d\d:\d\d/)
    {
    $object->method('a string connect with Key2' => $1);
    }

    if (/^;\s+Key3: (.*)/)
    {
    $object->method('a string connect with Key3' => $1);
    }
    }
    _____


    Each time I find a line which matches the regex I call a method
    on an object (neither of which are relevant) with two arguments
    based on the result of the match.

    Can anyone think of a way to reduce the amount of code here?
    An awful lot of it is repeated.


    Thanks very much,
    Brad
    Brad, Oct 27, 2004
    #1
    1. Advertising

  2. (Brad) writes:
    >
    > I'm trying to reduce some code which repeats itself
    > in my program, but I can't find a clever way to do it.
    > I'm parsing a file which looks like this:


    One way which comes to mind is to write some code that generates
    the stereotypical code. A good programming language to use for
    program-generating programs is of course Perl.

    (If you have any reason to modify the generated code by hand after
    it's been generated, discrepancies will appear between the true source
    and the modified generated code, but that's a subject for another
    discussion forum.)
    Arndt Jonasson, Oct 27, 2004
    #2
    1. Advertising

  3. Brad wrote:
    > Hello,
    >
    > I'm trying to reduce some code which repeats itself
    > in my program, but I can't find a clever way to do it.
    > I'm parsing a file which looks like this:
    >
    > ____
    > ; Key1: Value1
    > ; Key2: Value2 22:33
    > ; Key3: Value3
    >
    > and so on
    > ____
    >
    > The "\d\d:\d\d" with Key2 will always appear.
    >
    > I'm parsing this file by using this loop:
    >
    > _____
    > while (<>)
    > {
    > if (/^;\s+Key1: (.*)/)
    > {
    > $object->method('a string connect with Key1' => $1);
    > }
    >
    > if (/^;\s+Key2: (.*) \d\d:\d\d/)
    > {
    > $object->method('a string connect with Key2' => $1);
    > }
    >
    > if (/^;\s+Key3: (.*)/)
    > {
    > $object->method('a string connect with Key3' => $1);
    > }
    > }
    > _____
    >
    >
    > Each time I find a line which matches the regex I call a method
    > on an object (neither of which are relevant) with two arguments
    > based on the result of the match.
    >
    > Can anyone think of a way to reduce the amount of code here?
    > An awful lot of it is repeated.


    Use an array of hashes:

    my @table = (
    { Key => "Key1", Postfix => '' },
    { Key => "Key2", Postfix => ' \d\d:\d\d' },
    { Key => "Key3", Postfix => '' }
    );
    while (my $l = <>) {
    foreach (@table) {
    my $key = ${$_}{Key};
    my $postfix = ${$_}{Postfix};
    if ($l =~ m/^;\s+$key: (.*)$postfix/) {
    $object->method("a string connect with $key" => $1);
    last;
    }
    }
    }

    Not much less code, but little repetition and easily expandable.

    --
    Josef Möllers (Pinguinpfleger bei FSC)
    If failure had no penalty success would not be a prize
    -- T. Pratchett
    Josef Moellers, Oct 27, 2004
    #3
  4. Brad

    Anno Siegel Guest

    Brad <> wrote in comp.lang.perl.misc:
    > Hello,
    >
    > I'm trying to reduce some code which repeats itself
    > in my program, but I can't find a clever way to do it.
    > I'm parsing a file which looks like this:
    >
    > ____
    > ; Key1: Value1
    > ; Key2: Value2 22:33
    > ; Key3: Value3
    >
    > and so on
    > ____
    >
    > The "\d\d:\d\d" with Key2 will always appear.


    Then why try to match it?

    > I'm parsing this file by using this loop:
    >
    > _____
    > while (<>)
    > {
    > if (/^;\s+Key1: (.*)/)
    > {
    > $object->method('a string connect with Key1' => $1);
    > }
    >
    > if (/^;\s+Key2: (.*) \d\d:\d\d/)
    > {
    > $object->method('a string connect with Key2' => $1);
    > }
    >
    > if (/^;\s+Key3: (.*)/)
    > {
    > $object->method('a string connect with Key3' => $1);
    > }
    > }
    > _____
    >
    >
    > Each time I find a line which matches the regex I call a method
    > on an object (neither of which are relevant) with two arguments
    > based on the result of the match.
    >
    > Can anyone think of a way to reduce the amount of code here?
    > An awful lot of it is repeated.


    Sure. The price is a more complex regex, because it now has to
    cover all the alternatives. Untested:

    /^;\s+Key(\d): (.*?)(?: \d\d:\d\d)?$/ and
    print "a string connected with Key$1 => $2\n" while <>;

    Anno
    Anno Siegel, Oct 27, 2004
    #4
  5. Brad

    Anno Siegel Guest

    Brad <> wrote in comp.lang.perl.misc:
    > Hello,
    >
    > I'm trying to reduce some code which repeats itself
    > in my program, but I can't find a clever way to do it.
    > I'm parsing a file which looks like this:
    >
    > ____
    > ; Key1: Value1
    > ; Key2: Value2 22:33
    > ; Key3: Value3
    >
    > and so on
    > ____
    >
    > The "\d\d:\d\d" with Key2 will always appear.
    >
    > I'm parsing this file by using this loop:
    >
    > _____
    > while (<>)
    > {
    > if (/^;\s+Key1: (.*)/)
    > {
    > $object->method('a string connect with Key1' => $1);
    > }
    >
    > if (/^;\s+Key2: (.*) \d\d:\d\d/)
    > {
    > $object->method('a string connect with Key2' => $1);
    > }
    >
    > if (/^;\s+Key3: (.*)/)
    > {
    > $object->method('a string connect with Key3' => $1);
    > }
    > }
    > _____
    >
    >
    > Each time I find a line which matches the regex I call a method
    > on an object (neither of which are relevant) with two arguments
    > based on the result of the match.
    >
    > Can anyone think of a way to reduce the amount of code here?
    > An awful lot of it is repeated.


    Sure. The price is a more complex regex, because it now has to
    cover all the alternatives. Untested:

    /^;\s+Key(\d): (.*?)(?: \d\d:\d\d)?$/ and
    print "a string connected with Key$1 => $2\n" while <>;

    Anno
    Anno Siegel, Oct 27, 2004
    #5
  6. Brad <> wrote:

    > I'm trying to reduce some code which repeats itself
    > in my program, but I can't find a clever way to do it.



    Look-ahead can be used for that.


    > if (/^;\s+Key1: (.*)/)


    > $object->method('a string connect with Key1' => $1);


    > if (/^;\s+Key2: (.*) \d\d:\d\d/)


    > if (/^;\s+Key3: (.*)/)




    > Can anyone think of a way to reduce the amount of code here?



    You can replace all 3 if's with this one (untested):

    if ( /^;\s+(Key[123]): (.*?)(?=\d\d:\d\d|$)/ ) {
    $object->method("a string connect with $1" => $2);
    }


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Oct 27, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex
    Replies:
    4
    Views:
    405
    john gresh
    Apr 7, 2006
  2. Salvador I. Ducros

    STL & reducing code bloat

    Salvador I. Ducros, Jul 28, 2003, in forum: C++
    Replies:
    5
    Views:
    1,565
    Howard Hinnant
    Aug 5, 2003
  3. JellyBum

    Reducing Repeated code for arrays

    JellyBum, May 3, 2004, in forum: C Programming
    Replies:
    2
    Views:
    258
    Mike Wahler
    May 3, 2004
  4. Rich
    Replies:
    1
    Views:
    674
    Francis Avila
    Dec 23, 2003
  5. Ralf W. Grosse-Kunstleve
    Replies:
    16
    Views:
    559
    Lonnie Princehouse
    Jul 11, 2005
Loading...

Share This Page