For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > September 2006 > about perltoot









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author about perltoot
Chen Li

2006-09-21, 6:58 pm

Hi all,

I read some sections in perltoot. In section
Autoloaded Data Methods I see some line codes as
following:

package Person;
use Carp;
our $AUTOLOAD; # it's a package global

my %fields = (
name => undef,
age => undef,
peers => undef,
);

sub new {
my $class = shift;
my $self = {
_permitted => \%fields,
%fields,
};
bless $self, $class;
return $self;
}

It looks like that _permitted => \%fields and %fields
are redundant. Could anyone explain it a little bit
more?

Thanks,

Li

________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
wenbinye@gmail.com

2006-09-21, 6:58 pm

You should read more carefully, the author had explained the reason
bellow:
Notice how we saved a reference to our class data on the
object itself? Remember that it's important to access class
data through the object itself instead of having any method
reference %fields directly, or else you won't have a decent
inheritance.

Chen Li wrote:
> Hi all,
>
> I read some sections in perltoot. In section
> Autoloaded Data Methods I see some line codes as
> following:
>
> package Person;
> use Carp;
> our $AUTOLOAD; # it's a package global
>
> my %fields = (
> name => undef,
> age => undef,
> peers => undef,
> );
>
> sub new {
> my $class = shift;
> my $self = {
> _permitted => \%fields,
> %fields,
> };
> bless $self, $class;
> return $self;
> }
>
> It looks like that _permitted => \%fields and %fields
> are redundant. Could anyone explain it a little bit
> more?
>
> Thanks,
>
> Li
>
> ________________________________________
__________
> Do You Yahoo!?
> Tired of spam? Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com


Mumia W.

2006-09-22, 3:57 am

On 09/21/2006 07:08 PM, chen li wrote:
> Hi all,
>
> I read some sections in perltoot. In section
> Autoloaded Data Methods I see some line codes as
> following:
>
> package Person;
> use Carp;
> our $AUTOLOAD; # it's a package global
>
> my %fields = (
> name => undef,
> age => undef,
> peers => undef,
> );
>
> sub new {
> my $class = shift;
> my $self = {
> _permitted => \%fields,
> %fields,
> };
> bless $self, $class;
> return $self;
> }
>
> It looks like that _permitted => \%fields and %fields
> are redundant. [...]


That "redundancy" allows you to use inheritance. If you have a class
Employee, with an expanded set of fields, this method makes it possible
to add the fields without having to modify each method that uses them.



Chen Li

2006-09-22, 7:57 am



--- "Mumia W." <mumia.w.18.spam+nospam@earthlink.net>
wrote:

> On 09/21/2006 07:08 PM, chen li wrote:
> %fields
>
> That "redundancy" allows you to use inheritance. If
> you have a class
> Employee, with an expanded set of fields, this
> method makes it possible
> to add the fields without having to modify each
> method that uses them.
>


Where can I find more about this kind of syntax?

Thanks,

Li

________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Mumia W.

2006-09-22, 6:57 pm

On 09/22/2006 07:50 AM, chen li wrote:
>
> --- "Mumia W." <mumia.w.18.spam+nospam@earthlink.net>
> wrote:
>
> Where can I find more about this kind of syntax?
> [...]


Read the "Class Data" section in perltoot.


Chen Li

2006-09-24, 6:57 pm



--- "Mumia W." <mumia.w.18.spam+nospam@earthlink.net>
wrote:

> On 09/22/2006 07:50 AM, chen li wrote:
> <mumia.w.18.spam+nospam@earthlink.net>
> If
>
> Read the "Class Data" section in perltoot.
>

Hi Mumia,

I don't think I get the point. If my purpose of using
AUTOLOAD is to handle 1) many attributes in construct
2) create an un-predined method on the fly, what will
happen if I make the following changes:

in sub new change
my $self = {_permitted => \%fields,%fields,};

to my $self =\%fields;


in sub AUTOLOAD comment out the unless statement.

Do you think these change will affect inheritance?

Thanks in advacne,

Li


