Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Should I use BEGIN, CHECK, or INIT?
Greetings,

I have a couple of questions and I would like to know the opinions
of the Perl community.

I while ago, I wrote a Perl module which is now practically
finished.  Its exact contents aren't important for my questions,
except for the fact that it is a package and its functions are called
like:

use MyPackage;
MyPackage::init();
MyPackage::f1();
MyPackage::f2($var1, $var2);

The first function that must be called is an initialization
function (MyPackage::init()).  It must be called before any other
function in the package and should only be called once.  This fact is
well-documented in the perldoc documentation, so any Perl programmer
who bothers to check this module's documentation should be aware of
it.

However, recently I've been thinking:  If the init() function has
to be called before any other function and should only be called once,
why not put the initialization call in a BEGIN block inside the module
itself?  That way, the programmer who uses my module doesn't even have
to call the init() function; it will be done automatically at the "use
MyPackage;" statement.

My first question is:  Is putting the initialization function
inside a BEGIN (or CHECK or INIT) block a good idea, or is there some
pontential problem that I'm not aware of?  If the initialization
function fails, I want it to stop the program from running at all.  Of
course, if I do put the init() function in a BEGIN block, I'll remove
all mention of it from the perldoc so the programmer won't be tempted
to use it.

And my second question:  If it is a good idea to automatically call
the init() function for the programmer, should I:

a) put the init() statement in a BEGIN block
b) put the init() statement in a CHECK block
c) put the init() statement in an INIT block
d) put the init() statement as the last statement executed
in the module
or
e) it's not a good idea, so just let the programmer who uses
my module call it in his/her own code

The only difference I see between BEGIN, CHECK, and INIT (besides
the facts that BEGIN statments happen before CHECK statements which
happen before INIT statements and that CHECK statements happen in
"First In, Last Out" order) is that if I put the init() function in a
BEGIN or CHECK block and the init() function fails, then it is
discovered at compile time.  In other words, if the init() function
fails, then the statement:

perl -c myscript.pl

will fail as well, as long as the init() function call is placed
inside a BEGIN block or a CHECK block.

This sounds appealing in that "use MyPackage;" will fail if the
init() function fails, bringing it right away to the attention of the
programmer.  However, it's possible that I might not see an obvious
problem with this approach, and so I would like any advice or comments
from anyone who might have had experience with something similar.

To sum up my questions:  Should I put the init() call in a BEGIN,
CHECK, or INIT block, or should I just let the programmer who uses my
module do it automatically (and document it thoroughly in the
perldoc)?

Thanks in advance for any advice.

-- Jean-Luc

Report this thread to moderator Post Follow-up to this message
Old Post
J. Romano
10-28-04 08:56 AM


Re: Should I use BEGIN, CHECK, or INIT?
Also sprach J. Romano:

>    I while ago, I wrote a Perl module which is now practically
> finished.  Its exact contents aren't important for my questions,
> except for the fact that it is a package and its functions are called
> like:

[...]

>    The first function that must be called is an initialization
> function (MyPackage::init()).  It must be called before any other
> function in the package and should only be called once.  This fact is
> well-documented in the perldoc documentation, so any Perl programmer
> who bothers to check this module's documentation should be aware of
> it.
>
>    However, recently I've been thinking:  If the init() function has
> to be called before any other function and should only be called once,
> why not put the initialization call in a BEGIN block inside the module
> itself?  That way, the programmer who uses my module doesn't even have
> to call the init() function; it will be done automatically at the "use
> MyPackage;" statement.
>
>    My first question is:  Is putting the initialization function
> inside a BEGIN (or CHECK or INIT) block a good idea, or is there some
> pontential problem that I'm not aware of?  If the initialization
> function fails, I want it to stop the program from running at all.  Of
> course, if I do put the init() function in a BEGIN block, I'll remove
> all mention of it from the perldoc so the programmer won't be tempted
> to use it.

That appears to be good idea.

>    And my second question:  If it is a good idea to automatically call
> the init() function for the programmer, should I:
>
>    a) put the init() statement in a BEGIN block
>    b) put the init() statement in a CHECK block
>    c) put the init() statement in an INIT block
>    d) put the init() statement as the last statement executed
>       in the module

