in reply to efficient getters in module (class)

You could make your key pair (item+name, user+id) a parameter of a generic 'get' subroutine, but you would still have to figure out how to compare the values associated with the second key. You would also have to make sure that your $this object is initialized with all the possible keys (item, user) so that you can detect typos (and same for $user, $item objects). Something like this to get you started:
sub get_by_string { my ($this, $field, $property, $value) = @_; die "Invalid field $field" if (!exists $this->{$field}); return grep { $_->{$property} eq $value } @{$this->{$field}}; } sub get_by_number { my ($this, $field, $property, $value) = @_; die "Invalid field $field" if (!exists $this->{$field}); return grep { $_->{$property} == $value } @{$this->{$field}}; }
Your get calls would then look like this:
my @items = $obj->get_by_string('item','name',$name); my @users = $obj->get_by_number('user','id',$id);