########### copy from perltoot
package Person;
use Carp;
our $AUTOLOAD; # it's a package global

my %fields = (
name => undef,
age => undef,
peers => undef,
);

sub new {
my $class = shift;
my $self = {
_permitted => \%fields,
%fields,
};
bless $self, $class;
return $self;
}


sub AUTOLOAD {
my $self = shift;
my $type = ref($self)
or croak "$self is not an
object";

my $name = $AUTOLOAD;
$name =~ s/.*://; # strip
fully-qualified portion

unless (exists
$self->{_permitted}->{$name} ) {
croak "Can't access `$name' field in
class $type";
}

if (@_) {
return $self->{$name} = shift;
} else {
return $self->{$name};
}
}

________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Rob Dixon

2006-09-24, 6:57 pm

chen li wrote:
>
> --- "Mumia W." <mumia.w.18.spam+nospam@earthlink.net>
> wrote:
>
>
>
> Hi Mumia,
>
> I don't think I get the point. If my purpose of using
> AUTOLOAD is to handle
> 1) many attributes in construct
> 2) create an un-predined method on the fly
> what will happen if I make the following changes:
>
> in sub new change
> my $self = {_permitted => \%fields,%fields,};
> to
> my $self =\%fields;
>
> in sub AUTOLOAD comment out the unless statement.
>
> Do you think these change will affect inheritance?
>
> Thanks in advacne,
>
> Li
>
>
> ########### copy from perltoot
> package Person;
> use Carp;
> our $AUTOLOAD; # it's a package global
>
> my %fields = (
> name => undef,
> age => undef,
> peers => undef,
> );
>
> sub new {
> my $class = shift;
> my $self = {
> _permitted => \%fields,
> %fields,
> };
> bless $self, $class;
> return $self;
> }
>
>
> sub AUTOLOAD {
> my $self = shift;
> my $type = ref($self)
> or croak "$self is not an
> object";
>
> my $name = $AUTOLOAD;
> $name =~ s/.*://; # strip
> fully-qualified portion
>
> unless (exists
> $self->{_permitted}->{$name} ) {
> croak "Can't access `$name' field in
> class $type";
> }
>
> if (@_) {
> return $self->{$name} = shift;
> } else {
> return $self->{$name};
> }
> }


Hello Li

About the _permitted hash key, the perltoot tutorial says

+ I could have avoided the "_permitted" field entirely, but I wanted to
+ demonstrate how to store a reference to class data on the object so you
+ wouldn't have to access that class data directly from an object method.

So the point of the class data %fields is to restrict autoloaded methods to the
expected ones, while the point of putting a reference to it in the object data
is, as Tom says, to demonstrate how class data can be accessed indirectly from
within an object method.

Preventing the module from autoloading non-permitted methods has the same
purpose as 'use strict "vars"', i.e. to prevent a misspelled name producing
obscure runtime bugs. Without the _permitted hash, I could write:

my $me = new Person;
$me->nane('Rob');
die unless $me->name eq 'Rob';

and I could be perplexed for a while over why it kept dying. Adding the check,
the AUTOLOAD method would croak and immediately explain the problem.

With regard to the reference to class data, later on in the tutorial there is a
class Person with a class scalar $Census which keeps track of the number of
objects that have been created. This scalar can be accessed via the 'population'
method. Using the same technique, the 'new' and 'population' methods could be
rewritten:

my $Census = 0;

sub new {

my $class = shift;

my $self = {
NAME => undef,
AGE => undef,
PEERS => [],
_census => \$Census,
};

${$self->{_census}}++;

bless ($self, $class);
}

sub population {

my $self = shift;

return ${$self->{_census}};
}

so that the access method has no need to refer directly to the package variable,
in the same way that your AUTOLOAD method needn't use the %fields hash
explicitly. I believe this is what Mumia meant about inheritance: if the method
had directly accessed %fields hash then a subclass like Employee would have no
way of reaching it, but once a reference to it appears in the object data then
all is well once more.

I hope this makes things clearer for you.

Rob

