Odd number of elements in hash assignment with default

后端 未结 2 1179
逝去的感伤
逝去的感伤 2020-12-22 00:36

Greeting Dear Community.

I\'m trying to make a sub in perl that takes a hash and a debug flag which defaults to zero. However I keep getting this error

相关标签:
2条回答
  • 2020-12-22 01:14

    You want to pass your hashes by value to your subroutine and this creates the problem. Try to pass your hash %h2 by reference instead (notice the \ before the %):

    &hash2print(\%h2, 1);
    

    Then in your sub hash2print, you can get the hash back in the following way:

    sub hash2print {
        (my $hashref, my $debug) = @_;
        my %HoH = %$hashref; # dereference $hashref to get back the hash
        ...
    

    You can read more about references here if you don't understand the concepts behind them.

    0 讨论(0)
  • 2020-12-22 01:20

    Arguments are passed to a function as one flat list. On the other hand, a hash can be assigned a list, %h = qw(a b), where consecutive elements form key-value pairs, $h{a} is 'b'. So when a hash is the first variable that receives arguments in a function it scoops up all of them. Here is a recent post on how a function returns, where the exact same story applies.

    So everything is assigned to the hash, the remaining scalar as well. Thus the hash gets one more element than intended and ends up with an odd number of elements.

    A solution -- in this case, only to pass hash by reference, as in the answer by Inferno

    sub hash2print{
        my ($rHoH, $debug) = @_;
        my %HoH = %$rHoH;
        # ...
    }
    hash2print(\%h2, 1);
    

    It is in principle a good idea to pass lists by reference, unless they are very short.

    In general you can pass the scalar first then the hash

    sub hash2print{
        my ($value, %HoH) = @_;
        # ...
    }
    hash2print(1, %h2);
    

    But in your case this doesn't go since the $debug is optional, and if we leave it out when calling the function the first key of the hash would wind up in $value.

    A few other comments

    • Don't use globals unless there is a non-negotiable reason for that. Declare in small scope.

    • You don't have to do $rec = {};, can just declare it my $rec;.

    • In general, don't put & in front of a function call but use just file2hash(...);

    0 讨论(0)
提交回复
热议问题