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}?
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
|
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.
| [reply] [Watch: Dir/Any] |
|
|
|
|
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
"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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
> 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}} ?
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
|
|
$$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
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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>
| [reply] [Watch: Dir/Any] [d/l] |
|
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.
| [reply] [Watch: Dir/Any] |
|
Understandably ... he's too busy telling us how to improve this site to improve his code... ;-)
| [reply] [Watch: Dir/Any] |
|
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!)
| [reply] [Watch: Dir/Any] [d/l] |
|
|