0

I am getting the error

Type of of argument to keys on reference must be unblessed hasref or arrayref at xxxx.pl line 6518

Part of the script is

    ndr_log("Processing file: $file [$filesize bytes] Portion: $portion; Billing Date/MDate: $portion_date/$filemtime; Reading Proc: [$entries/$entries_reading/$entries_n15]: $reading_proc", 'Info');

    if (!defined $BILL->{$portion}->{$portion_date}->{mtime}
            or $BILL->{$portion}->{$portion_date}->{mtime} < $filemtime) {

        $BILL->{$portion}->{$portion_date}->{mtime}    = $filemtime;
        $BILL->{$portion}->{$portion_date}->{entries}  = $entries;
        $BILL->{$portion}->{$portion_date}->{readings} = $entries_reading;
        $BILL->{$portion}->{$portion_date}->{n15}      = $entries_n15;
        $BILL->{$portion}->{$portion_date}->{proc}     = $reading_proc;
        $BILL->{$portion}->{$portion_date}->{ok}       = $meter_ok;
        $BILL->{$portion}->{$portion_date}->{nok}      = $meter_nok;
    }
    else {
        DbgPlain("Ignoring file: $file; this is older result; never version exists: $BILL->{$portion}->{$portion_date}->{mtime}");
    }

} # for files

# Create Report
#
my @REPORT;

for (sort keys $BILL) {  ### Line 6518

    my $portion = $_;

    for ( sort keys $BILL->{$portion} ) {

        my $portion_date = $_;

        #ndr_log("Portion: $portion on $portion_date")

        my $entries         = $BILL->{$portion}->{$portion_date}->{entries};
        my $entries_reading = $BILL->{$portion}->{$portion_date}->{readings};
        my $entries_n15     = $BILL->{$portion}->{$portion_date}->{n15};
        my $reading_proc    = $BILL->{$portion}->{$portion_date}->{proc};
        my $meter_ok        = $BILL->{$portion}->{$portion_date}->{ok};
        my $meter_nok       = $BILL->{$portion}->{$portion_date}->{nok};

Is there anyway to solve it?

I have in my new server ActivePerl 5.16.3 build 1604 and in the one that works Build 1603. Is it a version issue?

Borodin
  • 126,100
  • 9
  • 70
  • 144
Raul
  • 27
  • 2
  • 5
  • 1
    Please don't rewrite error messages. Copy and paste them. You will introduce typos that could hide valuable information. – simbabque May 10 '18 at 16:06
  • 1
    Is $BILL an object? If it is, you shouldn't dereference it at all, not even to peek into its internal data (as in `$BILL->{$portion}`), you should call its methods instead. To iterate over the keys, there should be a method providing the list. – choroba May 10 '18 at 16:08
  • 1
    Perl 5.14 introduced [auto dereferencing](https://perldoc.perl.org/perl5140delta.html#Array-and-hash-container-functions-accept-references) as an experimental feature, but it was removed again in 5.24. But not on objects. – simbabque May 10 '18 at 16:13
  • The difference in behaviour isn't due to AP 1603 vs AP 1604. – ikegami May 10 '18 at 16:55

2 Answers2

2

If $BILL is a blessed object, getting its keys makes no sense. It might have a method to provide a list of the "keys" that you can then use as method names or parameters to a universal getter - but we don't know, as you haven't shown how $BILL is populated and what class it's been blessed to.

There were some changes in the behaviour of keys and references. To stay on the safe side, don't use it at all, dereference the reference:

keys %$BILL

But that applies to plain non-blessed hash references only. Applying dereference on an object breaks encapsulation (and note that $BILL->{$portion} dereferences the object, too).

choroba
  • 231,213
  • 25
  • 204
  • 289
0
**Line 1618:**  for (sort keys $BILL) {

$BILL is a scalar value (starts with $), specifically a reference to a hash as can be seen how it was used earlier. You need to call keys on the hash itself and not on the reference to it. To do this you need to dereference it to get to the hash and call keys on it, i.e. use keys %$BILL not keys $BILL.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • While you should use `keys %$ref` instead `keys $ref` (because the latter was an experimental feature that was abandoned), that's not the problem the OP is having. Switching to `keys %$ref` may or may not help. (I didn't downvote.) – ikegami May 10 '18 at 16:54