princepawn has asked for the wisdom of the Perl Monks concerning the following question:

I am getting two warnings, yet my code seems to run without error. Both are in line 73. The warnings are:
  • "Odd number of elements in hash assignment"
  • "Use of uninitialized value"
    sub diff_aref { my ($aref1, $aref2) = @_; my %href = undef; #### this is line 73 @href{@{$aref2}} = @{$aref2}; grep { not defined($href{$_}) } @$aref1; }
    • Comment on Odd number of elements in hash assignment warning. Use of uninitialized value warning
    • Download Code
  • Replies are listed 'Best First'.
    Re: Odd number of elements in hash assignment warning. Use of uninitialized value warning
    by Fastolfe (Vicar) on Sep 21, 2000 at 20:21 UTC
      Your statement:
      my %hash = undef;
      is incorrect. In this context, since %hash is more like an array than a scalar, 'undef' is actually a value you're trying to set to %hash. This "list-ish" behavior lets you do stuff like this:
      my %hash = ( key => "value", key2 => "value2" ); # OK my %hash = ( "key", "value", "key2", "value2" ); # OK (same) my %hash = ( "key", "value", "key2" ); # WRONG - gives the + error you describe my %hash = ( undef ); # WRONG - equivalen +t to what you were doing!
      If you're wanting to "un-set" %hash, try either:
      undef %hash; %hash = (); # empty list = empty hash
      But in your code above, this is unnecessary. Simply declaring my %hash; is sufficient, since in Perl this would initialize your hash to be empty.
    Re: Odd number of elements in hash assignment warning. Use of uninitialized value warning
    by Adam (Vicar) on Sep 21, 2000 at 20:16 UTC
      Don't assign your hash undef, instead assign it an empty array ()

      Also, use exists when testing for hash elements.

    Re: Odd number of elements in hash assignment warning. Use of uninitialized value warning
    by merlyn (Sage) on Sep 21, 2000 at 20:17 UTC
      Yes. You've committed the same flaw as:
      @array = undef;
      which is that it makes @array have one element of undef, not zero elements (empty).

      Do not use undef for anything other than the scalar undefined value. Your program could use:

      my %href = ();
      But I'd probably flag that on code review as "potential signs of cluelessness - look very carefully at the remaining code", since that's also the default, and people who override the default with the default tend to make other mistakes. {grin}

      -- Randal L. Schwartz, Perl hacker

        "potential signs of cluelessness - look very carefully at the remaining code", since that's also the default

        I think what he means (in less sarcastic terms :) ) is that there is no reason not to simply have:

        my %hash;
        I'm sure some people would defend variable initialization, even to the default, but in general I think it's more readable to simply accept the default (undef) that Perl assigns. Trust Perl. Perl is your friend.
          Initializing variables with undef or () upon creation is a best practice for those who might ever have their code run under mod_perl.
        You are right. And by the way, Net::FTP was causing problems for us along these lines... it is best to get an array ref from Net::FTP instead of an array because you will get an array with one element (undef) if there are no files resulting from an $ftp->ls call.

        But anyway, undef %h or undef @x will work fine. But the noun form is the one that I errantly used.

        What a dummy am I.

        oops, there I go again. That should've been What a dummy I am... misplaced noun and verb again. heh.