Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Problem with indirect variables

Reply
Thread Tools

Problem with indirect variables

 
 
Marshall Dudley
Guest
Posts: n/a
 
      03-22-2007
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
 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      03-22-2007
On Mar 22, 5:08 pm, Marshall Dudley <(E-Mail Removed)> 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?

 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      03-22-2007
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


 
Reply With Quote
 
Marshall Dudley
Guest
Posts: n/a
 
      03-22-2007
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_Na me_First'}","form_data{'Ecom_BillTo_Postal_Name_La st'}",
"form_data{'Ecom_BillTo_Company'}","form_data{'Eco m_BillTo_Postal_Street_Line1'}","form_data{'Ecom_B illTo_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{'Eco m_ShipTo_Postal_Name_Last'}",
"form_data{'Ecom_ShipTo_Postal_Street_Line1'}","fo rm_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
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      03-22-2007
>>>>> "MD" == Marshall Dudley <(E-Mail Removed)> 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_Na me_First'}","form_data{'Ecom_BillTo_Postal_Name_La st'}",
MD> "form_data{'Ecom_BillTo_Company'}","form_data{'Eco m_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.velocityreviews.com/forums/(E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      03-22-2007
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_Na me_First'}","form_data{'Ecom_BillTo_Postal_Name_La st'}",
> "form_data{'Ecom_BillTo_Company'}","form_data{'Eco m_BillTo_Postal_Street_Line1'}","form_data{'Ecom_B illTo_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{'Eco m_ShipTo_Postal_Name_Last'}",
> "form_data{'Ecom_ShipTo_Postal_Street_Line1'}","fo rm_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



 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      03-22-2007
Marshall Dudley <(E-Mail Removed)> 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_Na me_First'}","form_data{'Ecom_BillTo_Postal_Name_La st'}",
> "form_data{'Ecom_BillTo_Company'}","form_data{'Eco m_BillTo_Postal_Street_Line1'}","form_data{'Ecom_B illTo_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{'Eco m_ShipTo_Postal_Name_Last'}",
> "form_data{'Ecom_ShipTo_Postal_Street_Line1'}","fo rm_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
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Marshall Dudley
Guest
Posts: n/a
 
      03-23-2007
Uri Guttman wrote:
>>>>>> "MD" == Marshall Dudley <(E-Mail Removed)> 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_Na me_First'}","form_data{'Ecom_BillTo_Postal_Name_La st'}",
> MD> "form_data{'Ecom_BillTo_Company'}","form_data{'Eco m_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
>
>

 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      03-23-2007
>>>>> "MD" == Marshall Dudley <(E-Mail Removed)> 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 ------ (E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"indirect" ipsec dt1649651@yahoo.com Cisco 3 05-19-2005 08:17 PM
Enterprise Library - Indirect/Inherited Configuration?? plaztik via DotNetMonster.com ASP .Net 1 05-06-2005 03:44 PM
Indirect recursion and templates? Steven T. Hatton C++ 2 04-22-2004 06:24 AM
Indirect use of COM George Ter-Saakov ASP .Net 2 08-27-2003 03:03 PM
Can a class call its indirect base's member function? Yu Lianqing C++ 1 07-31-2003 02:31 PM



Advertisments