(After reading the tutorial further I realise that Tom Christiansen has made a
very similar adaptation to the one I have described above. The main difference
is that the 'population' method is written so that it can also be called as the
class method Person::population as well as an object method $person->population.
I hope this doesn't confuse you.)
Mumia W.

2006-09-24, 6:57 pm

On 09/24/2006 12:35 PM, chen li wrote:
>
> --- "Mumia W." <mumia.w.18.spam+nospam@earthlink.net>
> wrote:
>
> Hi Mumia,
>
> I don't think I get the point.


Write an example. Create a superclass and a subclass where the
superclass has class data that you want to be able to override in the
subclass (but *without* having to override every method that uses that
data).

> If my purpose of using
> AUTOLOAD is to handle 1) many attributes in construct
> 2) create an un-predined method on the fly, what will
> happen if I make the following changes:
>
> in sub new change
> my $self = {_permitted => \%fields,%fields,};
>
> to my $self =\%fields;
>
>
> in sub AUTOLOAD comment out the unless statement.
>
> Do you think these change will affect inheritance?
>


Why didn't you test what happens when you do that? What happens when you
create three different objects and manipulate them? What happens with
those object when you go back to the original code?

> Thanks in advacne,
>
> Li
>
>
> ########### copy from perltoot
> package Person;
> [...]





Chen Li

2006-09-24, 6:57 pm


> Why didn't you test what happens when you do that?
> What happens when you
> create three different objects and manipulate them?
> What happens with
> those object when you go back to the original code?



Actually before I post it I already check what happen.
It looks like there are NO differences before and
after the changes. But I haven't check the inheritance
yet.

Li


________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Chen Li

2006-09-24, 6:57 pm


>
> Hello Li
>
> About the _permitted hash key, the perltoot tutorial
> says
>
> + I could have avoided the "_permitted" field
> entirely, but I wanted to
> + demonstrate how to store a reference to class data
> on the object so you
> + wouldn't have to access that class data directly
> from an object method.
>
> So the point of the class data %fields is to
> restrict autoloaded methods to the
> expected ones, while the point of putting a
> reference to it in the object data
> is, as Tom says, to demonstrate how class data can
> be accessed indirectly from
> within an object method.
>
> Preventing the module from autoloading non-permitted
> methods has the same
> purpose as 'use strict "vars"', i.e. to prevent a
> misspelled name producing
> obscure runtime bugs. Without the _permitted hash, I
> could write:
>
> my $me = new Person;
> $me->nane('Rob');
> die unless $me->name eq 'Rob';
>
> and I could be perplexed for a while over why it
> kept dying. Adding the check,
> the AUTOLOAD method would croak and immediately
> explain the problem.
>
> With regard to the reference to class data, later on
> in the tutorial there is a
> class Person with a class scalar $Census which keeps
> track of the number of
> objects that have been created. This scalar can be
> accessed via the 'population'
> method. Using the same technique, the 'new' and
> 'population' methods could be
> rewritten:
>
> my $Census = 0;
>
> sub new {
>
> my $class = shift;
>
> my $self = {
> NAME => undef,
> AGE => undef,
> PEERS => [],
> _census => \$Census,
> };
>
> ${$self->{_census}}++;
>
> bless ($self, $class);
> }
>
> sub population {
>
> my $self = shift;
>
> return ${$self->{_census}};
> }
>
> so that the access method has no need to refer
> directly to the package variable,
> in the same way that your AUTOLOAD method needn't
> use the %fields hash
> explicitly. I believe this is what Mumia meant about
> inheritance: if the method
> had directly accessed %fields hash then a subclass
> like Employee would have no
> way of reaching it, but once a reference to it
> appears in the object data then
> all is well once more.
>
> I hope this makes things clearer for you.
>
> Rob
>
> (After reading the tutorial further I realise that
> Tom Christiansen has made a
> very similar adaptation to the one I have described
> above. The main difference
> is that the 'population' method is written so that
> it can also be called as the
> class method Person::population as well as an object
> method $person->population.
> I hope this doesn't confuse you.)
>


Thanks Rob. I think now I get the points.

Li

________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com