Problem with indirect variables

Discussion in 'Perl Misc' started by Marshall Dudley, Mar 22, 2007.

  1. Why can I not get the second variable to print it's value in the
    following code?

    $test = "Test String";
    $form_data{'test'} = "form data variable";
    foreach $string (test,"form_data{'test'}") {
    print "$string = $$string\n";
    }

    perl test.pl
    test = Test String
    form_data{'test'} =

    Thanks,

    Marshall
     
    Marshall Dudley, Mar 22, 2007
    #1
    1. Advertising

  2. On Mar 22, 5:08 pm, Marshall Dudley <> wrote:
    > Why can I not get the second variable to print it's value in the
    > following code?


    Because expanding a symbolic reference just does a single look up in
    the package symbol table. It does not evaluate an arbitrary string as
    Perl code.

    > $test = "Test String";
    > $form_data{'test'} = "form data variable";
    > foreach $string (test,"form_data{'test'}") {
    > print "$string = $$string\n";


    You are telling perl to look for single scalar package variable the
    name of which is literally the string "form_data{'test'}". That is to
    say there literally are braces and quote characters in the _name_ of
    the scalar variable. I suspect you wanted to get at the value in the
    hash %form_data associated with the key 'test'.

    I'm now going to show you how you'd make Perl do what you thought
    would happen

    Do not actually do it.

    To do so would be stupid**100.

    Let me say that again, to actually do this would be stupid**100.

    Is that clear?

    OK here goes.

    print "$string = ",eval( '$' . $string), "\n"; # Don't actually
    do this!

    Now, what was it you really wanted to do?
     
    Brian McCauley, Mar 22, 2007
    #2
    1. Advertising

  3. Marshall Dudley wrote:
    > Why can I not get the second variable to print it's value in the
    > following code?
    >
    > $test = "Test String";
    > $form_data{'test'} = "form data variable";
    > foreach $string (test,"form_data{'test'}") {
    > print "$string = $$string\n";



    Had you enabled warnings then perl would have told you:
    Use of uninitialized value in concatenation (.) or string at ....

    In short: You do not have a variable that is named
    form_data{'test'}

    Besides that what you are trying to do is known as symbolic references and
    it is A BAD IDEA!
    See the FAQ "How can I use a variable as a variable name?" for details about
    why and what to use instead.

    jue
     
    Jürgen Exner, Mar 22, 2007
    #3
  4. Jürgen Exner wrote:
    > Marshall Dudley wrote:
    >
    >> Why can I not get the second variable to print it's value in the
    >> following code?
    >>
    >> $test = "Test String";
    >> $form_data{'test'} = "form data variable";
    >> foreach $string (test,"form_data{'test'}") {
    >> print "$string = $$string\n";
    >>

    >
    >
    > Had you enabled warnings then perl would have told you:
    > Use of uninitialized value in concatenation (.) or string at ....
    >
    > In short: You do not have a variable that is named
    > form_data{'test'}
    >
    > Besides that what you are trying to do is known as symbolic references and
    > it is A BAD IDEA!
    > See the FAQ "How can I use a variable as a variable name?" for details about
    > why and what to use instead.
    >
    > jue
    >
    >
    >

    I looked at the faq, but did not really see anything applicable. Here
    is the deal. I have been notified that I have clean up all my variables
    that print to not allow any <, >, ', &, ( or ) in them to prevent cross
    platform scripting hacking. So I have a confirmation page that prints
    dozens of variables that are global variables, most of which are form
    variables from the form input. So I wanted to have a list of the
    variable names, and use one small section of code to do the
    substitutions, like this:

    foreach my $variable
    (customer_number,"form_data{'Ecom_BillTo_Postal_Name_First'}","form_data{'Ecom_BillTo_Postal_Name_Last'}",
    "form_data{'Ecom_BillTo_Company'}","form_data{'Ecom_BillTo_Postal_Street_Line1'}","form_data{'Ecom_BillTo_Postal_City'}",
    "form_data{'Ecom_BillTo_Postal_StateProv'}","form_data{'Ecom_BillTo_PostalCode'}","bill_country,form_data{'Ecom_BillTo_Telecom_Phon
    "form_data{'Ecom_BillTo_Online_Email'}","form_data{'Ecom_ShipTo_Postal_Name_First'}","form_data{'Ecom_ShipTo_Postal_Name_Last'}",
    "form_data{'Ecom_ShipTo_Postal_Street_Line1'}","form_data{'Ecom_ShipTo_Postal_City'}","ship_country","form_data{'PO'}",
    "$form_data{'Comments'}") {
    $$variable =~ s/\</\&lt;/g;
    $$variable =~ s/\>/\&gt;/g;
    $$variable =~ s/\(/\(/g;
    $$variable =~ s/\)/\)/g;
    $$variable =~ s/\'/\'/g;
    }

    If I inline it, I end up with 5*18 or 90 lines of code in what should be
    able to be done in 6 or 7.

    Thanks,

    Marshall
     
    Marshall Dudley, Mar 22, 2007
    #4
  5. Marshall Dudley

    Uri Guttman Guest

    >>>>> "MD" == Marshall Dudley <> writes:

    MD> I looked at the faq, but did not really see anything applicable. Here
    MD> is the deal. I have been notified that I have clean up all my
    MD> variables that print to not allow any <, >, ', &, ( or ) in them to
    MD> prevent cross platform scripting hacking. So I have a confirmation
    MD> page that prints dozens of variables that are global variables, most
    MD> of which are form variables from the form input. So I wanted to have
    MD> a list of the variable names, and use one small section of code to do
    MD> the substitutions, like this:

    you are thinking about this in a totally backwards way on several levels.

    MD> foreach my $variable
    MD> (customer_number,"form_data{'Ecom_BillTo_Postal_Name_First'}","form_data{'Ecom_BillTo_Postal_Name_Last'}",
    MD> "form_data{'Ecom_BillTo_Company'}","form_data{'Ecom_BillTo_Postal_S

    where did those 'variables' come from? show that code too. and as
    several people have said, "form_data{'Ecom_BillTo_Postal_Name_First'}"
    IS NOT A VARIABLE. it is not even a hash value as it has no normal perl
    $hash{key} syntax (it is missing the leading $). i don't know what you
    think it is nor where you learned it but it makes no sense in how you
    describe it. it is a simple string expression. so it can't ever refer to
    anything else in perl especially other 'variables' as it is not even a
    proper variable name.

    now you actually seem to have the values in a hash. i will assume that
    the hash is named %form_data since it is perl. maybe it comes from some
    bastard cgi parser (my main guess). so the first thing you need to do is
    use a proper module CGI.pm to get your form params. but let's stick with
    the hash for now and this is easily changed to use CGI.pm.


    MD> $$variable =~ s/\</\&lt;/g;
    MD> $$variable =~ s/\>/\&gt;/g;
    MD> $$variable =~ s/\(/\(/g;
    MD> $$variable =~ s/\)/\)/g;
    MD> $$variable =~ s/\'/\'/g;

    again, perl has modules for that. why are you reinventing wheels?


    MD> If I inline it, I end up with 5*18 or 90 lines of code in what should
    MD> be able to be done in 6 or 7.

    if you used a module it would be 1 line.

    use HTML::Entities

    encode_entities $_ for values %form_data ;

    now isn't that a bit easier to understand? and it works too!

    so please learn more perl and stop beating your head against the
    wall. your loop code above had NO VARIABLES so don't use that term and
    then expect us to understand you.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 22, 2007
    #5
  6. Marshall Dudley wrote:
    > Jürgen Exner wrote:
    >> Marshall Dudley wrote:
    >>> print "$string = $$string\n";
    >>>

    >>
    >> Besides that what you are trying to do is known as symbolic
    >> references and it is A BAD IDEA!
    >> See the FAQ "How can I use a variable as a variable name?" for
    >> details about why and what to use instead.
    >>
    >> jue
    >>
    >>
    >>

    > I looked at the faq, but did not really see anything applicable.


    You were trying to do "$$string". This is dereferencing a symbolic
    reference. Therefore the FAQ is very applicable.

    > Here
    > is the deal. I have been notified that I have clean up all my
    > variables that print to not allow any <, >, ', &, ( or ) in them to
    > prevent cross platform scripting hacking.


    This seems like such a frequent task. I never use Perl for web site
    development, but maybe it would be worthwhile to check CPAN if there isn't a
    module that does this kink of cleanup already.

    > So I have a confirmation
    > page that prints dozens of variables that are global variables, most
    > of which are form variables from the form input. So I wanted to have
    > a list of the variable names, and use one small section of code to do
    > the substitutions, like this:
    >
    > foreach my $variable
    > (customer_number,"form_data{'Ecom_BillTo_Postal_Name_First'}","form_data{'Ecom_BillTo_Postal_Name_Last'}",
    > "form_data{'Ecom_BillTo_Company'}","form_data{'Ecom_BillTo_Postal_Street_Line1'}","form_data{'Ecom_BillTo_Postal_City'}",


    What is this "form_data{'xxxx'}"? Do you mean "$form_data{'xxxx'}"?
    If yes, then you already got the hash that is suggested in the FAQ.

    for my $variable(keys(%form_data)) {

    > "form_data{'Ecom_BillTo_Postal_StateProv'}","form_data{'Ecom_BillTo_PostalCode'}","bill_country,form_data{'Ecom_BillTo_Telecom_Phon
    > "form_data{'Ecom_BillTo_Online_Email'}","form_data{'Ecom_ShipTo_Postal_Name_First'}","form_data{'Ecom_ShipTo_Postal_Name_Last'}",
    > "form_data{'Ecom_ShipTo_Postal_Street_Line1'}","form_data{'Ecom_ShipTo_Postal_City'}","ship_country","form_data{'PO'}",
    > "$form_data{'Comments'}") {
    > $$variable =~ s/\</\&lt;/g;


    $form_data{$variable} =~ .....

    > $$variable =~ s/\>/\&gt;/g;
    > $$variable =~ s/\(/\(/g;
    > $$variable =~ s/\)/\)/g;
    > $$variable =~ s/\'/\'/g;
    > }
    >
    > If I inline it, I end up with 5*18 or 90 lines of code in what should
    > be able to be done in 6 or 7.
    >
    > Thanks,
    >
    > Marshall
     
    Jürgen Exner, Mar 22, 2007
    #6
  7. Marshall Dudley <> wrote:
    > Jürgen Exner wrote:


    >> Besides that what you are trying to do is known as symbolic references and
    >> it is A BAD IDEA!
    >> See the FAQ "How can I use a variable as a variable name?" for details about
    >> why and what to use instead.


    > I have been notified that I have clean up all my variables
    > that print to not allow any <, >, ', &, ( or ) in them


    > So I wanted to have a list of the
    > variable names, and use one small section of code to do the
    > substitutions, like this:
    >
    > foreach my $variable
    > (customer_number,"form_data{'Ecom_BillTo_Postal_Name_First'}","form_data{'Ecom_BillTo_Postal_Name_Last'}",
    > "form_data{'Ecom_BillTo_Company'}","form_data{'Ecom_BillTo_Postal_Street_Line1'}","form_data{'Ecom_BillTo_Postal_City'}",
    > "form_data{'Ecom_BillTo_Postal_StateProv'}","form_data{'Ecom_BillTo_PostalCode'}","bill_country,form_data{'Ecom_BillTo_Telecom_Phon
    > "form_data{'Ecom_BillTo_Online_Email'}","form_data{'Ecom_ShipTo_Postal_Name_First'}","form_data{'Ecom_ShipTo_Postal_Name_Last'}",
    > "form_data{'Ecom_ShipTo_Postal_Street_Line1'}","form_data{'Ecom_ShipTo_Postal_City'}","ship_country","form_data{'PO'}",
    > "$form_data{'Comments'}") {
    > $$variable =~ s/\</\&lt;/g;
    > $$variable =~ s/\>/\&gt;/g;
    > $$variable =~ s/\(/\(/g;
    > $$variable =~ s/\)/\)/g;
    > $$variable =~ s/\'/\'/g;
    > }



    Do you need a bazillion hash entries to illustrate your problem,
    or would, say, two entries do it?

    Do you need 5 substitutions to illustrate your problem, or would, say,
    one or two substitutions do it?

    Have you seen the Posting Guidelines that are posted here frequently?

    The

    < > ' &

    characters are not meta there, so they do not need any backslashing.


    > If I inline it, I end up with 5*18 or 90 lines of code in what should be
    > able to be done in 6 or 7.



    Now that you have come clean on your XY problem, we can offer a fairly
    easy solution that uses no crufty symbolic references.

    Use the aliasing feature of foreach instead:

    -------------------------------------------------
    #!/usr/bin/perl
    use warnings;
    use strict;

    my $customer_number = '<bad stuff>';

    my %form_data = (
    abc => 'more <bad> stuff',
    xyz => 'yet more <ungood> stuff',
    );

    foreach my $var ( $customer_number, values %form_data ) {
    $var =~ s/</&lt;/g;
    $var =~ s/>/&gt;/g;
    }

    print "customer_number=$customer_number\n";
    print "$_=$form_data{$_}\n" for keys %form_data;
    -------------------------------------------------


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Mar 22, 2007
    #7
  8. Uri Guttman wrote:
    >>>>>> "MD" == Marshall Dudley <> writes:
    >>>>>>

    >
    > MD> I looked at the faq, but did not really see anything applicable. Here
    > MD> is the deal. I have been notified that I have clean up all my
    > MD> variables that print to not allow any <, >, ', &, ( or ) in them to
    > MD> prevent cross platform scripting hacking. So I have a confirmation
    > MD> page that prints dozens of variables that are global variables, most
    > MD> of which are form variables from the form input. So I wanted to have
    > MD> a list of the variable names, and use one small section of code to do
    > MD> the substitutions, like this:
    >
    > you are thinking about this in a totally backwards way on several levels.
    >
    > MD> foreach my $variable
    > MD> (customer_number,"form_data{'Ecom_BillTo_Postal_Name_First'}","form_data{'Ecom_BillTo_Postal_Name_Last'}",
    > MD> "form_data{'Ecom_BillTo_Company'}","form_data{'Ecom_BillTo_Postal_S
    >
    > where did those 'variables' come from? show that code too. and as
    > several people have said, "form_data{'Ecom_BillTo_Postal_Name_First'}"
    > IS NOT A VARIABLE. it is not even a hash value as it has no normal perl
    > $hash{key} syntax (it is missing the leading $).


    &require_supporting_libraries (__FILE__,__LINE__,"library/cgi-lib.pl");
    &ReadParse(*form_data);

    > i don't know what you
    > think it is nor where you learned it but it makes no sense in how you
    > describe it. it is a simple string expression. so it can't ever refer to
    > anything else in perl especially other 'variables' as it is not even a
    > proper variable name.
    >

    $form_data{'string'} is a standard hash variable name. I am not sure
    why you think it is not.
    > now you actually seem to have the values in a hash. i will assume that
    > the hash is named %form_data since it is perl. maybe it comes from some
    > bastard cgi parser (my main guess). so the first thing you need to do is
    > use a proper module CGI.pm to get your form params.

    I am using the cgi-lib.pl library routine to get them.
    > but let's stick with
    > the hash for now and this is easily changed to use CGI.pm.
    >
    >
    > MD> $$variable =~ s/\</\&lt;/g;
    > MD> $$variable =~ s/\>/\&gt;/g;
    > MD> $$variable =~ s/\(/\(/g;
    > MD> $$variable =~ s/\)/\)/g;
    > MD> $$variable =~ s/\'/\'/g;
    >
    > again, perl has modules for that. why are you reinventing wheels?
    >
    >
    > MD> If I inline it, I end up with 5*18 or 90 lines of code in what should
    > MD> be able to be done in 6 or 7.
    >
    > if you used a module it would be 1 line.
    >
    > use HTML::Entities
    >
    > encode_entities $_ for values %form_data ;
    >

    OK, I will check the Entities module.

    Thanks,

    Marshall
    > now isn't that a bit easier to understand? and it works too!
    >
    > so please learn more perl and stop beating your head against the
    > wall. your loop code above had NO VARIABLES so don't use that term and
    > then expect us to understand you.
    >
    > uri
    >
    >
     
    Marshall Dudley, Mar 23, 2007
    #8
  9. Marshall Dudley

    Uri Guttman Guest

    >>>>> "MD" == Marshall Dudley <> writes:

    MD> Uri Guttman wrote:

    MD> &require_supporting_libraries
    MD> (__FILE__,__LINE__,"library/cgi-lib.pl");


    where did that sub come from? do you really need to know the line and
    file where you loaded something? if an error happened, perl will tell
    you that info.

    MD> &ReadParse(*form_data);

    that is an ancient, buggy and crappy cgi library. use CGI.pm and it even
    has a compatible function for you.

    >> i don't know what you
    >> think it is nor where you learned it but it makes no sense in how you
    >> describe it. it is a simple string expression. so it can't ever refer to
    >> anything else in perl especially other 'variables' as it is not even a
    >> proper variable name.
    >>

    MD> $form_data{'string'} is a standard hash variable name. I am not sure
    MD> why you think it is not.

    because of what i said. YOU WERE MISSING THE LEADING $ when you
    (mis)used it in your loop. THAT was a string and not a variable. anyhow
    you can't do symrefs like that even if you wanted to (which you don't.

    MD> I am using the cgi-lib.pl library routine to get them.

    use CGI.pm. cgi-lib hasn't been touched in over a decade.

    MD> If I inline it, I end up with 5*18 or 90 lines of code in what should
    MD> be able to be done in 6 or 7.
    >>
    >> if you used a module it would be 1 line.
    >>
    >> use HTML::Entities
    >>
    >> encode_entities $_ for values %form_data ;
    >>

    MD> OK, I will check the Entities module.

    and CGI.pm and learn some basic perl. your concept of a loop over a hash
    was nowhere close to what you wanted.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 23, 2007
    #9
    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. George Ter-Saakov

    Indirect use of COM

    George Ter-Saakov, Aug 26, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    353
    Natty Gur
    Aug 27, 2003
  2. plaztik via DotNetMonster.com

    Enterprise Library - Indirect/Inherited Configuration??

    plaztik via DotNetMonster.com, May 6, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    520
    Scott Allen
    May 6, 2005
  3. Yu Lianqing
    Replies:
    1
    Views:
    381
    John Harrison
    Jul 31, 2003
  4. Steven T. Hatton

    Indirect recursion and templates?

    Steven T. Hatton, Apr 22, 2004, in forum: C++
    Replies:
    2
    Views:
    447
    Steven T. Hatton
    Apr 22, 2004
  5. Larry Bates

    Indirect Memory Addressing

    Larry Bates, Jun 4, 2004, in forum: Python
    Replies:
    2
    Views:
    387
    Michel Claveau/Hamster
    Jun 4, 2004
Loading...

Share This Page