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

Discussion in 'Perl Misc' started by ioneabu@yahoo.com, Dec 27, 2004.

  1. Guest

    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
     
    , Dec 27, 2004
    #1
    1. Advertising

  2. Matt Garrish Guest

    <> wrote in message
    news:...
    >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
     
    Matt Garrish, Dec 27, 2004
    #2
    1. Advertising

  3. Paul Lalli Guest

    <> wrote in message
    news:...
    > 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::Dumper;
    #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
     
    Paul Lalli, Dec 27, 2004
    #3
  4. Guest

    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.
     
    , Dec 27, 2004
    #4
  5. Paul Lalli Guest

    "Matt Garrish" <> wrote in message
    news:yVVzd.12015$...
    >
    > <> wrote in message
    > news:...
    > >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
     
    Paul Lalli, Dec 27, 2004
    #5
  6. Paul Lalli Guest

    <> wrote in message
    news:...
    > 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
     
    Paul Lalli, Dec 27, 2004
    #6
  7. Guest

    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
     
    , Dec 27, 2004
    #7
  8. Matt Garrish Guest

    "Paul Lalli" <> wrote in message
    news:HwWzd.2607$PY6.2590@trndny02...
    > "Matt Garrish" <> wrote in message
    > news:yVVzd.12015$...
    >>
    >> <> wrote in message
    >> news:...
    >> >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
     
    Matt Garrish, Dec 27, 2004
    #8
  9. Guest

    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
     
    , Dec 27, 2004
    #9
  10. Paul Lalli Guest

    "Matt Garrish" <> wrote in message
    news:v6Xzd.12800$...
    >
    > 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
     
    Paul Lalli, Dec 27, 2004
    #10
  11. Paul Lalli Guest

    <> wrote in message
    news:...

    Please read the posting guidlines for this group. Specifically, please
    quote the message you are responding to. Thank you.

    > I didn't realize that was not an official site.


    If it's not on oreilly.com or perl.com, it's not official.

    > $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


    All correct.

    > and is not the same as:
    >
    > %hash1{keys %hash2} = values %hash2;


    This is a classic example of "What happened when you tried it?" I
    gather that you did not try it, because when I try it, I get:

    syntax error at - line 4, near "%hash1{"

    > which I assume is special notation for dealing with hash slices.

    Would
    > this be the same?
    >
    > @hash1{keys %hash2} = values %hash2;


    No. This is the correct way of creating hash slices. The example with
    % above is not valid code.

    > 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.


    You use % to assign a list of key/value pairs to a hash. You use @ to
    create a hash slice - that is, to read or set a list of values based on
    a list of keys. (There are no restrictions on the size of that list -
    it could be empty, it could contain all of the currently existing hash
    keys, it could contain hash keys that do not currently exist).

    my %hash = (foo=>1, bar=>2);
    is equivalent to:
    my %hash;
    @hash{foo,bar}=(1,2);

    I hope that clears things up,
    Paul Lalli
     
    Paul Lalli, Dec 27, 2004
    #11
  12. Guest

    Thank you very much for taking the time to explain. Through Google,
    all answers to my questions have provided an incredibly invaluable
    reference in my studies and practice.

    Regarding my poor posting practices recently, specifically improper
    quoting, this is due to Google's new beta version of groups.google.com.
    I prefer it over the old format because posts go up immediately rather
    than 6-8 hours.

    Unfortunately, replies to a message are done in such a way to make them
    non-compliant with comp.lang.perl.misc posting practices.

    Try it and see, a little reply box appears at the bottom of the message
    you are replying to and that's all you get. I was paying $10 monthly
    for a newsgroup service, but I did not need nearly the bandwidth I was
    paying for and I had no interest in any kind of large encoded binary
    files.

    I hope that Google fixes this, I don't know exactly who to complain to.
    You would think that such a powerful search engine must use a little
    Perl somewhere and that their programmers who spend time here would
    have noticed the problem.

    wana
     
    , Dec 27, 2004
    #12
  13. Paul Lalli Guest

    [OT - Google Groups] WAS: copying values from a hash into CGI.pm via tied hash reference

    <> wrote in message
    news:...
    > Regarding my poor posting practices recently, specifically improper
    > quoting, this is due to Google's new beta version of

    groups.google.com.
    > I prefer it over the old format because posts go up immediately rather
    > than 6-8 hours.
    >
    > Unfortunately, replies to a message are done in such a way to make

    them
    > non-compliant with comp.lang.perl.misc posting practices.
    >
    > Try it and see, a little reply box appears at the bottom of the

    message
    > you are replying to and that's all you get.


    Instead of clicking Reply, click the "Show Options" link, and then click
    the Reply link that appears near the top of the message text.

    Paul Lalli
     
    Paul Lalli, Dec 27, 2004
    #13
  14. Juha Laiho Guest

    "Paul Lalli" <> said:
    >"Matt Garrish" <> wrote in message
    >news:v6Xzd.12800$...
    >>
    >> 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).


    Hmm.. is it also so that the order is not necessarily consistent for
    two successive runs of the same program? From perldelta for 5.8.1:

    : Mainly due to security reasons, the ``random ordering'' of hashes has
    : been made even more random. Previously while the order of hash
    : elements from keys(), values(), and each() was essentially random, it
    : was still repeatable. Now, however, the order varies between different
    : runs of Perl.
    :
    : Perl has never guaranteed any ordering of the hash keys, and the
    : ordering has already changed several times during the lifetime of Perl
    : 5. Also, the ordering of hash keys has always been, and continues to
    : be, affected by the insertion order.

    So, the order is constant for a single run of the program, but not
    repeatable in consecutive runs.
    --
    Wolf a.k.a. Juha Laiho Espoo, Finland
    (GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
    PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
    "...cancel my subscription to the resurrection!" (Jim Morrison)
     
    Juha Laiho, Dec 28, 2004
    #14
  15. Tomi Häsä Guest

    wrote:
    >
    > Regarding my poor posting practices recently, specifically
    > improper quoting, this is due to Google's new beta version of
    > groups.google.com.
    > [...]
    >
    > I hope that Google fixes this, I don't know exactly who to
    > complain to.


    If you want to report problems with Google Groups Beta, you can use
    this feedback page:

    http://groups-beta.google.com/support/bin/request.py

    Or you can send email to Google Groups Beta:

    (labs-groups2 @ google.com)

    Or you can post a message to this discussion group:

    http://groups-beta.google.com/group/google-labs-groups2

    This message contains a list of some the bugs and problems that have
    been reported so far:

    http://groups-beta.google.com/group/google-labs-groups2/msg/b54c12517c75eb24

    More info in this FAQ:
    http://www.geocities.com/googlepubsupgenfaq/#groupsproblems
     
    Tomi Häsä, Jan 10, 2005
    #15
    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. Dan
    Replies:
    1
    Views:
    93
    Ben Morrow
    Nov 21, 2003
  2. Dan Anderson

    What is a tied hash?

    Dan Anderson, Nov 21, 2003, in forum: Perl Misc
    Replies:
    5
    Views:
    296
    Tad McClellan
    Nov 21, 2003
  3. Thomas Reat

    sharing a (tied) hash between processes

    Thomas Reat, Jan 1, 2004, in forum: Perl Misc
    Replies:
    4
    Views:
    126
    pkent
    Jan 3, 2004
  4. Konrad Eisele

    tied hash

    Konrad Eisele, Jul 27, 2005, in forum: Perl Misc
    Replies:
    3
    Views:
    101
    Anno Siegel
    Jul 28, 2005
  5. bernd
    Replies:
    0
    Views:
    625
    bernd
    Apr 24, 2012
Loading...

Share This Page