http://qs321.pair.com?node_id=1045267

ravi06 has asked for the wisdom of the Perl Monks concerning the following question:

my %book = ( 'name' => 'abc', 'author' => 'monk', 'isbn' => '123-890', 'issn' => '@issn', ); my %chapter = ( 'title' => 'xyz', 'page' => '90', );
How do I incorporate %book inside %chapter through reference so that when I write "print $chapter{name}", it should print 'abc'?

Replies are listed 'Best First'.
Re: How can I populate attributes of a hash into another ?
by 2teez (Vicar) on Jul 19, 2013 at 07:40 UTC

    ravi06,
    I thought, a chapter should be a subset of a book and not the other way round? However, if you are sure of what you wanted, knowing that the key of hash MUST be unique, then you can do like so:

    use warnings; use strict; use Data::Dumper; my %book = ( 'name' => 'abc', 'author' => 'monk', 'isbn' => '123-890', 'issn' => '@issn', ); my %chapter = ( 'title' => 'xyz', 'page' => '90', ); ## VOIR HERE my @temp_arr = keys %book; @chapter{@temp_arr} = @book{@temp_arr}; print Dumper \%chapter; print $/, $chapter{name},$/; #prints abc
    NOTE: And what about '@issn' in your script? Like you have it, if it is an array variable, it won't interpolate!! Just saying...

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      Calls to keys and values are guaranteed to return data in a consistent way, so you could simply write:

      @chapter{ keys %book } = values %book;
Re: How can I populate attributes of a hash into another ?
by hdb (Monsignor) on Jul 19, 2013 at 07:34 UTC

    The closest I can think of is this:

    use strict; use warnings; my %book = ( 'name' => 'abc', 'author' => 'monk', 'isbn' => '123-890', 'issn' => '@issn', ); my %chapter = ( 'title' => 'xyz', 'page' => '90', ); $chapter{book} = \%book; print $chapter{book}{name},"\n";
Re: How can I populate attributes of a hash into another ?
by BrowserUk (Patriarch) on Jul 19, 2013 at 10:52 UTC

    As others have also pointed out, you cannot transparently 'inherit' one hash from another; but wouldn't

    print $chapter{book}{name};

    Be both acceptable and superior as its clear that it's the book's name, not the chapter's name, being printed

    (Also, you could then use 'title' for both the title of the book and the title of the chapters if you wanted to):

    #! perl -slw use strict; my %book = ( 'name' => 'abc', 'author' => 'monk', 'isbn' => '123-890', 'issn' => '@issn', ); my %chapter = ( 'book' => \%book, 'title' => 'xyz', 'page' => '90', ); print $chapter{book}{name}; __END__ C:\test>junk82 abc

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: How can I populate attributes of a hash into another ?
by LanX (Saint) on Jul 19, 2013 at 10:40 UTC
    Answering the question as expressed ("through reference"):

    The only possibility to make %chapter act as a proxy for %book is using hash ties.

    I won't go into details since this is certainly a XY problem!

    Most probably you just need to copy

    %chapter=(%chapter,%book)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: How can I populate attributes of a hash into another ?
by packetstormer (Monk) on Jul 19, 2013 at 07:21 UTC

    Why not just merge the two hashes? Are the keys unique? Is there anything to link the hashes together e.g ISBN or unique book ID?

Re: How can I populate attributes of a hash into another ?
by Random_Walk (Prior) on Jul 19, 2013 at 14:12 UTC

    I would flip the data model around. One book may contain multiple chapters. They will also normally be sequentially numbered so I'd make an array of them.

    #!/usr/bin/perl use strict; use warnings; my %book = ( name => 'ABC - an adventure', author => 'monk', isbn => '123-890', issn => '@issn', chapter => [], ); $book{chapter}[1] = { name => 'Testing Times', page => 2, }; $book{chapter}[2] = { name => 'Importing Hash', page => 99, }; print "$book{name}\n"; my $i = 1; while (exists $book{chapter}[$i]) { print "Ch: $i '$book{chapter}[$i]{name}' ($book{chapter}[$i]{page} +)\n"; $i++ }
    Output:
    ABC - an adventure Ch: 1 'Testing Times' (2) Ch: 2 'Importing Hash' (99)

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
Re: How can I populate attributes of a hash into another ?
by Anonymous Monk on Jul 19, 2013 at 07:05 UTC
Re: How can I populate attributes of a hash into another ?
by Rahul6990 (Beadle) on Jul 19, 2013 at 07:36 UTC
    Hi Good Morning , Perhaps this is what you are looking for:

    %chapter = ( 'book'=> { 'name' => 'abc', 'author' => 'monk', 'isbn' => '123-890', 'issn' => '@issn', }, 'title' => 'xyz', 'page' => '90', ); $value = $chapter{'book'}{'name'}; print ":$value:";
Re: How can I populate attributes of a hash into another ?
by nemesdani (Friar) on Jul 19, 2013 at 07:03 UTC
    No way. If you add a reference to the %book hash,  print $chapter{name} will still not print what you want. Why do you want to add a book under chapter anyway? Are you sure your data model is good?


    I'm too lazy to be proud of being impatient.
      Maybe there is a way. You could create a tied hash which looks up key/values somewhere else if they are not present.

      However that's something I definitely do not recommend at all. This way lies loss of sanity and lots of hairpulling.

      Yes. I am sure about the data model.
Re: How can I populate attributes of a hash into another ?
by Anonymous Monk on Jul 19, 2013 at 10:23 UTC
    map { $chapter{$_} = $book{$_} } keys %book;