in reply to Perl OOP help for OOP newbie

You probably don't want to have Account be a sub-class of User. That is, you don't want to have our @ISA = qw(User). Instead, you probably should have an instance variable in each Account that references the User object that it is associated with.

Also, since you can have several accounts for each user, it probably doesn't make sense to have $self->{account} = User::Account->new($account_id);

You probably want to have something like:
package User; # ... sub open_account { my ($self, $account_id) = @_; return User::Account->new($self, $account_id); } package Account; sub new { my ($class, $user, $account_id) = @_; my $self = { user => $user, account_id = $account_id }; bless $self, $class; } sub balance { my $self = shift; # now you have $self->{user} for the user object # and $self->{account_id} }

Replies are listed 'Best First'.
Re^2: Perl OOP help for OOP newbie
by Anonymous Monk on Jun 01, 2011 at 21:10 UTC

    Thanks for your reply. I don't get your comment "Instead, you probably should have an instance variable in each Account that references the User object that it is associated with." Surely, User::Account belongs to User? and I don't understand how you'd create an instance variable in each Account that references the User object - how do you do that? Presumably you are referring to the $self in "return User::Account->new($self, $account_id); ".

    I'll work on your idea and see where I get.

      Inheritance is for "is a" relationships. For instance, a BMW "is a" SportsCar, so BMW could inherit from SportsCar. Now let's try it with your class: An Account "is a" User. That isn't true, so Account would not inherit from User.

      "Composition" is for "has a" relationships. For instance, a User "has a(n)" Account. In your case, composition would involve assigning an Account object to a User variable. If your User object uses a hash internally, then one key in the hash could be called ACCOUNTS, and its value could be a reference to an array. The array would contain various Account objects.

      If a user has multiple accounts, I'd suggest this:
      package User; sub new { my ($class, $username) = @_; my $self =(username=> $username, accounts=>{} , # No accounts for a +new user server=> {Some server connection info} ); bless $self, $class; } sub open_account { my ($self, $account_id) = @_; return $self->accounts->{$account_id} = User::Account->new($self, $ac +count_id); } # accessor for accounts.. sub get_account{ my ($self,account_id) = @_; return $self->accounts->{account_id}; }

                  "XML is like violence: if it doesn't solve your problem, use more."