Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > copying values from a hash into CGI.pm via tied hash reference

Reply
Thread Tools

copying values from a hash into CGI.pm via tied hash reference

 
 
ioneabu@yahoo.com
Guest
Posts: n/a
 
      12-27-2004
I am trying to restore values from a saved session to fill in my CGI.pm
fields in the simplest and most generic way possible (such that if I
change my form, I don't have to rewrite this code). This statement did
not work:

$params->{keys %session} = values %session;

$params is a reference to a tied hash returned by Vars().

Here is info on Vars() quoted from

http://stein.cshl.org/WWW/software/CGI/

<quote>
Many people want to fetch the entire parameter list as a hash in which
the keys are the names of the CGI parameters, and the values are the
parameters' values. The Vars() method does this. Called in a scalar
context, it returns the parameter list as a tied hash reference.
Changing a key changes the value of the parameter in the underlying CGI
parameter list. Called in an list context, it returns the parameter
list as an ordinary hash. This allows you to read the contents of the
parameter list, but not to change it.
</quote>

Thanks for help. I know I could do it differently, I was just
wondering why it didn't work this way.

wana

 
Reply With Quote
 
 
 
 
Matt Garrish
Guest
Posts: n/a
 
      12-27-2004

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
>I am trying to restore values from a saved session to fill in my CGI.pm
> fields in the simplest and most generic way possible (such that if I
> change my form, I don't have to rewrite this code). This statement did
> not work:
>
> $params->{keys %session} = values %session;
>
> $params is a reference to a tied hash returned by Vars().
>
> Thanks for help. I know I could do it differently, I was just
> wondering why it didn't work this way.
>


You can't just write something you don't understand and expect it to work:
"keys %session" returns the number of keys in %session in scalar context and
"values %session" returns the number of values (see perlfunc). So, assuming
to two key/value pairs in %session, your statement becomes:

$params->{2} = 2;

If you don't use some kind of loop, you're never going to get what you want:

foreach (keys %session) { $params->{$_} = $session{$_} }

Matt


 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      12-27-2004
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> I am trying to restore values from a saved session to fill in my

CGI.pm
> fields in the simplest and most generic way possible (such that if I
> change my form, I don't have to rewrite this code). This statement

did
> not work:


"did not work" is a remarkably poor error description. What did it do?
What were you expecting/hoping for it to do? How did the results
differ?

Have you read the posting guidelines that are posted to this group
semi-weekly?

> $params->{keys %session} = values %session;


You are using the keys function in a scalar context. In scalar context,
keys returns the number of keys in the given hash. Therefore, if
%session contained two key/value pairs, this is the equivalent of

$params->{2} = 2; #since values in scalar context also returns the
number of pairs

What you want to do is create a hash slice and assign to that. If you
had a normal hash, say:
my %hash;
you would generate the slice like so:
@hash{foo,bar} = ( ... );

The general rule when dealing with hashrefs is to replace the name of
the hash ('hash' in this case) with the hashref, in brackets. Thus
%hash becomes %{$params}
and
@hash{foo,bar} becomes @($params}{foo,bar);

Putting it all together, here's a short example script to demonstrate
the correct technique:

#!/usr/bin/perl
use strict;
use warnings;
use Data:umper;
#fill %session with dummy data
my %session = (foo=>1,bar=>2);
#create anon hash reference
my $params = { };
#create a hashslice and use it to populate the anon hash
@{$params}{keys %session} = values %session;
print Dumper($params);
__END__

$VAR1 = {
'bar' => 2,
'foo' => 1
};


Hope this helps,
Paul Lalli

 
Reply With Quote
 
ioneabu@yahoo.com
Guest
Posts: n/a
 
      12-27-2004
Sorry for saying 'did not work.'

Here is what I tried:

$params->{keys %session} = values %session;

Here is the example I based it on:

http://www.unix.org.ua/orelly/perl/learn/ch05_05.htm

<quote>
Hash slices can also be used to merge a smaller hash into a larger one.
In this example, the smaller hash takes precedence in the sense that if
there are duplicate keys, the value from the smaller hash is used:

%league{keys %score} = values %score;
</quote>

Maybe this was the source of my confusion. I thought I understood the
example but now I am not sure.

 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      12-27-2004
"Matt Garrish" <(E-Mail Removed)> wrote in message
news:yVVzd.12015$(E-Mail Removed). ..
>
> <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) oups.com...
> >I am trying to restore values from a saved session to fill in my

CGI.pm
> > fields in the simplest and most generic way possible (such that if I
> > change my form, I don't have to rewrite this code). This statement

did
> > not work:
> >
> > $params->{keys %session} = values %session;
> >

>
> If you don't use some kind of loop, you're never going to get what you

want:
>
> foreach (keys %session) { $params->{$_} = $session{$_} }


Untrue. A hash slice will do just fine. See my previous response in
this thread. (And no, I haven't benchmarked to see which is faster...)

Paul Lalli

 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      12-27-2004
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> Sorry for saying 'did not work.'
>
> Here is what I tried:
>
> $params->{keys %session} = values %session;
>
> Here is the example I based it on:
>

<<<SNIPPED PIRATTED BOOK URL>>>

Ah, so you used a piratted copy of material and didn't understand what
it actually did. I'd say that satisfies Karma.

> <quote>
> Hash slices can also be used to merge a smaller hash into a larger

one.
> In this example, the smaller hash takes precedence in the sense that

if
> there are duplicate keys, the value from the smaller hash is used:
>
> %league{keys %score} = values %score;
> </quote>
>
> Maybe this was the source of my confusion. I thought I understood the
> example but now I am not sure.


Do you understand how the above line of code differs from what you did?
If not, you need to read up on references. Fortunately, Perl comes with
free documentation that you don't have to steal.

At your command line, type
perldoc perlreftut
perldoc perllol
perldoc perldsc
perldoc perlref
(generally in that order)


Paul Lalli

 
Reply With Quote
 
ioneabu@yahoo.com
Guest
Posts: n/a
 
      12-27-2004
I didn't realize that was not an official site. I did buy all of the
O'Reilly Perl books plus a few others, so I'm not totally a terrible
person. I did not mean to put a disreputable link into this group.
Sorry again.

$params->{keys %session} = values %session;

hmm...This would be like saying...

${$params}{keys %session} = values %session;

which is accessing an individual hash element which requires a scalar
for the key which puts keys %session into scalar context and is not the
same as:

%hash1{keys %hash2} = values %hash2;

which I assume is special notation for dealing with hash slices. Would
this be the same?

@hash1{keys %hash2} = values %hash2;

Now I am wondering about how to interprete the hash slice notation and
why to use the @ in one case and the % in the other.

Thanks,

wana

 
Reply With Quote
 
Matt Garrish
Guest
Posts: n/a
 
      12-27-2004

"Paul Lalli" <(E-Mail Removed)> wrote in message
news:HwWzd.2607$PY6.2590@trndny02...
> "Matt Garrish" <(E-Mail Removed)> wrote in message
> news:yVVzd.12015$(E-Mail Removed). ..
>>
>> <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed) oups.com...
>> >I am trying to restore values from a saved session to fill in my

> CGI.pm
>> > fields in the simplest and most generic way possible (such that if I
>> > change my form, I don't have to rewrite this code). This statement

> did
>> > not work:
>> >
>> > $params->{keys %session} = values %session;
>> >

>>
>> If you don't use some kind of loop, you're never going to get what you

> want:
>>
>> foreach (keys %session) { $params->{$_} = $session{$_} }

>
> Untrue. A hash slice will do just fine. See my previous response in
> this thread. (And no, I haven't benchmarked to see which is faster...)
>


Fair enough. I was thinking that keys and values wouldn't necessarily return
in the same order when I wrote that, but learned something new today (I'd
still take a loop over a hash slice for clarity, though). And fyi, the time
disparity between the two is minimal, but foreach is slightly faster.

Matt


 
Reply With Quote
 
ioneabu@yahoo.com
Guest
Posts: n/a
 
      12-27-2004
I agree with the loop. That is what I finally used in my program since
I realized that I don't necessarily want to share all of the values of
one hash with the other. I needed to do a little filtering along the
way. It is still good for me for learning purposes. Thanks for help.
wana

 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      12-27-2004
"Matt Garrish" <(E-Mail Removed)> wrote in message
news:v6Xzd.12800$(E-Mail Removed). ..
>
> Fair enough. I was thinking that keys and values wouldn't necessarily

return
> in the same order when I wrote that, but learned something new today

(I'd
> still take a loop over a hash slice for clarity, though). And fyi, the

time
> disparity between the two is minimal, but foreach is slightly faster.


Just to be clear, keys, values, and each all return the hash's elements
in the same order. That's a guarantee. What that order *is* however,
is unknowable (without digging into the internals of perl itself, I
imagine).

Paul Lalli

 
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
Tied hash: Differentiating between assignment of single value andentire hash bernd Perl Misc 0 04-24-2012 02:41 PM
tied hash Konrad Eisele Perl Misc 3 07-28-2005 10:46 AM
sharing a (tied) hash between processes Thomas Reat Perl Misc 4 01-03-2004 09:42 PM
What is a tied hash? Dan Anderson Perl Misc 5 11-21-2003 10:43 PM
Tied hash for CGI-usage (what about file corruption?) Dan Perl Misc 1 11-21-2003 04:26 PM



Advertisments