dynamically creating a hash from an array

Discussion in 'Perl Misc' started by ccc31807, Mar 21, 2014.

  1. ccc31807

    ccc31807 Guest

    To be honest, this may be a FAQ, but I don't seem to have the vocabulary to find it.

    Suppose I have a set of variables, like this:
    my $username = 'Joe';
    my $password = 'somepassword';
    my $role = 'user';
    my $session = 'q1w2e3r4t5y6';
    my $date = '2014-03-21';
    my $time = '12345678';

    Now, suppose I have a sub that prints the name and value of each variable, like this:
    sub debug
    {
    my $href = shift;
    print "-------------begin debugging data------------\n";
    foreach my $key (sort keys %{$href})
    {
    print "$key = $href->{$key}\n";
    }
    print "-------------end debugging data------------\n";
    }

    Further, suppose I have an array, like this:
    my @debugarray = qw( username password role session date time );

    Question: how can I turn the array into a hash so I can pass a reference to the has to the sub? Like this, perhaps:
    debug($href);

    I suppose that my hash would look like this:
    my $href = {
    username => $username,
    password => password,
    role => $role,
    session => $session,
    date => $date,
    time => $time,
    };

    As I say, this is probably frequently asked, but I may not know how to ask the question. Thanks CC.
    ccc31807, Mar 21, 2014
    #1
    1. Advertising

  2. ccc31807 <> writes:
    > To be honest, this may be a FAQ, but I don't seem to have the vocabulary to find it.
    >
    > Suppose I have a set of variables, like this:
    > my $username = 'Joe';
    > my $password = 'somepassword';
    > my $role = 'user';
    > my $session = 'q1w2e3r4t5y6';
    > my $date = '2014-03-21';
    > my $time = '12345678';


    [...]

    > Further, suppose I have an array, like this:
    > my @debugarray = qw( username password role session date time );
    >
    > Question: how can I turn the array into a hash so I can pass a reference to the has to the sub? Like this, perhaps:
    > debug($href);
    >
    > I suppose that my hash would look like this:
    > my $href = {
    > username => $username,
    > password => password,
    > role => $role,
    > session => $session,
    > date => $date,
    > time => $time,
    > };


    There's no way to access a 'my' variable 'by name' because at run time,
    its "name" is an index into the lexical pad (term?) it belongs to. This
    means the only way to achieve this is to generate a string containing
    the Perl code creating the anonymous has and executing this code via
    eval in a scope where the desired set of my variables exists. Example:

    -------------
    my $username = 'Joe';
    my $password = 'somepassword';
    my $role = 'user';
    my $session = 'q1w2e3r4t5y6';
    my $date = '2014-03-21';
    my $time = '12345678';

    my @debugarray = qw(username password role session date time);

    sub make_hash_init
    {
    my $code;

    $code = '{';
    $code .= sprintf('%s => $%s,', $_,$_) for @_;
    return $code.'}';
    }

    my $hdebug = eval(make_hash_init(@debugarray));

    printf("%s\t%s\n", $_, $hdebug->{$_}) for keys(%$hdebug);
    -------------
    Rainer Weikusat, Mar 21, 2014
    #2
    1. Advertising

  3. ccc31807

    $Bill Guest

    On 3/21/2014 09:34, ccc31807 wrote:
    >


    Obviously this only gets the content of each var at the time the
    hash is created - changing one of them won't change what's in the
    hash:

    use strict;
    use warnings;

    my $username = 'Joe';
    my $password = 'somepassword';
    my $role = 'user';
    my $session = 'q1w2e3r4t5y6';
    my $date = '2014-03-21';
    my $time = '12345678';
    my @debugarray = qw(username password role session date time);

    my $href;
    foreach (@debugarray) { eval "\$href->{$_} = \$$_"; }
    debug ($href);
    exit;

    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    sub debug {
    my $href = shift;

    print "-------------begin debugging data------------\n";
    foreach my $key (sort keys %{$href}) {
    print "$key = $href->{$key}\n";
    }
    print "-------------end debugging data------------\n";

    }

    __END__
    $Bill, Mar 21, 2014
    #3
  4. # here you go

    use strict;
    use warnings;

    my $username = 'Joe';
    my $password = 'somepassword';
    my $role = 'user';
    my $session = 'q1w2e3r4t5y6';
    my $date = '2014-03-21';
    my $time = '12345678';
    my @debugarray = qw( username password role session date time fakevar1
    fakevar2);
    my %hash;



    foreach my $var (@debugarray) {
    $_ = eval "\$$var";
    $hash{$var} = $_ unless $@
    }


    use Data::Dumper; print Dumper \%hash;
    George Mpouras, Mar 21, 2014
    #4
  5. On 3/21/2014 9:34 AM, ccc31807 wrote:
    > To be honest, this may be a FAQ, but I don't seem to have the vocabulary to find it.
    >
    > Suppose I have a set of variables, like this:
    > my $username = 'Joe';
    > my $password = 'somepassword';
    > my $role = 'user';
    > my $session = 'q1w2e3r4t5y6';
    > my $date = '2014-03-21';
    > my $time = '12345678';
    >
    > Now, suppose I have a sub that prints the name and value of each variable, like this:
    > sub debug
    > {
    > my $href = shift;
    > print "-------------begin debugging data------------\n";
    > foreach my $key (sort keys %{$href})
    > {
    > print "$key = $href->{$key}\n";
    > }
    > print "-------------end debugging data------------\n";
    > }
    >
    > Further, suppose I have an array, like this:
    > my @debugarray = qw( username password role session date time );
    >
    > Question: how can I turn the array into a hash so I can pass a reference to the has to the sub? Like this, perhaps:
    > debug($href);
    >
    > I suppose that my hash would look like this:
    > my $href = {
    > username => $username,
    > password => password,
    > role => $role,
    > session => $session,
    > date => $date,
    > time => $time,
    > };
    >
    > As I say, this is probably frequently asked, but I may not know how to ask the question. Thanks CC.
    >


    See PadWalker for caveats:

    use PadWalker qw/peek_my/;
    use feature 'say';

    my $username = 'Joe';
    ....
    my @debugarray = qw/$username $password $role $session $date $time/;
    debug( peek_my(0), \@debugarray );

    sub debug {
    my ($href, $aref ) = @_;
    foreach my $key (@$aref) {
    say "$key = ", ${$href->{$key}};
    }
    }

    --
    Charles DeRykus
    Charles DeRykus, Mar 23, 2014
    #5
  6. cool !
    George Mpouras, Mar 24, 2014
    #6
  7. Rainer Weikusat, Mar 24, 2014
    #7
  8. On 3/24/2014 5:31 AM, Rainer Weikusat wrote:
    > George Mpouras <> writes:
    >
    > [PadWalker]
    >
    >> cool !

    >
    > "I wouldn't recommend using PadWalker directly in production code"
    >
    > http://search.cpan.org/~robin/PadWalker-1.98


    Also mentions "PadWalker is particularly useful for debugging. It's
    even used by Perl's built-in debugger..."

    So it may be worth the risk here. YMMV.

    --
    Charles DeRykus
    Charles DeRykus, Mar 24, 2014
    #8
  9. Charles DeRykus <> writes:
    > On 3/24/2014 5:31 AM, Rainer Weikusat wrote:
    >> George Mpouras <> writes:
    >>
    >> [PadWalker]
    >>
    >>> cool !

    >>
    >> "I wouldn't recommend using PadWalker directly in production code"
    >>
    >> http://search.cpan.org/~robin/PadWalker-1.98

    >
    > Also mentions "PadWalker is particularly useful for debugging. It's
    > even used by Perl's built-in debugger..."
    >
    > So it may be worth the risk here. YMMV.


    Being able to replace a tiny bit of 'safe' (in the sense that it works
    only with documented interfaces and doesn't fiddle around with internal
    data structures of the interpreter) with a fairly large bit of (not
    exactly expertly written) C code isn't worth any risks.
    Rainer Weikusat, Mar 24, 2014
    #9
  10. On 3/24/2014 3:52 PM, Rainer Weikusat wrote:
    > Charles DeRykus <> writes:
    >> On 3/24/2014 5:31 AM, Rainer Weikusat wrote:
    >>> George Mpouras <> writes:
    >>>
    >>> [PadWalker]
    >>>
    >>>> cool !
    >>>
    >>> "I wouldn't recommend using PadWalker directly in production code"
    >>>
    >>> http://search.cpan.org/~robin/PadWalker-1.98

    >>
    >> Also mentions "PadWalker is particularly useful for debugging. It's
    >> even used by Perl's built-in debugger..."
    >>
    >> So it may be worth the risk here. YMMV.

    >
    > Being able to replace a tiny bit of 'safe' (in the sense that it works
    > only with documented interfaces and doesn't fiddle around with internal
    > data structures of the interpreter) with a fairly large bit of (not
    > exactly expertly written) C code isn't worth any risks.
    >


    That's overreaching IMO. You're deprecating the value of a module
    even used by "Perl's built-in debugger" and especially, in this
    case, since the use was limited to debug. You should throw out Perl's
    built-in debugger then for the same reason. Caution tips over and
    becomes FUD.

    --
    Charles DeRykus
    Charles DeRykus, Mar 25, 2014
    #10
  11. ccc31807

    Kaz Kylheku Guest

    On 2014-03-25, Charles DeRykus <> wrote:
    > On 3/24/2014 3:52 PM, Rainer Weikusat wrote:
    >> Charles DeRykus <> writes:
    >>> On 3/24/2014 5:31 AM, Rainer Weikusat wrote:
    >>>> George Mpouras <> writes:
    >>>>
    >>>> [PadWalker]
    >>>>
    >>>>> cool !
    >>>>
    >>>> "I wouldn't recommend using PadWalker directly in production code"
    >>>>
    >>>> http://search.cpan.org/~robin/PadWalker-1.98
    >>>
    >>> Also mentions "PadWalker is particularly useful for debugging. It's
    >>> even used by Perl's built-in debugger..."
    >>>
    >>> So it may be worth the risk here. YMMV.

    >>
    >> Being able to replace a tiny bit of 'safe' (in the sense that it works
    >> only with documented interfaces and doesn't fiddle around with internal
    >> data structures of the interpreter) with a fairly large bit of (not
    >> exactly expertly written) C code isn't worth any risks.
    >>

    >
    > That's overreaching IMO. You're deprecating the value of a module
    > even used by "Perl's built-in debugger" and especially, in this
    > case, since the use was limited to debug. You should throw out Perl's
    > built-in debugger then for the same reason. Caution tips over and
    > becomes FUD.


    A lexical environment is not something that is passed down to a child function:
    doing so (as an exposed feature) makes it a de facto dynamic environment.

    Programs that depend on a lexical environment being treated as a dynamic
    environment (via some internal escape hatch) should be written with the
    understanding that the author is wrecking the lexical scope paradigm.

    This falls into the "dumb hack" category when used other than for the intended
    purpose of supporting the debugger as part of the implemenation. If Perl ever
    becomes a properly compiled language, this area will have to drastically
    change, such that programs which depend on it will break.
    Kaz Kylheku, Mar 25, 2014
    #11
  12. ccc31807

    Tim McDaniel Guest

    In article <lgqo59$q3r$>,
    Charles DeRykus <> wrote:
    >Rainer Weikusat wrote [against using PadWalker]
    >
    >That's overreaching IMO. You're deprecating the value of a module


    So far as I've seen, that's Rainer's usual approach to modules from
    CPAN, for example, so I'm not surprised to see the same opinion here.

    You write that PadWalker is used in the Perl debugger, but
    perl -e 'use PadWalker'
    fails for me on the systems I have available, so I don't understand
    what's going on with it.

    --
    Tim McDaniel,
    Tim McDaniel, Mar 25, 2014
    #12
  13. On 3/24/2014 9:37 PM, Kaz Kylheku wrote:
    > On 2014-03-25, Charles DeRykus <> wrote:
    >> On 3/24/2014 3:52 PM, Rainer Weikusat wrote:
    >>> Charles DeRykus <> writes:
    >>>> On 3/24/2014 5:31 AM, Rainer Weikusat wrote:
    >>>>> George Mpouras <> writes:
    >>>>>
    >>>>> [PadWalker]
    >>>>>
    >>>>>> cool !
    >>>>>
    >>>>> "I wouldn't recommend using PadWalker directly in production code"
    >>>>>
    >>>>> http://search.cpan.org/~robin/PadWalker-1.98
    >>>>
    >>>> Also mentions "PadWalker is particularly useful for debugging. It's
    >>>> even used by Perl's built-in debugger..."
    >>>>
    >>>> So it may be worth the risk here. YMMV.
    >>>
    >>> Being able to replace a tiny bit of 'safe' (in the sense that it works
    >>> only with documented interfaces and doesn't fiddle around with internal
    >>> data structures of the interpreter) with a fairly large bit of (not
    >>> exactly expertly written) C code isn't worth any risks.
    >>>

    >>
    >> That's overreaching IMO. You're deprecating the value of a module
    >> even used by "Perl's built-in debugger" and especially, in this
    >> case, since the use was limited to debug. You should throw out Perl's
    >> built-in debugger then for the same reason. Caution tips over and
    >> becomes FUD.

    >
    > A lexical environment is not something that is passed down to a child function:
    > doing so (as an exposed feature) makes it a de facto dynamic environment.
    >
    > Programs that depend on a lexical environment being treated as a dynamic
    > environment (via some internal escape hatch) should be written with the
    > understanding that the author is wrecking the lexical scope paradigm.
    >
    > This falls into the "dumb hack" category when used other than for the intended
    > purpose of supporting the debugger as part of the implemenation. If Perl ever
    > becomes a properly compiled language, this area will have to drastically
    > change, such that programs which depend on it will break.
    >


    And the documentation makes it clear that it's particularly useful for
    debugging...and not recommended for production code. You need enough
    rope to climb into the nooks and crannies of a language even if it's
    dangerous and tomorrow you may need a better rope. The "Perl Hacks"
    segment on PadWalker shows a couple of cases where breaking
    encapsulation is useful and a very apt rationale:

    "It's scary and wrong, but sometimes it's just what you need".


    --
    Charles DeRykus
    Charles DeRykus, Mar 25, 2014
    #13
  14. On 3/24/2014 10:32 PM, Tim McDaniel wrote:
    > In article <lgqo59$q3r$>,
    > Charles DeRykus <> wrote:
    >> Rainer Weikusat wrote [against using PadWalker]
    >>
    >> That's overreaching IMO. You're deprecating the value of a module

    >
    > So far as I've seen, that's Rainer's usual approach to modules from
    > CPAN, for example, so I'm not surprised to see the same opinion here.
    >
    > You write that PadWalker is used in the Perl debugger, but
    > perl -e 'use PadWalker'
    > fails for me on the systems I have available, so I don't understand
    > what's going on with it.
    >


    I see in perldebug that using the "y" command requires PadWalker to be
    installed.

    --
    Charles DeRykus
    Charles DeRykus, Mar 25, 2014
    #14
  15. Charles DeRykus <> writes:
    > On 3/24/2014 3:52 PM, Rainer Weikusat wrote:
    >> Charles DeRykus <> writes:
    >>> On 3/24/2014 5:31 AM, Rainer Weikusat wrote:
    >>>> George Mpouras <> writes:
    >>>>
    >>>> [PadWalker]
    >>>>
    >>>>> cool !
    >>>>
    >>>> "I wouldn't recommend using PadWalker directly in production code"
    >>>>
    >>>> http://search.cpan.org/~robin/PadWalker-1.98
    >>>
    >>> Also mentions "PadWalker is particularly useful for debugging. It's
    >>> even used by Perl's built-in debugger..."
    >>>
    >>> So it may be worth the risk here. YMMV.

    >>
    >> Being able to replace a tiny bit of 'safe' (in the sense that it works
    >> only with documented interfaces and doesn't fiddle around with internal
    >> data structures of the interpreter) with a fairly large bit of (not
    >> exactly expertly written) C code isn't worth any risks.
    >>

    >
    > That's overreaching IMO. You're deprecating the value of a module
    > even used by "Perl's built-in debugger" and especially, in this
    > case, since the use was limited to debug. You should throw out Perl's
    > built-in debugger then for the same reason. Caution tips over and
    > becomes FUD.


    I didn't write that I thought any risk was associated with using this
    module and in fact, I don't think so, except possibly that it may not or
    not anymore or not at all be compatible with some Perl versions, IOW,
    "it may seem like a free download now but you will have to maintain this
    code". Considering that versus

    eval('{'.join(',', map { "$_, \$$_" } @a).'}');

    this becomes a very bad tradeoff.
    Rainer Weikusat, Mar 25, 2014
    #15
  16. (Tim McDaniel) writes:
    > In article <lgqo59$q3r$>,
    > Charles DeRykus <> wrote:
    >>Rainer Weikusat wrote [against using PadWalker]
    >>
    >>That's overreaching IMO. You're deprecating the value of a module

    >
    > So far as I've seen, that's Rainer's usual approach to modules from
    > CPAN, for example, so I'm not surprised to see the same opinion here.


    That's my usual approach to human gateways answering any Perl question
    by (blindly) forwarding something the CPAN search engine returned: It
    shifts the topic of discussion away from the original question towards
    the 'free download du jour'.

    > You write that PadWalker is used in the Perl debugger, but
    > perl -e 'use PadWalker'
    > fails for me on the systems I have available, so I don't understand
    > what's going on with it.


    According to the documentation, auto-completion of lexical variable
    names is provided via PadWalker if it is available. It also seems to be
    a core part of the/ an Eclipse Perl debugger.
    Rainer Weikusat, Mar 25, 2014
    #16
  17. Charles DeRykus <> writes:
    > On 3/24/2014 9:37 PM, Kaz Kylheku wrote:
    >> On 2014-03-25, Charles DeRykus <> wrote:


    [...]

    >>>>>> [PadWalker]


    [...]

    >> A lexical environment is not something that is passed down to a child function:
    >> doing so (as an exposed feature) makes it a de facto dynamic environment.
    >>
    >> Programs that depend on a lexical environment being treated as a dynamic
    >> environment (via some internal escape hatch) should be written with the
    >> understanding that the author is wrecking the lexical scope paradigm.
    >>
    >> This falls into the "dumb hack" category when used other than for the intended
    >> purpose of supporting the debugger as part of the implemenation. If Perl ever
    >> becomes a properly compiled language, this area will have to drastically
    >> change, such that programs which depend on it will break.

    >
    > And the documentation makes it clear that it's particularly useful for
    > debugging...and not recommended for production code. You need enough
    > rope to climb into the nooks and crannies of a language even if it's
    > dangerous and tomorrow you may need a better rope.


    Hmm ... sorry, but I don't need any more Perl-level access to the
    internal data structures of the interpreter in order to program in Perl/
    for perl than I need userspace access to internal kernel data structures
    for writing UNIX(*) applications.

    > The "Perl Hacks" segment on PadWalker shows a couple of cases where
    > breaking encapsulation is useful and a very apt rationale:
    >
    > "It's scary and wrong, but sometimes it's just what you need".


    The actual example is "dark magic you don't have to understand in order
    to use" (this cries out loud for banging some sense into the guy who
    wrote this --- there's nothing magical about clumsily written C code
    accessing perl data structures and trying to use something one doesn't
    understand is a recipe for disaster more of than not) in order to do
    something which could have been accomplished by inserting a
    print-statement into the example closure or even by running the
    unadorned program via perl debugger and using a watch point.
    Rainer Weikusat, Mar 25, 2014
    #17
    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. rp
    Replies:
    1
    Views:
    490
    red floyd
    Nov 10, 2011
  2. Anthony Martinez
    Replies:
    4
    Views:
    258
    Robert Klemme
    Jun 11, 2007
  3. Michal Suchanek
    Replies:
    6
    Views:
    214
    Nobuyoshi Nakada
    Jun 13, 2007
  4. Srijayanth Sridhar
    Replies:
    19
    Views:
    591
    David A. Black
    Jul 2, 2008
  5. Replies:
    14
    Views:
    178
    C.DeRykus
    Dec 22, 2009
Loading...

Share This Page