Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Dereferencing in blessed object

by LanX (Saint)
on Feb 25, 2021 at 23:08 UTC ( [id://11128809]=note: print w/replies, xml ) Need Help??


in reply to Dereferencing in blessed object

> The output is exactly as expected.

you should use warnings ... always!

Reference found where even-sized list expected at - line 16.

the only reason why your output seems to be correct is that you are dereferencing the $vars hash-ref from the closure° not the supposedly passed %vars .

please note that %vars and $vars are two different variables in separate namespaces.

try

my ($value, $vars) = @_;

and do yourself a favor and write

$vars->{test}; instead of $$vars{test}

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

°) "global" might be easier to understand

Update

Stripped quotes from hash-key

Replies are listed 'Best First'.
Re^2: Dereferencing in blessed object
by Bod (Parson) on Feb 25, 2021 at 23:16 UTC
    the only reason why your output seems to be correct is that you are dereferencing the $vars hash-ref from the closure

    Oh!
    Yes, changing the variable name in the subroutine 'breaks' it as expected...now I understand why the different bits of seemingly identical code behave differently! Thanks Rolf.

    $vars->{'test'}; instead of $$vars{test}

    I did have $vars->{'test'}; in there at one point whilst testing it.
    Why is this preferable to $$vars{test}?

      Both are legal syntax, the overwhelming mainstream tends to $vars->{'test'} probably since PBP.

      So many might have problems reading the other form.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      Oh! Yes, changing the variable name in the subroutine 'breaks' it as expected
      To avoid wasting time chasing silly mistakes like these in future, I suggest you always -- as a matter of routine habit -- order your file with functions first and mainline at the end.

      An alternative is to leave the mainline first but put a bare block around it, to ensure mainline global variables don't accidentally leak into the subroutines defined below.

        I suggest you always -- as a matter of routine habit -- order your file with functions first and mainline at the end

        Whilst that makes sense, it somehow feels wrong.
        Probably because I have always written code with the subroutines at the end. I recall it being a bit of a revelation when I realised that it wasn't compulsory to have them at the end!

        An alternative is to leave the mainline first but put a bare block around it

        That seems very sensible. It's also something that can be applied to existing code relatively easily.

      Why is this preferable to $$vars{test}?

      I don't see objectively why it would be, TBH. If you start getting into deeper structures then the increasing levels of syntax needed to deal with the $$foo{bar} equivalents is going to get messy. For a simple hash though there's little difference.

      Personally I do use the arrow operator as it (subjectively) stands out more clearly to me in an eye-parse. But I do not quote hash keys (whether in references or otherwise) unless necessary. If I see code like $vars->{'test'} it makes me pause and wonder why the key is quoted.

      Whatever you decide to do, make a plan and stick to it. Having your own coding standard, at least within one project, will be a benefit. Inconsistency is the bug's friend.


      🦛

        "Personally I do use the arrow operator as it (subjectively) stands out more clearly to me in an eye-parse."

        Yep, me too.

        I like being able to understand code at a very quick glance, and at a quick glance, I would (and do) see $$var{thing} as a hash, not a hash reference. $var->{thing} is very unambiguous and doesn't require a second look, ever.

        Because scalar references are so infrequently used, I would expect to have to look twice at a variable with the double $$ to understand why the author has used one. An in-memory variable-based file is one example, and is a special case that often does require a bit more than just a glance.

        > If you start getting into deeper structures then the increasing levels of syntax needed to deal with the $$foo{bar} equivalents is going to get messy.

        Could you give an example? I hope you are not referring to redundant -> arrows at deeper levels.

        > But I do not quote hash keys

        Neither do I, I just copy pasted from B::Deparse's output.

        edit

        > I don't see objectively why it would be,

        Like Bliako said, I have trouble parsing precedence, and I don't think it's only a matter training.

        can you immediately tell if $$x{key} means ${$x}{key} or ${$x{key}} ?

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      $$vars{'test'} is a visual pain for me because of the split millisecond where I ask myself about precedence. OTH the -> in $vars->{'test'} dates back to at least C where is used in exactly the same way and context.

      Performance-wise I don't think there is a difference (OSX 10.13 and perl 5.28.3):

      use Benchmark qw( cmpthese ); cmpthese(-5, { deref => 'use strict; use warnings; my $x = { map { $_ => rand + } 1..50 }; $x->{$_} = $_ for 1..100', none => 'use strict; use warnings; my $x = { map { $_ => rand + } 1..50 }; $$x{$_} = $_ for 1..100' }); Rate deref none deref 12483/s -- -1% none 12611/s 1% -- Rate none deref none 11938/s -- -0% deref 11967/s 0% --

      Or,

      use Benchmark qw( cmpthese ); cmpthese(-5, { deref => 'use strict; use warnings; srand 42; my $x = { map { rand() => rand() } 1..50 }; srand 42; $x->{rand()} = rand() for 1..100', none => 'use strict; use warnings; srand 42; my $x = { map { rand() => rand() } 1..50 }; srand 42; $$x{rand()} = rand() for 1..100' });

      For benchmarks see also: https://stackoverflow.com/questions/18984323/how-expensive-is-it-to-dereference-an-array-ref-in-perl

      bw, bliako

        > Performance-wise I don't think there is a difference (OSX 10.13 and perl 5.28.3):

        That would be surprsing, it's compiled to the same op-code.

        C:\WINDOWS\System32>perl -MO=Deparse -e"$$x{key}" $x->{'key'}; -e syntax OK C:\WINDOWS\System32>perl -MO=Concise -e"$$x{key}" 4 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter v ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 - <1> ex-helem vK/2 ->4 3 <+> multideref($x->{"key"}) vK ->4 - <0> ex-gv s ->3 -e syntax OK C:\WINDOWS\System32>perl -MO=Concise -e"$x->{key}" 4 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter v ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 - <1> ex-helem vK/2 ->4 3 <+> multideref($x->{"key"}) vK ->4 - <0> ex-gv s ->3 -e syntax OK C:\WINDOWS\System32>

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re^2: Dereferencing in blessed object
by marto (Cardinal) on Feb 26, 2021 at 07:34 UTC

    "you should use warnings ... always!"

    Despite being told and shown why this is a good idea, multiple times, it's still not sinking in.

      Understandably ... he's too busy telling us how to improve this site to improve his code... ;-)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        I think the root node shows a willingness to learn, and I don't think Bod deserves to be picked on this much.

        (Bod: ... yet ;-) Upgrading a legacy codebase can be a difficult and long process, but for any new code you write, listen to the advice given so far!)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-03-29 00:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found