For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > September 2006 > How to initialize class data?









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 How to initialize class data?
Ralph Moritz

2006-09-27, 7:01 pm

Hi,

I've got some class data which I want to initialize once.
I was thinking of doing it like this:

{ package Foo;

my $FirstTime = 1;

sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$class->init() if ($FirstTime);
}

sub init {
# Initialize class data...
$FirstTime = 0;
}
}

Is this okay, or is there a generally accepted way
to do this?

Thanks,
Ralph

--
Ralph Moritz
Quantum Solutions Ph: +27 315 629 557
GPG Public Key: http://ralphm.info/public.gpg
Paul Lalli

2006-09-27, 7:01 pm

Ralph Moritz wrote:
> I've got some class data which I want to initialize once.
> I was thinking of doing it like this:
>
> { package Foo;
>
> my $FirstTime = 1;
>
> sub new {
> my $class = shift;
> my $self = {};
> bless $self, $class;
> $class->init() if ($FirstTime);
> }
>
> sub init {
> # Initialize class data...
> $FirstTime = 0;
> }
> }
>
> Is this okay, or is there a generally accepted way
> to do this?


What do you mean by "class data" in this case? Variables scoped to the
package, that all class-methods and object-methods would have access
to? If that's the case, I have a dumb question - why aren't you just
declaring these variables to be initialized to whatever they need to be
initialized to?

That is, instead of:
{
package Foo;
my $FirstTime = 1;
my $data;

sub new {
#...
initialize_data() if $FirstTime;
}

sub initialize_data {
$data = "Stuff";
$FirstTime = 0;
}
}

why aren't you just doing:

{
package Foo;
my $data = "Stuff";

sub new {
#...
}
}

?

If I've over simplified things so as to remove the point of your
question, please give us a better idea of what it is you're trying to
accomplish.

Paul Lalli

Brian McCauley

2006-09-27, 7:01 pm


Ralph Moritz wrote:
> Hi,
>
> I've got some class data which I want to initialize once.
> I was thinking of doing it like this:
>
> { package Foo;
>
> my $FirstTime = 1;
>
> sub new {
> my $class = shift;
> my $self = {};
> bless $self, $class;
> $class->init() if ($FirstTime);
> }
>
> sub init {
> # Initialize class data...
> $FirstTime = 0;
> }
> }
>
> Is this okay, or is there a generally accepted way
> to do this?


The canonical way would be an INIT block.

Or sometimes you'll see people just not put the code in a subroutine at
all.

But both of these will make the initialization code be called even if
Foo is never instanciated.

If you really want to defer until the first object is instanciated then
what you are doing is approximately correct. However you should not be
calling $class->init() you should call Foo->init() or simply init().
With your code if the first Foo object that's instanciated happens to
be a of a subclass you'll call init() in that subclass.

Oh and it's probably more ideomatic to reverse the sense of your flag.

my $initialized;

sub init {
$initialized++; # Slower than =1 but the more common idiom
# etc...
}

sub new {
init unless $initialized;
my $class = shift;
my $self = bless {}, $class;
# etc...
}

Ralph Moritz

2006-09-27, 7:01 pm

"Paul Lalli" <mritty@gmail.com> writes:

[snip]
> That is, instead of:
> {
> package Foo;
> my $FirstTime = 1;
> my $data;
>
> sub new {
> #...
> initialize_data() if $FirstTime;
> }
>
> sub initialize_data {
> $data = "Stuff";
> $FirstTime = 0;
> }
> }
>
> why aren't you just doing:
>
> {
> package Foo;
> my $data = "Stuff";
>
> sub new {
> #...
> }
> }
>
> ?


Because I need to read the value of $data from a config file.

--
Ralph Moritz Ph: +27 846 269 070
GPG Public Key: http://ralphm.info/public.gpg

"Faith is believing something you know ain't true."
Ralph Moritz

2006-09-27, 7:01 pm

"Brian McCauley" <nobull67@gmail.com> writes:

> Ralph Moritz wrote:
[snipped the rest of my original post][color=darkred]
> The canonical way would be an INIT block.
>
> Or sometimes you'll see people just not put the code in a subroutine at
> all.
>
> But both of these will make the initialization code be called even if
> Foo is never instanciated.
>
> If you really want to defer until the first object is instanciated then
> what you are doing is approximately correct. However you should not be
> calling $class->init() you should call Foo->init() or simply init().
> With your code if the first Foo object that's instanciated happens to
> be a of a subclass you'll call init() in that subclass.
>
> Oh and it's probably more ideomatic to reverse the sense of your flag.
>
> my $initialized;
>
> sub init {
> $initialized++; # Slower than =1 but the more common idiom
> # etc...
> }
>
> sub new {
> init unless $initialized;
> my $class = shift;
> my $self = bless {}, $class;
> # etc...
> }


Excellent. Thank you.

--
Ralph Moritz Ph: +27 846 269 070
GPG Public Key: http://ralphm.info/public.gpg

"Faith is believing something you know ain't true."
Michele Dondi

2006-09-27, 7:01 pm

On Wed, 27 Sep 2006 21:38:34 +0200, Ralph Moritz <me@ralphm.info>
wrote:

>
>Because I need to read the value of $data from a config file.


Or because, more generally, you want for some reason to do that
initialization only at the first instantiation of the class, which
indeed is a good point, IMHO...


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
Sponsored Links







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

Copyright 2008 codecomments.com