We help IT Professionals succeed at work.

Problem Calling Embedded Function within OO Perl - Namespace Issue??

rmgould
rmgould asked
on
Medium Priority
312 Views
Last Modified: 2012-06-21
I am obviously missing something in this simplified example.  I have a 'custom module' for the function I have written over time.
This module uses function from other modules.  For this example - I am using a function from the Date::Manip module.

I am trying to use these functions from an instance of the Net::Server class.  When I call my custom function from a normal perl program or from another module - I have no problem.  When I call my custom from within the child_init_hook sub of the Net::Server module - the ParseDateString function causes the subroutine to end.  Note that no error message occurs and Net::Server continues to run - the sub routine (child_init_hook) just stops executing.

What makes this problem even more bizzare is that if I call my test function 'pdate' before I start the run method (note: i have this line commented out in the text below)- everything works fine.  I am obviously missing something obvious about object oriented perl.


************ Sample Code - Main Program

#!/export/opt/perl/5.8.0/bin/perl

package MyPackage;
 
  use mod
  use vars qw(@ISA);
  use Net::Server::PreFork  qw(:DEFAULT /^/);
  @ISA = qw(Net::Server::PreFork);

#$a=pdate("20020101"); # If this line is not commented out - pdate in child_init_hook works!!

  MyPackage->run();
  exit;

  sub child_init_hook
  {

    print "initializing process id $$\n";
    $a=pdate("20020101");

    print "f $a\n";

  }

1;

********** Sample Module

#!/export/opt/perl/5.8.0/bin/perl

package mod;

require Exporter;
use base qw(Exporter);
use vars qw(@EXPORT @EXPORT_OK @INC);
@EXPORT = qw(&pdate);
use Date::Manip;
sub pdate
{
  my ($y) = @_;
 
  print "bef\n";
  $a=ParseDateString($y);
  print "after $a\n";
}
1;


Comment
Watch Question

Try declaring $a first:

  sub child_init_hook
  {

    print "initializing process id $$\n";
    my $a=pdate("20020101");

    print "f $a\n";

  }

Also, if you are writing a module *** put "use strict;" at the top! ***  There are very good reasons to force variable declaration, and it just might solve this problem.

Author

Commented:
I do use strict in my actual code.  I did not include it when making this simple example.  Just to check - I did declare my variables first.  There was no effect.  To show the output I included it below.  You can see that the function 'pdate' does not go further than the ParseDateString call.  

*************

2004/04/04-13:41:45 MyPackage (type Net::Server::PreFork) starting! pid(16543)
Port Not Defined.  Defaulting to '20203'
Binding to TCP port 20203 on host *
Group Not Defined.  Defaulting to EGID '201 601 201'
User Not Defined.  Defaulting to EUID '60128'
initializing process id 16544
bef
initializing process id 16545
bef
initializing process id 16546
bef
initializing process id 16548
bef
initializing process id 16547
bef

*****************

If I take out the comment from
  #$a=pdate("20020101"); # If this line is not commented out - pdate in child_init_hook works!!

in the original post I get this output which is correct... i just don't get it...

**********

2004/04/04-13:46:45 MyPackage (type Net::Server::PreFork) starting! pid(16798)
Port Not Defined.  Defaulting to '20203'
Binding to TCP port 20203 on host *
Group Not Defined.  Defaulting to EGID '201 601 201'
User Not Defined.  Defaulting to EUID '60128'
initializing process id 16802
bef
initializing process id 16803
bef
after 2002010100:00:00
f 1
after 2002010100:00:00
f 1
initializing process id 16804
bef
initializing process id 16805
bef
after 2002010100:00:00
f 1
after 2002010100:00:00
f 1
initializing process id 16806
bef
after 2002010100:00:00
f 1




Try turning on warnings ("use warnings;" or append -w to shebang) and run it again.

Author

Commented:
My current version has 'use warnings' added in addition to properly declaring all variables.  The output above is from that code.  No warnings are currently given.
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
does not change anything.  Remember if the pdate call outside of the child_init_hook is called (ie that line is not commented out in the original post) - the whole thing works fine to begin with.  I think the problem has to lie in the namespace of the module.  If I had to guess - somehow the custom module had its namespace overridden by the namespace of the net server class.  

Perhaps you can try saving my 2 examples into 2 files test.pl and mod.pm and see if you replicate the output I am seeing.
Owner
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
I found the answer on from a google newsgroup search.  The answer seems to be a problem (feature) with the 'Prefork' component of Net::Server.  If I use 'Fork' vs. 'PreFork' all is well.  The other post had no explanation - but as I don't really need to prefork given my anticipated volume - I am happy with only a forking server.  tkx to all.  splitting the points for the effort given...
jmcgOwner

Commented:
You must have excellent Google skills -- I could not find anything helpful on the web.

Using the Fork instead of Prefork version means that you are much less likely to get into the startup situation of having all of several children simultaneously tring to run Date_Init. You'd still be well advised to call pdate in the parent before any forks, since having to run Date_Init anew on every transaction is a waste and may slow your response time just a wee bit.
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.