Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

How to return values from a hash?

by perl-diddler (Hermit)
on Mar 30, 2013 at 00:34 UTC ( #1026212=perlquestion: print w/replies, xml ) Need Help??
perl-diddler has asked for the wisdom of the Perl Monks concerning the following question:

I have a Hash of Hashes in an object. It's accessed through access routines, but I'm trying to pull a hash out of it via a key (pathnames pointing to logical volume info). However, when the access routine returns the value, it's returning the dereferenced HASH, not the pointer to the hash. However if I put a \ in front of the hash in the access routine, then the calling routine gets "not a hash ref". I.e. Access routine is returning
$p->{hashname}{'path'}=<another hashref>;
But that has is being expanded -- in the debugger it says it is being returned in a scalar context. How can I annotate the 'another hash' so it gets returned as a reference? I know how too force it into scalar context, but I need to force it into staying as a reference...I'm sure this is a simple perl-101 question, but I'm just missing a big enough cluestick! ;-(

Anyone wanna hit me over the head w/one?... ;-) Thanks! (some days I have to look at my license to remember my name!)

Replies are listed 'Best First'.
Re: How to return values from a hash?
by LanX (Chancellor) on Mar 30, 2013 at 01:08 UTC
    What you are describing is rather cryptic and doesn't make much sense w/o showing code.


    return $p->{hashname}{'path'};

    is perfect to return a hashref.


    if it's returning a list¹ , put curlies around the call, to create a new ano hash.

     $hash_ref = { $obj->meth() } ;

    And if it's supposed to return a list but you call it in scalar context, you are only getting the last element from that list.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    ¹) a "dereferenced hash" is not an entity Perl can return, only the list of elements.

      This is what 'db' is showing:
      > perl -d -X x /home Loading DB routines from version 1.37 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. main::( our $VERSION = '0.0.2'; DB<1> b Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp DB<2> c Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp( 832: my $lvm = shift; DB<2> s Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp( 833: my ($base_lvh, $lv_mp) = @_; DB<2> s Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp( 834: my $diff_dev = pathcat("/dev", 835: + $base_lvh->vg_name, $base_lvh->lv_name . ".diff"); DB<2> n Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp( ------------ #### here is where I have the problem the return from the 'by_mp' -- +you'll see $lv_mp."diff" a bit below.... 837: my $bdiff_lvh = (@_ && $lvm->by_mp($lv_mp . ". +diff")) or 838: $lvm->by_devpath( 839: pathcat("/dev", $base_lvh->vg_name, $b +ase_lvh->lv_name . ".diff")); DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/ 793: sub by_mp(;$) { my $map = shift; my $c = ref $map || $ +map; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/ 793: sub by_mp(;$) { my $map = shift; my $c = ref $map || $ +map; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/ 794: bless $map = $map->new(), $c unless ref $map; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/ 795: my $arg = $_[0]; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/ 796: $map->_init_by_mp unless $map->{_by_mp}; DB<2> p $arg /home.diff ----- ^^Above^^ is the string I passed in... so then I 'r'eturn from the rou +tine and see: DB<3> r scalar context return from Lvm::Maps::by_mp: '_chunksize' => undef '_d_type' => undef '_fs_perms' => undef '_fs_type' => Fs::Xfs=HASH(0x2198c08) 'mount_ops' => 'nodiratime,noatime,swalloc' 'name' => 'xfs' 'snapshot_ops' => 'nouuid,norecovery,ro' '_fs_type_name' => 'xfs' 'cfg' => undef 'fs_mp' => undef 'lv_attr' => '-wc-ao---' 'lv_kernel_major' => 254 'lv_kernel_minor' => 9 'lv_name' => 'Home.diff' 'lv_path' => '/dev/HnS/Home.diff' 'lv_size' => 549755813888 'origin' => '' 'vg_extent_size' => 4194304 'vg_name' => 'HnS' Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp( 840: die P "Can't find \"diff\" dir for vol %s by m +ount or device path", $lv_mp 841: unless ref $bdiff_lvh;

      Now you are right, I could just throw curlies around that and create a NEW HASH from my **reference**, but gosh darnit... I'd rather it NOT dereference it in the the first place! Isn't the fact that it "expands it", then is stuck in a new anonymous hash, even meaning that not only has it done extra work, but the new hash isn't even the same hash (in memory) as they old (i.e. if I changed something in the hash, it would change the anon-copy, as I didn't get back the pointer I wanted to the original hash.

      Does that make it more clear?

      If you can tell by the line numbers, -- that's 1 of 2 main program files, with scads of little support libs thrown in for fun. So I'm just not sure how to prevent it from "returning the expansion of the HASH pointed to by the reference...(without, as you say, creating a new anon-hash -- which isn't really returning my reference that I want, at all!)

        Does that make it more clear?

        Nope. Just a big mess of unintelligible console output.

        Returning a hashref from a subroutine is simple and straightforward:

        %hash = ( subhash1 => { a=>1, b=>2 }, subhash2 => { c=>3, d=>4 } );; sub getSubhash { return $hash{ $_[0] } };; pp getSubhash( 'subhash1' );; { a => 1, b => 2 } pp getSubhash( 'subhash2' );; { c => 3, d => 4 }

        Which means you must be doing something wrong.

        So, how about you post:

        • The source code of the subroutine or method that is (meant) to be returning the reference.
        • The (actual) line of code that is calling it.

        Then we'll be able to point out what you are doing wrong.

        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 to return values from a hash?
by Anonymous Monk on Mar 30, 2013 at 02:45 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1026212]
Approved by Old_Gray_Bear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2017-01-22 06:49 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (186 votes). Check out past polls.