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

Re^2: How to return values from a hash?

by perl-diddler (Hermit)
on Mar 30, 2013 at 02:19 UTC ( #1026223=note: print w/ replies, xml ) Need Help??


in reply to Re: How to return values from a hash?
in thread How to return values from a hash?

This is what 'db' is showing:

> perl -d snapper.pl -X x /home Loading DB routines from perl5db.pl version 1.37 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. main::(snapper.pl:5): 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(snapper.pl:832): 832: my $lvm = shift; DB<2> s Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp(snapper.pl:833): 833: my ($base_lvh, $lv_mp) = @_; DB<2> s Lvm::Snapshot_Ops::lvm_BaseDiff_Lvh_4_Base_opt_mp(snapper.pl:834): 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(snapper.pl:837): ------------ #### 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/Lvm_Utils.pm:793): 793: sub by_mp(;$) { my $map = shift; my $c = ref $map || $ +map; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/Lvm_Utils.pm:793): 793: sub by_mp(;$) { my $map = shift; my $c = ref $map || $ +map; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/Lvm_Utils.pm:794): 794: bless $map = $map->new(), $c unless ref $map; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/Lvm_Utils.pm:795): 795: my $arg = $_[0]; DB<2> s Lvm::Maps::by_mp(/home/law/bin/lib/Lvm_Utils.pm:796): 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(snapper.pl:840): 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!)


Comment on Re^2: How to return values from a hash?
Download Code
Re^3: How to return values from a hash?
by BrowserUk (Pope) on Mar 30, 2013 at 02:32 UTC
    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.
      At the bottom of the call stack, is a 'Vars' routine to wrap fields in a hash. The relevant parts:
      sub _Var ($$$;$) { # Wrkhorse code for manu +fctrd Vars #note $p->obj, $vn=varname, $wa=wantarray val my ($__, $p, $vn, $wa)=@$_; $_=$__; '$_' my $v = $p->{$vn}; # value my $rfv = ref $v; # type(ref) of var ...... } elsif ($rfv == 'HASH') { my $subvar=$arg; ## 1 var w/hash is is a key $p->{$vn}{$subvar}=$_[0] if @_; ## another? =>assign va +lue return $p->{$vn}{$subvar}; <- returns has here.
      That is called in sub 'by_mp' that takes care of init stuff and handles accessing the field: _by_mp in this case:
      sub by_mp(;$) { my $map = shift; my $c = ref $map || $map; ...init... my $arg_lvh = $map->_by_mp($arg); if (ref $arg_lvh) { $arg_lvh->fs_mp($arg); return $arg_lvh; #<----seems to return from here } my $devno = (stat $arg)[0]; $arg_lvh = $map->by_devno($devno); return undef unless $arg_lvh; die P "by_mp: by_devno(%s) returned %s, of type \"%s\", not a ref\ +n", $devno, $arg_lvh, ref $arg_lvh unless ref $arg_lvh; $map->_by_mp($arg, $arg_lvh); $arg_lvh->fs_mp($arg); return $arg_lvh; }
      That is called in the level of code where I detect the problem:
      sub lvm_BaseDiff_Lvh_4_Base_opt_mp ($;$) { my $lvm = shift; my ($base_lvh, $lv_mp) = @_; my $diff_dev = pathcat("/dev", $base_lvh->vg_name, $base_lvh->lv_name . ".diff"); #TPe "diff_dev=%s", $diff_dev; # next is call to by_mp -- here is where I don't seem to be #getting a reference back. my $bdiff_lvh = $lvm->by_mp($lv_mp.".diff") if @_; $bdiff_lvh = $lvm->by_devpath($diff_dev) unless ref $bdiff_lvh; ## commented version below was orig -- trying above -- ## seems to work better, but seems a bit random... #my $bdiff_lvh = (@_ && $lvm->by_mp($lv_mp . ".diff") or # $lvm->by_devpath($diff_dev)); die P "Can't find \"diff\" dir for vol %s by mount or device path" +, $lv_mp unless ref $bdiff_lvh; $bdiff_lvh->fs_mp($lv_mp) unless $bdiff_lvh->fs_mp; $bdiff_lvh->fs_type_name($base_lvh->fs_type_name) unless $bdiff_lvh->fs_type_name;

        Unless I am getting very short-sighted, _Var() is never called by either by_mp() or lvm_BaseDiff_Lvh_4_Base_opt_mp(), so why are you attributing the error to the return from that subroutine?


        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.
        I have some doubts about the following code:
        sub _Var ($$$;$) { # Wrkhorse code for manufctrd Vars #note $p->obj, $vn=varname, $wa=wantarray val my ($__, $p, $vn, $wa)=@$_;
        1. Why are you using prototypes in the subroutine definition? Unless you have a very very good reason to use prototypes, you should not use prototypes. And using prototypes to check the type and number of arguments is not a good reason.
        2. What do you think @$_ does? You are dereferencing the global default variable $_ into an array. Didn't you rather want to use the @_ variable which contains the parameters of the subroutine call?
        3. Are you using strict and warnings?

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1026223]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (20)
As of 2014-08-27 14:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (239 votes), past polls