formatting a number of elsif statements

Discussion in 'Perl Misc' started by ccc31807, Jul 5, 2009.

  1. ccc31807

    ccc31807 Guest

    Using 5.8 in a web app, I have about 18 elsif statements which look
    similar to this:

    elsif ($action eq 'AddAttorney')
    {
    print qq(<h4>Add Attorney</h4>);
    HTML::add_professional($oprid, $role, 'Attorney');
    HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);
    }
    elsif($action eq 'AddInsurer')
    ....

    I now fact the prospect of adding some more, hopefully not many, but
    I'm getting tired of looking at all of this.

    Is there any way to mimic the case/switch statement? Ideally, I'd like
    to have just the matching term for each block, like this:

    'AddAttorney'
    print qq(<h4>Add Attorney</h4>);
    HTML::add_professional($oprid, $role, 'Attorney');
    HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);
    'AddInsurer'
    ...

    It's not critical, but I'm just getting tired of looking at all the
    repetition.

    CC.
     
    ccc31807, Jul 5, 2009
    #1
    1. Advertising

  2. ccc31807 <> wrote:
    >Using 5.8 in a web app, I have about 18 elsif statements which look
    >similar to this:
    >
    >elsif ($action eq 'AddAttorney')
    >{
    > print qq(<h4>Add Attorney</h4>);
    > HTML::add_professional($oprid, $role, 'Attorney');
    > HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);
    >}
    >elsif($action eq 'AddInsurer')
    >...
    >
    >I now fact the prospect of adding some more, hopefully not many, but
    >I'm getting tired of looking at all of this.

    [...]
    >It's not critical, but I'm just getting tired of looking at all the
    >repetition.


    Yeah, repetition is what computers are good at.

    Step 1: identify which pieces of your repetitions are constant and which
    pieces change. I can only guess but it appears like

    print qq(<h4>Add #####</h4>);
    HTML::add_professional($oprid, $role, '#####');
    HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);

    is the constant part with the variable/changing part blocked out by
    #####.

    Step 2: Find a way to compute the variable parts from a suitable
    parameter. In this case you got $action as the parameter and you want to
    map it into a simple string. A hash is an ideal and very simple
    datastructure for that.

    my %param= {'AddAttorney' -> 'Attorney',
    'AddInsurer' -> 'Insurer',
    .....
    }

    Step 3: Replace the placeholder for the variable part ##### with actual
    parameterized code that retrieves the variable part at runtime:

    print qq(<h4>Add $param{$action}</h4>);
    HTML::add_professional($oprid, $role, $param{$action});
    HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);

    That should do it.

    jue
     
    Jürgen Exner, Jul 5, 2009
    #2
    1. Advertising

  3. ccc31807

    ccc31807 Guest

    Thanks, Ben.

    I went ahead and bit the bullet.

    I wrote a function that takes, among other arguments, an entity type
    and an action type, so now I just call one procedure. It did require a
    translation table as you suggested (which I hard coded for now but
    will probably put into a database), but that's a lot easier on the
    eyes than a couple hundred lines of elsif statements.

    As a bonus, I am able to abstract my SQL as well. In my code, I have
    procedures to:
    - add
    - insert
    - view all
    - view one
    - edit
    - update
    - delete

    for a dozen different categories, Insurers, Employers, Attorneys,
    Agents, etc. It started out pretty small, but man, scaling becomes an
    issue when different people start adding their wants to the list!
    Saying, 'Yes, I can do a little app to track the players,' turns into
    a Sunday at the keyboard when the office gets a crack at it.

    On Jul 5, 4:00 pm, Ben Morrow <> wrote:
    > That's a good suggestion. Another might be to use a hash table of
    > subrefs, like
    >
    >     my %dispatch = (
    >         AddAttorney => sub {
    >             print qq(<h4>Add Attorney</h4>);
    >             HTML::add_professional($oprid, $role, 'Attorney');
    >             HTML::print_button('setup.cgi','Return To Setup',
    >                 $oprid, $role);
    >         },
    >         AddInsurer => sub { ... },
    >     );
    >
    >     $dispatch{$action}();
    >
    > or even a class with a method for each action.


    One of these days, I'm going to learn OO Perl. I've got two books on
    my reading list, 'Object Oriented Perl' and 'Higher Order Perl', but
    I've never been able timewise to do more than just browse through
    them.

    Thanks for your suggestion.

    CC
     
    ccc31807, Jul 5, 2009
    #3
  4. ccc31807

    Guest

    On Sun, 5 Jul 2009 12:07:41 -0700 (PDT), ccc31807 <> wrote:

    >Using 5.8 in a web app, I have about 18 elsif statements which look
    >similar to this:
    >
    >elsif ($action eq 'AddAttorney')
    >{
    > print qq(<h4>Add Attorney</h4>);
    > HTML::add_professional($oprid, $role, 'Attorney');
    > HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);
    >}
    >elsif($action eq 'AddInsurer')
    >...
    >
    >I now fact the prospect of adding some more, hopefully not many, but
    >I'm getting tired of looking at all of this.
    >
    >Is there any way to mimic the case/switch statement? Ideally, I'd like
    >to have just the matching term for each block, like this:
    >
    >'AddAttorney'
    > print qq(<h4>Add Attorney</h4>);
    > HTML::add_professional($oprid, $role, 'Attorney');
    > HTML::print_button('setup.cgi','Return To Setup',$oprid, $role);
    >'AddInsurer'
    > ...
    >
    >It's not critical, but I'm just getting tired of looking at all the
    >repetition.
    >
    >CC.


    I haven't read any other reply's but I would bet there is that
    switch/case mimic in Perl 5.10

    Since you bring up the C switch/case construct, lets talk about
    what that really is and how much you should really worry about it.

    Forgetting languages except assembly for the moment. How many branch
    instructions do you think there are, and how many language intrinsics
    do you think you can make with them?

    Lets get at least a little bit real. Case/Switch was added to C for only one
    reason, as a pass through when conditions overlapp. It still uses the basic
    assembly branches but it is still a compound.

    Looks are in the eye of the beholder. You obviously never programmed in assembly.

    -sln
     
    , Jul 6, 2009
    #4
  5. On Mon, 06 Jul 2009 12:55:43 -0700, sln wrote:

    > Lets get at least a little bit real. Case/Switch was added to C for only
    > one reason, as a pass through when conditions overlapp. It still uses
    > the basic assembly branches but it is still a compound.


    Another reason is that it can often be implemented using a branch table.

    >
    > Looks are in the eye of the beholder. You obviously never programmed in
    > assembly.
    >


    And obviously, you didn't look enough at disassembled C. :)

    M4
     
    Martijn Lievaart, Jul 6, 2009
    #5
  6. ccc31807

    Guest

    On Mon, 6 Jul 2009 22:27:27 +0200, Martijn Lievaart <> wrote:

    >On Mon, 06 Jul 2009 12:55:43 -0700, sln wrote:
    >
    >> Lets get at least a little bit real. Case/Switch was added to C for only
    >> one reason, as a pass through when conditions overlapp. It still uses
    >> the basic assembly branches but it is still a compound.

    >
    >Another reason is that it can often be implemented using a branch table.
    >

    [snip]
    >
    >M4


    I'm sorry, I missed that branch table instruction in the op code list (rst?).
    Perhaps you should dissasemble your assembler.

    -sln
     
    , Jul 6, 2009
    #6
  7. ccc31807

    ccc31807 Guest

    On Jul 6, 3:55 pm, wrote:
    > I haven't read any other reply's but I would bet there is that
    > switch/case mimic in Perl 5.10


    Yes.

    > Forgetting languages except assembly for the moment. How many branch
    > instructions do you think there are, and how many language intrinsics
    > do you think you can make with them?


    As you say, looks are in the eye of the beholder. In this case, you
    can see the logic in two ways. The first way is how I started out, by
    switching based on the type (Agent, Attorney, Employer, etc) and task
    (insert, update, delete, select). The second way is how I ended up, in
    a more OO style, trashing all the branches and replacing them with a
    generic function, like this:
    $hashref = do_it($type, $task);

    > Lets get at least a little bit real. Case/Switch was added to C for only one
    > reason, as a pass through when conditions overlapp. It still uses the basic
    > assembly branches but it is still a compound.


    I don't know about that. I had six months of assembly years ago and
    can't remember much about it.

    > Looks are in the eye of the beholder. You obviously never programmed in assembly.


    Yes, and yes.

    CC
     
    ccc31807, Jul 6, 2009
    #7
  8. ccc31807

    Guest

    On Mon, 6 Jul 2009 14:03:06 -0700 (PDT), ccc31807 <> wrote:

    >On Jul 6, 3:55 pm, wrote:

    <snip>
    >> Lets get at least a little bit real. Case/Switch was added to C for only one
    >> reason, as a pass through when conditions overlapp. It still uses the basic
    >> assembly branches but it is still a compound.

    >
    >I don't know about that. I had six months of assembly years ago and
    >can't remember much about it.
    >
    >> Looks are in the eye of the beholder. You obviously never programmed in assembly.

    >
    >Yes, and yes.
    >
    >CC


    I started out doing assembly on the z80a actually, before assemblers. Did alot of
    hand written code (to be machine input later), later looked at all the 8080/286/386/486,
    and assemblers (Intel mostly), then reviewed the Motorolla, then some other cpu's, which
    were almost identical in basic functionality.

    There is only jump relative and its conditional flavors, or jump absolute, and restart (rst)
    which is a table absolute jump commonly used to boot (absolute code) systems or in response
    to intterrupts (hardware reset), not used by languages.

    So there you have it, jump relative (with conditional) or jump absolute.

    Remember any of that?

    -sln
     
    , Jul 6, 2009
    #8
  9. ccc31807

    Guest

    On Mon, 06 Jul 2009 14:27:17 -0700, wrote:

    >On Mon, 6 Jul 2009 14:03:06 -0700 (PDT), ccc31807 <> wrote:
    >
    >>On Jul 6, 3:55 pm, wrote:

    >So there you have it, jump relative (with conditional) or jump absolute.

    Iiether can be conditional (relative or absolute).
    I just never found the TABLE op code, u know. Assemblers have indirection
    with locations, but the raw code is jumps, assemblers just embelish and translate
    to simple op jumps. There is no construct more complex to the cpu no matter what
    you think.

    This is a prime example of learning before leaping.

    -sln
     
    , Jul 6, 2009
    #9
  10. On Mon, 06 Jul 2009 13:32:51 -0700, sln wrote:

    >>Another reason is that it can often be implemented using a branch table.
    >>

    > [snip]
    >>
    >>M4

    >
    > I'm sorry, I missed that branch table instruction in the op code list
    > (rst?). Perhaps you should dissasemble your assembler.


    It's called an indirect jump. Sorry, but you really should take some
    education here, these are rather basic concepts.

    M4
     
    Martijn Lievaart, Jul 9, 2009
    #10
  11. ccc31807

    Guest

    On Thu, 9 Jul 2009 07:18:09 +0200, Martijn Lievaart <> wrote:

    >On Mon, 06 Jul 2009 13:32:51 -0700, sln wrote:
    >
    >>>Another reason is that it can often be implemented using a branch table.
    >>>

    >> [snip]
    >>>
    >>>M4

    >>
    >> I'm sorry, I missed that branch table instruction in the op code list
    >> (rst?). Perhaps you should dissasemble your assembler.

    >
    >It's called an indirect jump. Sorry, but you really should take some
    >education here, these are rather basic concepts.
    >
    >M4


    I don't know if there is an indirect jump op code. The accumulator may contain
    an address, and there may be a jump to where it points. Any kind of indirection
    involves a 2-step loading of a fixed address into a register, getting its contents
    then loading it into another register (with a possible addition).

    Jumping to a fixed location is more than four times quicker, as is the case of
    if/then/else.

    I'm sorry, machine cycles (if there is a relative jump op) don't change. The math
    is still the same.

    Back in the days of 'resident' dos programs it made a difference, today it still
    makes a difference.

    Surely, real-time.

    -sln
     
    , Jul 9, 2009
    #11
  12. ccc31807

    Guest

    On Thu, 09 Jul 2009 14:39:54 -0700, wrote:

    >On Thu, 9 Jul 2009 07:18:09 +0200, Martijn Lievaart <> wrote:
    >
    >>On Mon, 06 Jul 2009 13:32:51 -0700, sln wrote:
    >>
    >>>>Another reason is that it can often be implemented using a branch table.

    <snip>

    It cannot be! Comparisons on each case must be made, there is no single leaf.

    -sln
     
    , Jul 9, 2009
    #12
  13. [OT] Re: formatting a number of elsif statements

    On Thu, 09 Jul 2009 15:18:50 -0700, sln wrote:

    > On Thu, 09 Jul 2009 14:39:54 -0700, wrote:
    >
    >>On Thu, 9 Jul 2009 07:18:09 +0200, Martijn Lievaart <>
    >>wrote:
    >>
    >>>On Mon, 06 Jul 2009 13:32:51 -0700, sln wrote:
    >>>
    >>>>>Another reason is that it can often be implemented using a branch
    >>>>>table.

    > <snip>
    >
    > It cannot be! Comparisons on each case must be made, there is no single
    > leaf.


    It's rather simple, something like:

    switch (x) {
    case 1:
    f1();
    break;
    case 2:
    f2();
    break;
    ..
    ..
    ..
    case <n>:
    f<n>;
    break;
    }

    might be implemented (in pseudo assembler)

    ..data
    label branchtable
    Lcont
    L1
    L2
    ..
    ..
    ..
    L<n>

    ..code

    ; value is in accumulator X

    CMP X,<n>
    JGT Lcont
    JMP branchtable[x]
    L1:
    call f1
    JMP Lcont
    L2:
    call f2
    JMP Lcont
    ..
    ..
    ..
    L<n>:
    CALL f<n>
    Lcont:

    Again, this is pretty basic stuff, consult a good book on compilers.

    M4
     
    Martijn Lievaart, Jul 10, 2009
    #13
  14. ccc31807

    Guest

    Re: [OT] Re: formatting a number of elsif statements

    On Fri, 10 Jul 2009 22:32:35 +0200, Martijn Lievaart <> wrote:

    >On Thu, 09 Jul 2009 15:18:50 -0700, sln wrote:
    >
    >> On Thu, 09 Jul 2009 14:39:54 -0700, wrote:
    >>
    >>>On Thu, 9 Jul 2009 07:18:09 +0200, Martijn Lievaart <>
    >>>wrote:
    >>>
    >>>>On Mon, 06 Jul 2009 13:32:51 -0700, sln wrote:
    >>>>
    >>>>>>Another reason is that it can often be implemented using a branch
    >>>>>>table.

    >> <snip>
    >>
    >> It cannot be! Comparisons on each case must be made, there is no single
    >> leaf.

    >
    >It's rather simple, something like:
    >
    >switch (x) {
    > case 1:
    > f1();
    > break;
    > case 2:
    > f2();
    > break;
    >.
    >.
    >.
    > case <n>:
    > f<n>;
    > break;
    >}
    >
    >might be implemented (in pseudo assembler)
    >
    >.data
    >label branchtable
    >Lcont
    >L1
    >L2
    >.
    >.
    >.
    >L<n>
    >
    >.code
    >
    >; value is in accumulator X
    >
    >CMP X,<n>
    >JGT Lcont
    >JMP branchtable[x]
    >L1:
    >call f1
    >JMP Lcont
    >L2:
    >call f2
    >JMP Lcont
    >.
    >.
    >.
    >L<n>:
    >CALL f<n>
    >Lcont:
    >
    >Again, this is pretty basic stuff, consult a good book on compilers.
    >
    >M4


    Looks pretty basic. A single comparison of a value in a range (seemingly continuous)
    that is the offset into a table (data) that hold the absolute jump addresses.

    Its the going from here:
    CMP X,<n>
    to here:
    JMP branchtable[x]

    thats got me. I haven't done assembly in a long time, if I were paid to do it I would.
    I do remember doing thousands and thousands of hand written machine code lines before assemblers.
    Mostly 8-bit. Then some stuff with Masm 5.1 and eproms for a while. Mostly frogotten.

    Thats why I look at your pseudo assembler and wonder if there is a hidden meaning in CMP X,<n>
    the '<n>' especially. It might be benificial to view dissasembly (preferably after c2 pass)
    to see if they actually invented some new 'op' code or something that would be a miracle and
    shorten your assembly down to what appears to be really only a very few machine cycles.

    So that this:

    if (x == 1)
    f1();
    else
    CMP X,1
    JRNE 16
    call f1
    JMP Lcont
    if (x == 2)
    f2();
    else
    CMP X,2
    JRNE 16
    call f2
    JMP Lcont
    ....
    Lcont:

    will forever be looked on as bad code as will this:

    switch (x) {
    case 1:
    f1();
    case 2:
    case 109827:
    fall();
    break;
    }

    -sln
     
    , Jul 12, 2009
    #14
    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. unexpected

    Avoiding if..elsif statements

    unexpected, Aug 25, 2006, in forum: Python
    Replies:
    11
    Views:
    601
    Tal Einat
    Aug 27, 2006
  2. michaelb
    Replies:
    0
    Views:
    484
    michaelb
    Sep 30, 2006
  3. karlwijk

    if/elsif problem

    karlwijk, Apr 16, 2007, in forum: VHDL
    Replies:
    3
    Views:
    686
    quantum_dot
    Apr 18, 2007
  4. palo
    Replies:
    0
    Views:
    1,325
  5. Brad Smallridge

    one hot machine without elsif

    Brad Smallridge, Feb 16, 2009, in forum: VHDL
    Replies:
    10
    Views:
    811
Loading...

Share This Page