Professional Web Applications Themes

Variable name substitution (probably a question on references) - PERL Beginners

Hello list, I have the following code: $cardtot{vm} = $cardtot{4} + $cardtot{5}; $trans{vm} = $trans{4} + $trans{5}; $dsc_amt{vm} = $dsc_amt{4} + $dsc_amt{5}; $trf_amt{vm} = $trf_amt{4} + $trf_amt{5}; $cardtot{vm} = $cardtot{4} + $cardtot{5}; $as_tot{vm} = $as_tot{4} + $as_tot{5}; How can it be rewritten in a way similar to this?: foreach $var ("cardtot", "trans", "dsc_amt", "trf_amt", "cardtot", "as_tot") { $$var{vm} = $$var{4} + $$var{5}; } It does not work the way I wrote it, so I guess I am missing something really really minor... Thanks Peter...

  1. #1

    Default Variable name substitution (probably a question on references)

    Hello list,
    I have the following code:

    $cardtot{vm} = $cardtot{4} + $cardtot{5};
    $trans{vm} = $trans{4} + $trans{5};
    $dsc_amt{vm} = $dsc_amt{4} + $dsc_amt{5};
    $trf_amt{vm} = $trf_amt{4} + $trf_amt{5};
    $cardtot{vm} = $cardtot{4} + $cardtot{5};
    $as_tot{vm} = $as_tot{4} + $as_tot{5};

    How can it be rewritten in a way similar to this?:

    foreach $var ("cardtot", "trans", "dsc_amt", "trf_amt", "cardtot", "as_tot")
    {
    $$var{vm} = $$var{4} + $$var{5};
    }

    It does not work the way I wrote it, so I guess I am missing something
    really really minor...

    Thanks

    Peter
    Peter Guest

  2. #2

    Default Re: Variable name substitution (probably a question on references)

    From: Peter Rabbitson <us> 

    You should use a hash like this:

    $data{vm}{cardtot} = $data{4}{cardtot} + $data{5}{cardtot};
    $data{vm}{trans} = $data{4}{trans} + $data{5}{trans};
    ...
     

    Then it would be either:

    foreach my $var ("cardtot", "trans", "dsc_amt", "trf_amt",
    "cardtot", "as_tot") {
    $data{vm}{$var} = $data{4}{$var} + $data{5}{$var};
    }

    or (if you were sure you want to do this for all keys in
    $data{something} you could use just:

    foreach my $var (keys %{$data{4}}) {
    $data{vm}{$var} = $data{4}{$var} + $data{5}{$var};
    }

     

    There are two things you are missing.
    1) What does $$var{key} mean? Is it the same as ${$var}{key} or
    ${$var{key}}? That is should I first dereference and then look for a
    key or the other way around? To tell the truth I don't remember
    myself which one takes precedence so I would always use the {} to
    make sure it means what I wanted.

    2) You are trying to use so called "soft references". While it is
    possible (without "use strict") it's not a good idea. Please read:

    Why it's stupid to `use a variable as a variable name' - by M-J.
    Dominus
    http://www.plover.com/~mjd/perl/varvarname.html

    HTH, Jenda
    ===== cz === http://Jenda.Krynicky.cz =====
    When it comes to wine, women and song, wizards are allowed
    to get drunk and croon as much as they like.
    -- Terry Pratchett in Sourcery

    Jenda Guest

  3. #3

    Default Re: Variable name substitution (probably a question on references)

    Ok, I guess I need to bring more context to the stage. The script itself is
    a credit card batch pr, which guesses the card type by the first digit,
    and proceeds by calculating totals, transaction counts, transaction fees,
    and bunch of other relevant things. So ebverything in the script revolves
    around hashes with the same keys (3,4,5,6). However at the end after all
    calculations, because of a certain processing specifics, I need to produce a
    visa + master grand total, if the user requests it (web for input). So I
    dropped this snippet which simply creates an additional key vm, and adds
    everything together. In this light I hope you understand that doing
    this:$data{vm}{cardtot} = $data{4}{cardtot} + $data{5}{cardtot};
    would complicate code even more than just plain adding them together.
    Actually it is not that big of a deal since I am replacing 5 lines with 3,
    not that much of a speed increase. However for aesthetical reasons I wanted
    to know how to reference a variable, nevertheless in this case it is
    completely justified. Granted the code will instantly break if some
    doofus changes the names of the variables (the foreach list will be invalid
    thereafter) but hey - who asked him to mess with the names?

    As a matter of fact this probably was a bad example, I have another
    application for this that is way more elaborate to write line by line.
    Consider a cgi form that has a number of properties for a number of cards.
    For example transaction fee, fee assessment, discount rate for all visa,
    master, discover, amex. Say we name the Input types accordingly:

    6_pct - discover discount rate
    6_tfee - discover transaction fee
    6_fa - discover fee assessment
    5_pct - master card discount rate
    .....
    you get the idea. Now I want to read them in the script:

    $pct{6} = $form->param('6_pct');
    $tfee{6} = $form->param('6_tfee');
    $fa{6} = $form->param('6_fa');
    $pct{5} = $form->param('5_pct');
    .....
    Wow... what if I had 10 kinds of cards and 20 properties for each?

    However if I could define:
    %cards = (4,"Visa", 5,"MasterCard", 6,"Discover", 3,"AmEx");
    props = ("pct", "tfee", "fa");

    and than do:
    foreach $c (keys (%cards)) {
    foreach $p (props) {
    $($p){$c} = $form->param('($c)."_".($p)');
    }
    }

    (or at least something along the lines, since this is obviously more
    pseudo-langague than perl itself)

    Disregard how "stupid" it is to use a variable as a variable name - I don't
    see why it wouldn't be suitable above. Nevertheless I still don't know how
    to do it, although Mr. Dominus says it is fairly easy.

    So help me or shoot me :)


    P.S. I personally think use strict complains just way too much, to a point
    where you lose all the elegance that coding in perl calls for.

    Peter

    P.P.S. Sorry for the double message, did not reply to list.

    On Sun, Oct 10, 2004 at 09:34:13PM +0200, Jenda Krynicky wrote: 
    >
    > You should use a hash like this:
    >
    > $data{vm}{cardtot} = $data{4}{cardtot} + $data{5}{cardtot};
    > $data{vm}{trans} = $data{4}{trans} + $data{5}{trans};
    > ...

    >
    > Then it would be either:
    >
    > foreach my $var ("cardtot", "trans", "dsc_amt", "trf_amt",
    > "cardtot", "as_tot") {
    > $data{vm}{$var} = $data{4}{$var} + $data{5}{$var};
    > }
    >
    > or (if you were sure you want to do this for all keys in
    > $data{something} you could use just:
    >
    > foreach my $var (keys %{$data{4}}) {
    > $data{vm}{$var} = $data{4}{$var} + $data{5}{$var};
    > }
    >

    >
    > There are two things you are missing.
    > 1) What does $$var{key} mean? Is it the same as ${$var}{key} or
    > ${$var{key}}? That is should I first dereference and then look for a
    > key or the other way around? To tell the truth I don't remember
    > myself which one takes precedence so I would always use the {} to
    > make sure it means what I wanted.
    >
    > 2) You are trying to use so called "soft references". While it is
    > possible (without "use strict") it's not a good idea. Please read:
    >
    > Why it's stupid to `use a variable as a variable name' - by M-J.
    > Dominus
    > http://www.plover.com/~mjd/perl/varvarname.html
    >
    > HTH, Jenda
    > ===== cz === http://Jenda.Krynicky.cz =====
    > When it comes to wine, women and song, wizards are allowed
    > to get drunk and croon as much as they like.
    > -- Terry Pratchett in Sourcery
    >
    >
    > --
    > To unsubscribe, e-mail: org
    > For additional commands, e-mail: org
    > <http://learn.perl.org/> <http://learn.perl.org/first-response>
    >
    >[/ref]
    Peter Guest

  4. #4

    Default Re: Variable name substitution (probably a question on references)

    [ Please type your reply below the quoted part of the message you are
    replying to. Please only quote what's needed to give context. ]

    Peter Rabbitson wrote: 

    I disagree. Nothing you have said makes me understand why the advice
    Jenda gave you isn't applicable to your problem.

    <snip>
     

    I'm sure it would be possible, but it's considered bad coding practice
    when you easily can apply another technique.
     

    Since you

    1) are not very convincing in explaining why it would be necessary to
    use soft references, and

    2) argue against enabling strictures, and with that make Perl help you
    get your code right,

    you'll find that few people here are inclined to help you.

    (You can always read about soft references in "perldoc perlref".)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Guest

  5. #5

    Default Re: Variable name substitution (probably a question on references)

    From: Peter Rabbitson <us> 

    Change that to
    ${$p}{$c} = $form->param($c."_".$p);
    and it will be runnable (albait not perfect) code.
     

    It would still IMHO be much better to do something like:

    %cards = (
    4 => {name => 'Visa'},
    5 => {name => 'MasterCard'},
    6 => {name => 'Discover'},
    3 => {name => 'AmEx'},
    );

    foreach my $cardid (keys %cards) {
    foreach my $property (props) {
    $data{$cardid}{$property} = $form->param($cardid."_".$property);
    }
    }

    This way you have just one variable holding all the data, not several
    separate variables. So you can pass the whole data between functions
    easily, you can keep several separate data structures holding
    different data ...

    It's probably not worth the effort to go rewrite the whole script,
    but believe me GLOBAL VARIABLES ARE BAD. And soft references are even
    worse.

    You may be able to keep track of everything if you are writing a
    single small script, but once you start on something bigger globals
    and soft references will surely bite you.

    You say "the code will instantly break if some
    doofus changes the names of the variables", yes that's quite
    possible. And the doofus may easily be you two months later, after
    you've forgotten the details of the implementation of this stuff.

    Jenda


    ===== cz === http://Jenda.Krynicky.cz =====
    When it comes to wine, women and song, wizards are allowed
    to get drunk and croon as much as they like.
    -- Terry Pratchett in Sourcery

    Jenda Guest

  6. #6

    Default Re: Variable name substitution (probably a question on references)

    > It would still IMHO be much better to do something like: 

    Now this is something I like :) As a matter of fact instead of using $data I
    can re-use $cards, so I have a single unified structure, hodling names,
    properties, totals and other things, all addressable by the primary hash key
    $cardid. I really like it :)

    Thanks

    Peter




    Peter Guest

  7. #7

    Default Re: Variable name substitution (probably a question on references)

    > Since you 

    If soft references were so evil as you claim, probably they would not be a
    part of Perl to begin with... imho of course.
    Peter Guest

  8. #8

    Default Re: Variable name substitution (probably a question on references)

    Peter Rabbitson wrote: 
    >
    > If soft references were so evil as you claim, probably they would
    > not be a part of Perl to begin with... imho of course.[/ref]

    Actually, I didn't say anything about their degree of evilness. Others
    can elaborate on that much better than I would be able to.

    I just said that soft references

    1) are considered something that typically should be avoided,
    2) can almost always be easily replaced with a solution involving a
    hash, and
    3) you did not show why there would be a need to use soft references
    in this case.

    Seems as if Jenda has convinced you now, btw.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Guest

Similar Threads

  1. #include substitution question
    By difoggio in forum Macromedia Flash Data Integration
    Replies: 1
    Last Post: March 5th, 04:33 AM
  2. backtick variable substitution
    By Hdan in forum PERL Beginners
    Replies: 6
    Last Post: April 22nd, 07:51 PM
  3. #22237 [Com]: PHP crashes when class references property using variable variable
    By rep at devdomain dot com in forum PHP Development
    Replies: 0
    Last Post: September 29th, 11:34 AM
  4. Substitution Question
    By Mike Flannigan in forum PERL Miscellaneous
    Replies: 8
    Last Post: August 2nd, 05:42 PM
  5. s/// substitution with capture / memory in a variable
    By Purl Gurl in forum PERL Miscellaneous
    Replies: 21
    Last Post: June 26th, 04:00 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139