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

Fellow monks,

I've been working on my first sizable project using object oriented Perl. The project is a card game with Player objects that act independently according to their own particular strategy for the game. There is a Hand class that manages the mechanics of play and tells each Player object the game state and requests it to make decisions based on this state. I'm passing an array of references to Player objects to the Hand constructor like so:

#!/usr/bin/perl -w use strict; use Player; use Hand; #... my @pl; push @pl, Player->new(name => Alice, strategy => aggressive); push @pl, Player->new(name => Bob, strategy => conservative); my $hand = Hand->new( players, \@pl ); $hand->play();

And in Hand.pm ...

sub new { my ($class, %arg) = @_; # ... bless { # ... _players => $arg{players} , }, $class; } sub play { my ($self) = @_; my %player; $self->{_players}[0]->out(); # this works # out() is a member function that prints some info about the Playe +r # add key containg ref to 1st player to %player and # with value of a reference to a new anonymous hash $player{$self->{_players}[0]} = {}; foreach my $this_player (keys %player) { $this_player->out(); # this doesn't } }
The error message returned at runtime by the line containing "# this doesn't" is:
Can't locate object method "out" via package "Player=HASH(0x1012ac74)" + (perhaps you forgot to load "Player=HASH(0x1012ac74)"?) at Hand.pm l +ine 63.
The reason I'm trying to use Player references as keys in the %player hash is that I need to keep track of each player's state as the hand plays out.

Thank you for any light you can shed on this!

Replies are listed 'Best First'.
Re: Problem using object references as hash keys
by sgifford (Prior) on Jun 08, 2004 at 21:31 UTC

    You can't use an object as the key to a hash; Perl automatically converts it to a string, and so you're trying to call a method on a string. Perl figures maybe you want to use symbolic references, where the string has the name of the class you want to use or the variable you want to dereference, but it can't find the method that way, so it fails with the error message you saw. If you used warnings and strict, Perl would have done a better job of warning you about this.

    You can store objects in arrays, or as the values in a hash. You should be able to use one of those techniques to get your code to do what you want.

      That's a convincing explanation of why I'm encountering this issue -- thank you. (I am using warnings and strict already and received the error messages I cited.)
Re: Problem using object references as hash keys
by Joost (Canon) on Jun 08, 2004 at 22:00 UTC
      Thank you for the reference -- that module looks like just the ticket if I can't successfully parse eric256's later reply, which appears to be a suggestion about how to do what I want without bringing in any additional modules.
Re: Problem using object references as hash keys
by eric256 (Parson) on Jun 09, 2004 at 03:05 UTC

    In the new method couldn't you map the players into an AofH with something like the following.

    _players => [ map { { Player => $_ } } @$arg{players} ],

    Then you could access it below with

    $self->{_players}[0]->{Player}->out(); # this works

    Then you would be storing the object reference in the Player key and would be able to use that same hash to store other state data however you felt neccessary.

    $self->{_players}[0]->{Score} = 100;

    ___________
    Eric Hodges