Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^5: 5.24 -> 5.28 -- what has changed in autovivification?

by leszekdubiel (Scribe)
on Apr 18, 2020 at 20:45 UTC ( [id://11115744]=note: print w/replies, xml ) Need Help??


in reply to Re^4: 5.24 -> 5.28 -- what has changed in autovivification?
in thread 5.24 -> 5.28 -- what has changed in autovivification?

I've found:

The documentation for the exists operator no longer says that autovivification behaviour "may be fixed in a future release". We've determined that we're not going to change the default behaviour. perl #127712

perl #127712

I understand that there are only two options:

  • NO autovivification. Then you can't do if (exists $h{a}{b}{c}{d}) { ... }, because you try to dereference non-existent $h{a}{b}, then you get error.
  • Or default (*) behaviour, WITH autovivification, that is when you do if (exists $h{a}{b}{c}{d}) { ... }, then perl will gracefully create $h{a}, $h{a}{b}, $h{a}{b}{c} for you :) :)
(*) -- this is the default behaviour that creators of perl decided not to change

I hoped to find solution that doesn't autovifify when existence is checked, so I could just act like this if (exists $h{a}{b}{c}{d}) { ... } and not like this if (exists $h{a} && exists $h{a}{b} && exists $h{a}{b}{c} && exists $h{a}{b}{c}{d}) { ... }

My preferred default behaviour would be to return undef for $h{a}{b}{c}{d} and NOT create $h{a}, $h{a}{b}, $h{a}{b}{c}... This is not possible.

Replies are listed 'Best First'.
Re^6: 5.24 -> 5.28 -- what has changed in autovivification?
by haukex (Archbishop) on Apr 18, 2020 at 22:08 UTC
    I understand that there are only two options

    In core Perl, yes (Update: actually, autovivification isn't even in the core). But choroba showed one possibility, and writing a single-purpose routine isn't difficult either (I've admittedly compacted it a bit):

    use warnings; use strict; sub dive { my $r = shift; $r = ref $r eq 'HASH' && exists $$r{$_} ? $$r{$_} : return for @_; return $r } use Test::More; my $h = { a => { b => { c => { d => 'e' } } } }; is dive($h, qw/ a /), $h->{a}; is dive($h, qw/ a b /), $h->{a}{b}; is dive($h, qw/ a b c /), $h->{a}{b}{c}; is dive($h, qw/ a b c d /), 'e'; is dive($h, qw/ a b c d e /), undef; is dive($h, qw/ a x /), undef; is dive($h, qw/ a b x /), undef; is dive($h, qw/ a x y /), undef; is dive($h, qw/ a b x y /), undef; is dive($h, qw/ x /), undef; is dive($h, qw/ x y /), undef; is dive($h, qw/ x y z /), undef; is_deeply $h, { a => { b => { c => { d => 'e' } } } }; done_testing;

    Update: Both of the links in your post appear to be broken. I assume you were trying to link to perl5280delta and RT#127712.

      Thank you for code and making links good.
Re^6: 5.24 -> 5.28 -- what has changed in autovivification?
by choroba (Cardinal) on Apr 18, 2020 at 21:44 UTC
    > This is not possible.

    You've been given a solution by haukex in Re: 5.24 -> 5.28 -- what has changed in autovivification?.

    Do you need more details? Here's an example:

    #! /usr/bin/perl use warnings; use strict; use feature qw{ say }; use Data::Diver qw{ Dive }; use Data::Dumper; my $h1 = {}; my $h2 = {a => {b => {c => 42}}}; for my $h ($h1, $h2) { say "Found $h->{a}{b}{c}" if Dive($h, qw( a b c )); } print Dumper $h1, $h2;
    Output:
    Found 42 $VAR1 = {}; $VAR2 = { 'a' => { 'b' => { 'c' => 42 } } };

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2024-04-19 22:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found