There's really not much difference between any of those alternatives.
Putting it in a BEGIN block means that it is executed very early, even
before the rest of the module is compiled. Since the module cannot be
used without successfully calling YourModule::init() anyway, there is no
need to finish compilation of it so it doesn't harm to die very early.

>      or
>    e) it's not a good idea, so just let the programmer who uses
>       my module call it in his/her own code

You should at least give him the opportunity to call it manually even
when it usually must not be done. I had a problem lately with one of my
modules where I called an init function in a BOOT-section of the XS
portion [which is roughly equivalent to d) in the above list]. I
received reports that the module didn't work in processes that had been
forked off. And indeed, it turned out that the underlying C-library
required this initialization to happen in each process.

So call init() in a BEGIN block but also document that it must be called
manually when using the module's functionality in child processes.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
 pam{rekcahbus})(rekcah{lrePbus})(lreP{re
htonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

Report this thread to moderator Post Follow-up to this message
Old Post
Tassilo v. Parseval
10-28-04 08:56 AM


Re: Should I use BEGIN, CHECK, or INIT?
J. Romano wrote:
>    And my second question:  If it is a good idea to automatically call
> the init() function for the programmer, should I:
>
>    a) put the init() statement in a BEGIN block
>    b) put the init() statement in a CHECK block
>    c) put the init() statement in an INIT block
>    d) put the init() statement as the last statement executed
>       in the module
>      or
>    e) it's not a good idea, so just let the programmer who uses
>       my module call it in his/her own code

I would put it in the BEGIN block and if I was really worried about the init
()
function being called only once I would make that a closure.


BEGIN { init(); }

{
my $called = 0;

sub init {
unless( $called ) {
print "Called init for the first time\n";
$called = 1;
} else {
print "Init has already been called\n";
}
}
}

I would not put it in the CHECK block in case there were any side effects of
calling it such as opening database connections, files or the like. As, I
believe, that CHECK is called when you do...

perl -c Module.pm

where as BEGIN is not.

I think, can anyone confirm this. I am only on my first cup to tea.

Report this thread to moderator Post Follow-up to this message
Old Post
Peter Hickman
10-28-04 01:56 PM


Re: Should I use BEGIN, CHECK, or INIT?
J. Romano <jl_post@hotmail.com> wrote in comp.lang.perl.misc:
> Greetings,
>
>    I have a couple of questions and I would like to know the opinions
> of the Perl community.
>
>    I while ago, I wrote a Perl module which is now practically
> finished.  Its exact contents aren't important for my questions,
> except for the fact that it is a package and its functions are called
> like:
>
>    use MyPackage;
>    MyPackage::init();
>    MyPackage::f1();
>    MyPackage::f2($var1, $var2);

[...]

>    And my second question:  If it is a good idea to automatically call
> the init() function for the programmer, should I:
>
>    a) put the init() statement in a BEGIN block
>    b) put the init() statement in a CHECK block
>    c) put the init() statement in an INIT block
>    d) put the init() statement as the last statement executed
>       in the module
>      or
>    e) it's not a good idea, so just let the programmer who uses
>       my module call it in his/her own code

I have little to add to Tassilo's thorough discussion of the issue,
except still another alternative:

f) rename the init() function as import() (or call it from
the import() function)

That (import()) will be called after the last executable statement
of your module, but before "use" returns to the caller, so it is
basically equivalent to d).  The difference is that the user has
the choice to suppress the call to import() and call it on their
own.

