SPUG:Object property question

Jeremy Kahn kahn at cpan.org
Wed Apr 30 21:31:25 CDT 2003


Jay, Dan --

don't forget that you want to build for the future. You may want to 
subclass Member someday (temporary members, super-members, moderators, 
whatever).

Jay Scherrer wrote:

>I would do something like:
>package Member;
>sub new
>{
>my $this = {};
>    bless $this;
>    return $this;
>}
>
I would rather do it like this:

package Member;

# take the type as an argument, so that this method can be inherited.
# this can be more compact, but it works and is clearer
sub new {
  my $class = shift;  # $class will be 'Member' (but *not* when you 
subclass it)
  my $instance = bless ({}, $class);
  $instance->init(@_); # any remaining arguments should be passed to init
  return $instance;
}

>sub init_newMember
>{   
>my $this = shift;
>$this{id} = shift;
>$this{FirstName} = shift;
>$this{LastName} = shift;
>}
>  
>
rather:
# we know it's a Member now, but this method might be used for a subclass
# too, so let's just call the method 'init'
sub init {
  my $self = shift;
  my ($id, $fn, $ln) = @_;
  $self->{'Member_id'} = $id;
  $self->{'Member_firstname'} = $fn;
  $self->{'Member_lastname'}  = $ln;
}

>1;
>  
>
Yup.

>Then in your script:
>$member = Member::new();
>
>$id = 0;
>$firstName = "John";
>$lastName = "Doe";
>$member->Member::init_newMember($id, $firstName, $lastName);
>  
>
No! This method of calling new() can't be inherited -- you're naming the 
package explicitly, but you'd like to leave yourself the option to 
re-implement Member so that it borrows a 'new' method from some *other* 
parent, someday (this is called "refactoring" and is very hip :-/).

Furthermore, with the new() as I suggested (calling the init() method 
from within itself) you can pass the arguments right in:

my ($id, $fn, $ln) = (0, 'John', 'Doe');
$member = Member->new($id, $fn, $ln);
# isn't that pretty? $member is all done and ready to be used; no need 
for a second call.

The key to the object->method() syntax is to remember that when a method 
is called like this, it passes the object as an implicit first argument 
(it's unshifted onto @_).

This applies even when it's a literal (like a classname) which is why we 
get away with Member->new(@args):
the method Member::new is called with the argument list ('Member', @args).

Note also that if Member::new isn't found, then it checks to see if 
@Member::ISA has any entries; if it does, it searches those ancestor 
classes recursively.

This is all *very* powerful, and kinda hacked together. I strongly 
recommend The Damian's book "Object Oriented Perl" -- the first five or 
six chapters are a great introduction to this subject.

>On Wednesday 30 April 2003 03:24 pm, Dan Ebert wrote:
>  
>
>>The Setup:
>>
>>I'm working on a module to manage a membership database.  I have it set
>>up so that there is a Member object with properties you can access like
>>
>>my $firstname = $member->firstname();
>>
>>and change with
>>
>>$member->firstname('new first name');
>>
>>etc.
>>
>>when a new member is created:
>>
>>$member->initialize(firstname => 'John',
>>                    lastname  => 'Doe');
>>$member->create();
>>
>>I insert the data into a table and get the member ID from an
>>auto-incrementing field.
>>
>>The Question:
>>
>>I want to set a new property of the Member object (the ID).  So that you
>>can retrieve the ID with
>>
>>$id = $member->id();
>>
>>In my module I tried:
>>
>>$member->{id} = $id
>>
>>but that didn't work.
>>
>>The only thing I've gotten to work is to return the object ... so that
>>you call the create method like this:
>>
>>$member = $member->create();
>>
>>which seems a little awkward.
>>
>>Is there a better way?
>>    
>>
>
>_____________________________________________________________
>Seattle Perl Users Group Mailing List  
>POST TO: spug-list at mail.pm.org
>ACCOUNT CONFIG: http://mail.pm.org/mailman/listinfo/spug-list
>MEETINGS: 3rd Tuesdays, U-District, Seattle WA
>WEB PAGE: www.seattleperl.org
>
>  
>





More information about the spug-list mailing list