Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Why is "odd number of elements in hash assignment" warning and not error?

by Dallaylaen (Chaplain)
on Feb 18, 2015 at 13:25 UTC ( [id://1117094]=perlquestion: print w/replies, xml ) Need Help??

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

Hello dear esteemed monks,

This has probably been asked before, but my google-fu cannot get through numerous "I have a warning, what should I do"-type questions. So I dare to ask:

Why does "Odd number of elements in hash assignment" condition cause a warning and not error?

Here are some reasons which may cause this warning:

  • hashref assigned to a hash;
  • a function returning nothing (not undef) in list context;
  • putting array instead of arrayref into hash assignment (as in %hash = (array => qw(foo bar)); );
  • misplaced parenthesis somewhere;
  • missing argument(s) in a function call.

I wonder which of the abovementioned is a "shoddy but still valid programming practice" and not a coding error, plain and simple? To make matters worse, if the missing hash value comes (well, doesn't come) in the middle of assignment, it causes the values and keys to change places.

But maybe there are still some reasons to keep this warning a warning? I would like to see what I'm missing.

Of course, I can use warnings FATAL => "all"; or just FATAL => "misc"; (here's another WTF - why "misc" category and not, say, "hash"/"odd"?!?!). Still I don't (fortunately) write ALL the code I have to deal with.

  • Comment on Why is "odd number of elements in hash assignment" warning and not error?

Replies are listed 'Best First'.
Re: Why is "odd number of elements in hash assignment" warning and not error?
by LanX (Saint) on Feb 18, 2015 at 13:36 UTC
    It's a runtime check and doesn't necessarily mean that your program will break (still a hash, the last value will simply be undef )

    IOW it's not a fatal problem!

    But you are free to turn it personally into FATAL.

    update

    But I have to admit that I'd like to see more compile time checking.

    Cheers Rolf

    PS: Je suis Charlie!

      Sure, I can fatalize some warnings. The problem is, there are a lot of different warnings under this misc group, caused by various conditions.

      Search for W misc in perldoc perldiag was an enlightening reading, and I had a good laugh reproducing some of those beasts. Most of those conditions do look like a loaded gun pointed at a foot, but not all.

        > there are a lot of different warnings under this misc group,

        just overwrite warn or die in %SIG according to your needs.

        > Most of those conditions do look like a loaded gun pointed at a foot, but not all.

        You know I love criticizing Perl, its part of my mentality to openly discuss room for improvements. Call me an anti fan boy.

        But whenever I try to get used to supposedly better designed languages (JS, Python, Ruby, ...) I'm instantly stumbling over something weird.

        And the answer I normally get after asking "why" is "yeah for historical reasons we had to do it like this and can't change it now"

        Misc is a good point, please send a feature request via Perlbug

        Cheers Rolf

        PS: Je suis Charlie!

Re: Why is "odd number of elements in hash assignment" warning and not error?
by AnomalousMonk (Archbishop) on Feb 18, 2015 at 17:50 UTC
    a function returning nothing (not undef) in list context;

    I don't get this point. I take it to mean the assignment of an empty list to a hash, but none of the circumstances that I can think of that involve such an assignment elicit any warning, nor should they IMHO: an empty hash is a valid hash.

    c:\@Work\Perl\monks>perl -wMstrict -le "my %hash; my %hasi = (); my %hasj = empty_list(); ;; print scalar keys %hasj; ;; sub empty_list { return; } " 0
    Can you expand a bit on this point?


    Give a man a fish:  <%-(-(-(-<

      Sure. I should've given examples to begin with... Here's a sample:

      use strict; use warnings; use Data::Dumper; my %hash = (0 => foo(0), 3 => foo(3), 7 => foo(7)); print Dumper(\%hash); sub foo { return unless $_[0]; return $_[0] * 2; };

      Now what one probably expected is (0 => undef, 3=>6, 7=>14). However, the real output would be (0 => 3, 6 => 7, 14 => undef) which is kinda weird. This is because hash assignment forces list context, so return; returns empty list which wreaks havoc on the rest of the hash. It can be fixed by arbitrary scalar foo(...) or by returning undef explicitly (perlcritic would complain about it though).

      I understood that point to mean one of these two, probably the first:

      sub nothing { return } sub something { return undef } my %foo = ( abc => nothing() ); my %bar = ( abc => 123, something() );
Re: Why is "odd number of elements in hash assignment" warning and not error?
by Anonymous Monk on Feb 18, 2015 at 16:09 UTC

    The points you raise are quite valid. Whether something should be fatal or not is sometimes a matter of taste - there's the "thanks for the warning but I know what I'm doing" crowd, and there's the "we should help people with their likely mistakes" crowd - so arguments about it are bound to be endless :-) Especially in this case, where an odd number of elements in a hash assignment is not a situation that Perl cannot recover from and is therefore not strictly fatal. Instead, this is more of a "the programmer likely made a mistake, but then again we don't know for 100% certain" (Perl tends to be permissive with these kinds of things), which is probably why it's a nonfatal warning. Or, looking at it from yet another angle: at least people are getting a warning in the first place, and then the user has control over their preferred level of strictness.

    why "misc" category and not, say, "hash"/"odd"?!?!

    That is an excellent point and worthy of a patch or at least feature request to P5P.

      > at least people are getting a warning in the first place,

      yep, as a side note:

      "devision by 0" is a "silent Not_a_Number" in some languages like JS

      I.e. not a fatal stop of execution!

      Not any exception which could be activated or caught!

      Just returning "NaN" from calculation.

      > there's the "thanks for the warning but I know what I'm doing" crowd,

      And we had recently a discussion about people complaining that undefined values raise far too many warnings. ;-)

      > > why "misc" category and not, say, "hash"/"odd"?!?!

      > That is an excellent point

      most likely the set of warnings was expanded gradually over time...

      update

      > worthy of a patch or at least feature request to P5P.

      well I'm more concerned that obvious compile time errors aren't reported

      perl -we 'sub tst {%h=\%h}'

      (reusing %h to silence "only used one")

      Cheers Rolf

      PS: Je suis Charlie!

        Just to throw in another side note :-)

        And we had recently a discussion about people complaining that undefined values raise far too many warnings. ;-)

        Even here, I think giving the programmer control is the best option: When I'm generating stuff from templates, I often use no warnings 'uninitialized'; because I want my undefs to silently become "", but when I'm handling other data, e.g. from a database where there is a difference between NULL and 0.0, I prefer having the warnings (and once in a while I may even fatalize them).

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-04-24 11:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found