>    The only difference I see between BEGIN, CHECK, and INIT (besides
> the facts that BEGIN statments happen before CHECK statements which
> happen before INIT statements and that CHECK statements happen in

Another difference is that BEGIN and CHECK are executed when the
module in question is loaded.  INIT (and END) are collected and
not executed before all compile-time activity is done, so if more
modules are loaded, INIT only runs after that has happened.

Anno

Report this thread to moderator Post Follow-up to this message
Old Post
Anno Siegel
10-28-04 01:57 PM


Re: Should I use BEGIN, CHECK, or INIT?
Peter Hickman wrote:
> I would not put it in the CHECK block in case there were any side
> effects of calling it such as opening database connections, files or the
> like. As, I believe, that CHECK is called when you do...
>
> perl -c Module.pm
>
> where as BEGIN is not.
>

dug@slurp:~/scratch$ cat A.pm
package A;

BEGIN { warn "begin" }
CHECK { warn "check" }
INIT  { warn "init"  }
END   { warn "end"   }

1;

dug@slurp:~/scratch$ perl -c A.pm
begin at A.pm line 3.
check at A.pm line 4.
A.pm syntax OK

dug@slurp:~/scratch$ perl A.pm
begin at A.pm line 3.
check at A.pm line 4.
init at A.pm line 5.
end at A.pm line 6.

See perlmod for more details.

> I think, can anyone confirm this. I am only on my first cup to tea.

Whereas I have the luxury of being well into my second cup of coffee {grin}.

-- Douglas Hunter

Report this thread to moderator Post Follow-up to this message
Old Post
Douglas Hunter
10-28-04 01:57 PM


Re: Should I use BEGIN, CHECK, or INIT?

Douglas Hunter wrote:

> Peter Hickman wrote:
> 
>
> dug@slurp:~/scratch$ cat A.pm
> package A;
>
> BEGIN { warn "begin" }
> CHECK { warn "check" }
> INIT  { warn "init"  }
> END   { warn "end"   }
>
> 1;

For more complete view of things...

bam@wcl-l:~/tmp> cat A1.pm
package A1;
sub import { warn "import" };
BEGIN { warn "begin" }
CHECK { warn "check" }
INIT  { warn "init"  }
END   { warn "end"   }
warn "body";
1;

bam@wcl-l:~/tmp> cat A2.pm
package A2;
sub import { warn "import" };
BEGIN { warn "begin" }
CHECK { warn "check" }
INIT  { warn "init"  }
END   { warn "end"   }
warn "body";
1;

bam@wcl-l:~/tmp> perl -ce 'use A1; use A1; use A2;'
begin at A1.pm line 3.
body at A1.pm line 7.
import at A1.pm line 2.
import at A1.pm line 2.
begin at A2.pm line 3.
body at A2.pm line 7.
import at A2.pm line 2.
check at A2.pm line 4.
check at A1.pm line 4.
-e syntax OK

bam@wcl-l:~/tmp> perl -e 'use A1; use A1; use A2;'
begin at A1.pm line 3.
body at A1.pm line 7.
import at A1.pm line 2.
import at A1.pm line 2.
begin at A2.pm line 3.
body at A2.pm line 7.
import at A2.pm line 2.
check at A2.pm line 4.
check at A1.pm line 4.
init at A1.pm line 5.
init at A2.pm line 5.
end at A2.pm line 6.
end at A1.pm line 6.

bam@wcl-l:~/tmp> perl -e 'require A1; require A1; require A2;'
begin at A1.pm line 3.
body at A1.pm line 7.
begin at A2.pm line 3.
body at A2.pm line 7.
end at A2.pm line 6.
end at A1.pm line 6.

My view is that initialisaton code that must be run once and once only
when the module is loaded and which doesn't connect to any external
resource is best called in the module body unless there's a specific
reason to put it elsewhere.
 
>
> Whereas I have the luxury of being well into my second cup of coffee
> {grin}.

And I'm dangerously close to an overdose.


Report this thread to moderator Post Follow-up to this message
Old Post
Brian McCauley
10-28-04 08:59 PM


Re: Should I use BEGIN, CHECK, or INIT?

Brian McCauley wrote:

>
>
> Anno Siegel wrote:

[snip most of Anno's message ]
 

import() is called each time the module use use()d.  It is therefore
inappropriate for initialisation that should happen once regardless of
how many times the module is used.


Report this thread to moderator Post Follow-up to this message
Old Post
Brian McCauley
10-28-04 08:59 PM


Re: Should I use BEGIN, CHECK, or INIT?

Anno Siegel wrote:

> J. Romano <jl_post@hotmail.com> wrote in comp.lang.perl.misc:
> 
>
>
> [...]
>
> 
>
>
> I have little to add to Tassilo's thorough discussion of the issue,
> except still another alternative:
>
>      f) rename the init() function as import() (or call it from
>         the import() function)
>
> That (import()) will be called after the last executable statement
> of your module, but before "use" returns to the caller, so it is
> basically equivalent to d).  The difference is that the user has
> the choice to suppress the call to import() and call it on their
> own.
>
> 
>
>
> Another difference is that BEGIN and CHECK are executed when the
> module in question is loaded.  INIT (and END) are collected and
> not executed before all compile-time activity is done, so if more
> modules are loaded, INIT only runs after that has happened.
>
> Anno


