pickledegg has asked for the wisdom of the Perl Monks concerning the following question:

I have the following code, I want to run it 20 times in a loop and replace all the occurences of number'1's in the $hashRecordPtr's with the $count variable.
I'm stuck with the syntax for this.
Can someone please help me at all? It will save me a few hundred lines of code if I can understand this one. :-)
$count=0; while ($count < 20){ $count+=1; if ($$hashRecordPtr{'price_product1'} ne "" ) { print "<tr bgcolor=\"#EDEFF5\">"; if ($$hashRecordPtr{'connection1_description'} ne ""){ print<<"CONNECTION1"; <td valign="middle" align="center" width="78">$$hashRecordPtr{'connect +ion1_size1'}</td> CONNECTION1 } if ($$hashRecordPtr{'connection1_description'} ne ""){ print<<"CONNECTION2"; <td width="78" align="center" valign="middle">$$hashRecordPtr{'connect +ion2_size1'}</td> CONNECTION2 } print "<td width=\"78\" align=\"center\" valign=\"middle\">$$hashRecor +dPtr{'part_number1'}</td>"; if ($$hashRecordPtr{'part_reference1'} ne ""){ # ie its a pack not ind +. print<<"PARTREF"; <td width="78" align="center" valign="middle">$$hashRecordPtr{'part_re +ference1'}</td> PARTREF } if ($$hashRecordPtr{'pack_qty1'} > 2){ # ie its a pack not ind. print<<"PACK"; <td width="78" align="center" valign="middle">$$hashRecordPtr{'pack_qt +y1'}</td> PACK } print<<"HTML3"; <form name="prod_1" action="shoppingBasket2.cgi" method="post"> <td width="68" align="center" valign="middle">&pound;$$hashRecordPtr{' +price_product1'}</td> <td width="72" align="center"> <select name="order_qty"> <option value="1" selected>1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> <option value="10">10</option> </select> </td> <td width="98" align="center" bgcolor="#EDEFF5"><a href=\"javascript: +validateUserAdd(prod_1)\">Add To Basket</a></td> <input type="hidden" name="action" value="add"> <input type="hidden" name="product_id" value="$$hashRecordPtr{'product +_id'}"> <input type="hidden" name="product_details" value="$$hashRecordPtr{'sh +ort_details'} ($$hashRecordPtr{'code1'})"> <input type="hidden" name="code" value="$$hashRecordPtr{'code1'}"> </tr> </form> HTML3 } #cut out from here }

2006-06-13 Retitled by planetscape, as per Monastery guidelines

( keep:0 edit:7 reap:0 )

Original title: 'Interpolation'

Replies are listed 'Best First'.
Re: Interpolation in a hash key
by davorg (Chancellor) on Jun 13, 2006 at 15:51 UTC

    Do you mean something like this:

    $count+=1; if ($$hashRecordPtr{"price_product$count"} ne "" ) { print "<tr bgcolor=\"#EDEFF5\">"; if ($$hashRecordPtr{"connection${count}_description!} ne "") { print<<"CONNECTION1"; <td valign="middle" align="center" width="78">$$hashRecordPtr{"connect +ion${count}_size${count}"}</td> CONNECTION1 } # etc... }

    Note that in some cases I've had to use ${varname} rather than $varname in order to disambiguate the variable name from the rest of the string.

    For future reference, it's helpful if you create a short extract of code which demonstrates your problem. And if you clean your code (add indentation - stuff like that) so that it's easy to read.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Interpolation in a hash key
by ptum (Priest) on Jun 13, 2006 at 15:53 UTC

    So, every place you have a '1' in a hash key, simply substitute this (untested):

    ${count}

    For example:

    print<<"CONNECTION1"; <td valign="middle" align="center" width="78">$$hashRecordPtr{'connect +ion1_size1'} </td> CONNECTION1

    ... becomes ...

    print<<"CONNECTION1"; <td valign="middle" align="center" width="78">$$hashRecordPtr{'connect +ion${count}_size${count}'} </td> CONNECTION1

    That should do it, no? At a glance, it looks like all your $$hashRecordPtr references are inside double-quoted strings or HERE docs ...


    No good deed goes unpunished. -- (attributed to) Oscar Wilde
      Right, the bits in HERE docs, work fine as shown:
      print<<"CONNECTION2"; <td width="78" align="center" valign="middle">$$hashRecordPtr{"connect +ion2_size$count"}</td> CONNECTION2

      But its just these bits now:(just a standard double quoted print statement)
      print "<td width=\"78\" align=\"center\" valign=\"middle\">$$hashRecordPtr{'part_number1'}</td>"; Any ideas on this last bit?

      Nearly there, thanks guys.

        So, in this last case, you've got a double-quoted string with a single-quoted substring. Interpolation rules indicate that a variable name inside the overall double-quoted string will still be resolved, so this should work (although it makes me nervous with all those backslashed double-quote characters):

        print "<td width=\"78\" align=\"center\" valign=\"middle\">$$hashRecor +dPtr{'part_number${count}'}</td>";

        Of course, I could be wrong -- you should try it out. :) When in doubt, I use the curly braces, because I think it makes it more readable and it has saved my bacon once or twice.


        No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: Interpolation in a hash key
by philcrow (Priest) on Jun 13, 2006 at 15:40 UTC
    I don't think $$hashvar{key} interpolates correctly as a dereferencer inside double quotes. Try:
    $hashRecordPtr->{'product_id'}
    etc.

    Phil

      I don't think $$hashvar{key} interpolates correctly as a dereferencer inside double quotes

      Seems to work fine here. What happened when you tried it?

      $ perl -le '$h = {one=>1}; print "$$h{one}"' 1
      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        Sorry chaps, I don't follow what you are doing there at all. I'm quite a novice.

        If I have:

        $$hashRecordPtr{'connection1_size1'}
        if I set $count to 3
        how can I replace the size1 for size$count and get $$hashRecordPtr{'connection1_size3'} ? Do you see what I'm getting at? I know you do as you are way above me in the perl stakes, I just don't understand your answer, sorry.