tags:

views:

38

answers:

3

I have a Perl class that contains a hash instance variable for storing other objects. I would like to have a method to print the number of elements in the hash but I am getting the following error message on the line return keys($self->{'_things'});

Type of arg 1 to keys must be hash (not hash element)

package MyClass;
use strict;

sub new {
    my ($class) = @_;
    my $self = {
        _things => undef
    };
    $self->{'_things'} = ();
    bless $self, $class;
    return $self;
}

sub get_count {
    my ( $self ) = @_;
    return keys($self->{'_things'});
}
+3  A: 

Use

return scalar(keys(%{$self->{'_things'}}));

$self->{'_things'} is just a reference to a hash, and keys() expects a hash as its argument—so, you have to dereference it first by wrapping it in %{…}. Finally, since you want to count items, you have to make sure the return value of keys() (which is a list) is interpreted in scalar context, by wrapping it in scalar(…).

igor
A: 

The error message is totally correct! ;) You need to 'dereference' the element into a hash, also you need to call keys() in a scalar context to get the count.

$ perl -wle 'use strict; my $href = { foo => undef }; $href->{foo} = (); print sclar keys $href->{foo}'
Type of arg 1 to keys must be hash (not hash element) at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

vs.

$ perl -wle 'use strict; my $href = { foo => undef }; $href->{foo} = (); print scalar keys %{ $href->{foo} }'
0

You might want to use a hash ref instead for $self->{_things} to avoid accidental list flattening and other issues though.

$ perl -wle 'use strict; my $href = { foo => undef };  $href->{foo} = { bar => 1 }; print scalar keys %{ $href->{foo} };'
1
nicomen
+2  A: 

If I understand you correctly, $self->{_things} should contain a hash data structure. If so, you have two problems:

sub new {
    my ($class) = @_;
    my $self = {
        # Initialize _things to be a reference to an empty hash.
        _things => {},
    };
    bless $self, $class;
    return $self;
}

sub get_count {
    my ( $self ) = @_;
    # Here's the way to get the N of keys.
    # The %{ FOO } syntax will take a hash reference (FOO in this case) and 
    # convert it to a hash, on which we can then call keys().
    return scalar keys %{ $self->{'_things'} };
}
FM