Report this thread to moderator Post Follow-up to this message
Old Post
Brian McCauley
10-28-04 08:59 PM


Re: Should I use BEGIN, CHECK, or INIT?
Brian McCauley (nobull@mail.com) wrote on MMMMLXXVI September MCMXCIII in
<URL:news:clr9kl$ia4$4@sun3.bham.ac.uk>:
--
--
--  Brian McCauley wrote:
--
-- >
-- >
-- > Anno Siegel wrote:
--
--  [snip most of Anno's message ]
--
-- >> I have little to add to Tassilo's thorough discussion of the issue,
-- >> except still another alternative:
-- >>
-- >>      f) rename the init() function as import() (or call it from
-- >>         the import() function)
-- >>
-- >> That (import()) will be called after the last executable statement
-- >> of your module, but before "use" returns to the caller, so it is
-- >> basically equivalent to d).  The difference is that the user has
-- >> the choice to suppress the call to import() and call it on their
-- >> own.
--
--  import() is called each time the module use use()d.  It is therefore
--  inappropriate for initialisation that should happen once regardless of
--  how many times the module is used.


my $ping_a_pong;
sub import {
$ping_a_pong ++ or do {
.. initialization code ...
};
}


I'd hesitate to use INIT in a module. From "man perlmod":

"INIT" blocks are run just before the Perl runtime begins
execution, in "first in, first out" (FIFO) order. For
example, the code generators documented in perlcc make use
of "INIT" blocks to initialize and resolve pointers to
XSUBs.

It's not entirely clear to me when (or if) an INIT in a module is run.
Is that just before runtime of the main program, or just before runtime
of the module?


However, if I need to initialize something in a module, I wouldn't use
BEGIN, INIT, or CHECK, nor would I use import() or require an init()
function to be called.

I'd either put the initialization code in the main body of the module,
or just the call to init(). After all, a module, whether required or used,
*is* executed. Once. Right after it was compiled. Which sounds exactly
what the OP wants.  (Sure, it would run multiple times if people use
'do Module;', or much with '%INC'. But that's their problem.)


Abigail
--
#!/opt/perl/bin/perl   --   # Remove trailing newline!
BEGIN{$SIG{__WARN__}=sub{$_=pop;y-_- -;print/".*(.)"/;
truncate$0,-1+-s$0;exec$0;}}//rekcaH_lreP_rehtona_tsuJ

Report this thread to moderator Post Follow-up to this message
Old Post
Abigail
10-29-04 01:56 AM


Re: Should I use BEGIN, CHECK, or INIT?
Quoth "Tassilo v. Parseval" <tassilo.von.parseval@rwth-aachen.de>:
> Also sprach J. Romano:
> 

You should not put things in CHECK blocks, in general. They are hooks
for the (unimplemented) perl compiler.
 

I would say here is best, but it really makes no difference. Putting
init stuff in init blocks is necessary for any form of perl compiler to
work (including things I have tried to do in the past to make PAR's
module-detection mechanism more reliable in the face of modules which
use other modules for you, such as 'if' and 'all'); however, this
convention is so universally ignored that there is little point trying
to follow it.
 
>
> You should at least give him the opportunity to call it manually even
> when it usually must not be done.

As you're going to do this, I would recommend calling it from ->import.
Thn the user can choose (if necessary) not to call it with

use Module ();

and then call it later when necessary.

Ben

--
For far more marvellous is the truth than any artists of the past imagined!
Why do the poets of the present not speak of it? What men are poets who can
speak of Jupiter if he were like a man, but if he is an immense spinning
sphere of methane and ammonia must be silent? [Feynmann]     ben@morrow.me.uk

Report this thread to moderator Post Follow-up to this message
Old Post
Ben Morrow
10-29-04 01:56 AM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

PERL Miscellaneous archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 05:08 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.