[Koha-bugs] [Bug 25491] Perl warning at the login page of installer

bugzilla-daemon at bugs.koha-community.org bugzilla-daemon at bugs.koha-community.org
Wed Jun 17 20:54:17 CEST 2020


https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=25491

--- Comment #3 from Andrew Nugged <nugged at gmail.com> ---
If we talk about:

    if ( $info{'invalid_username_or_password'} &&
         $info{'invalid_username_or_password'} == 1) { ...

so this is ok,

there is first-level key check, not a sub-key, so no autovivification
and at the same time, this combines both "existence of the key" check + "Perl
false" check (i.e. undef too) on the left "&&" part. 

Autovivification happens for parent keys or array elements in complex data
structures if we will go for a subkey from a key, because Perl first needs to
create all chain or parent structure/refs (autovivification here) to reach the
deepest requested one, but that deepest-requested one does not created.

So for the top-level key it is ok to check existence + Perl non-false in single
"$hash{key}" form.


( docs references:

  [https://perldoc.perl.org/perlref.html] "Before this statement, $array[$x]
  may have been undefined. If so, it's automatically defined with a hash
  reference so that we can look up {"foo"} in it. Likewise $array[$x]->{"foo"}
  will automatically get defined with an array reference so that we can look
  up [0] in it. This process is called autovivification." 


  brian d foy's: 
  https://www.effectiveperlprogramming.com/2011/04/understand-autovivification/ 


  my own example (Peter & Salava, pls pay attention too):

  # this is okay, no autovivification and also this prevents "undef" warning:
  if ($info{invalid_username_or_password} &&
      $info{invalid_username_or_password} == 1) { ...

  # this below one is useless, because still no undef-proteciton,
  # so warning etmitted in case key has undef:
  if (exists $info{invalid_username_or_password} &&
             $info{invalid_username_or_password} == 1) { ...

  # this is overreaction yet will work correctly:
  if (exists  $info{invalid_username_or_password} &&
      defined $info{invalid_username_or_password} &&
              $info{invalid_username_or_password} == 1) { ...

  # this is bad, upper level key (config_set) autovivified:
  if ($info{config_set}{invalid_username_or_password} &&
      $info{config_set}{invalid_username_or_password} == 1) { ...

  # this is bad, upper level key (config_set) autovivified, even you have 
  # 'exists', because before 'exists' Perl solves sub-hash deref:
  if (exists $info{config_set}{invalid_username_or_password} &&
             $info{config_set}{invalid_username_or_password} == 1) { ...

)

P.S. sorry for such a long example, I wanted all related people to read & train
this and maybe we can refer to this comment one day for my other students :P.

Proof of concept for the local Perl to run & see:

====== vivify.pl ======

#!/usr/bin/env perl
use Modern::Perl; use Data::Dumper qw(Dumper); $|=1; $, = ", ";
$Data::Dumper::Terse = 1; $Data::Dumper::Indent = 0;

my %H = (
    user => undef
); 
say __LINE__, Dumper \%H;
# 8, {'user' => undef}


# this is okay, no autovivification and also this prevents "undef" warning:
say __LINE__,
    $H{user} && $H{user} == 1
        ? 'User exists, defined, and == 1' : 'User absent';
# 13, User absent
say __LINE__, Dumper \%H;
# 17, {'user' => undef}

# this below one is useless, because still no undef-proteciton,
# so warning etmitted in case key has undef:
say __LINE__,
    exists $H{user} && $H{user} == 1
# Use of uninitialized value $H{"user"} in numeric eq (==) at vivify.pl line
23.
        ? 'User exists and == 1' : 'User absent';
# 22, User absent
say __LINE__, Dumper \%H;
# 27, {'user' => undef}


# this is overreaction yet will work correctly:
say __LINE__,
    exists $H{user} && defined $H{user} && $H{user} == 1
        ? 'User name exists, defined, and == 1' : 'User name absent';
# 32, User name absent
say __LINE__, Dumper \%H;
# 36, {'user' => undef}


%H = ();
say __LINE__, Dumper \%H;
# 41, {}

# this is wrong, upper level key (user) unexpectedly autovivified:
say __LINE__,
    $H{user}{name} && $H{user}{name} == 1
        ? 'User name exists and == 1' : 'User name absent';
# 45, User name absent
say __LINE__, Dumper \%H;
# 49, {'user' => {}}


%H = ();
say __LINE__, Dumper \%H;
# 54, {}

# this is wrong, upper level key (user) unexpectedly autovivified:
say __LINE__,
    exists $H{user}{name} && defined $H{user}{name} && $H{user}{name} == 1
        ? 'User exists and == 1' : 'User absent';
# 58, User absent
say __LINE__, Dumper \%H;
# 62, {'user' => {}}

-- 
You are receiving this mail because:
You are watching all bug changes.


More information about the Koha-bugs mailing list