Disappearing Module

H

Hal Vaughan

I've had a similar problem before and now I realize it was resolved by
removing a level of modules. I don't see how I can include sample code
unless I include entire modules, but basically, when I do a "use Module;",
in some cases the functions in that Module aren't available. Here's an
example that works:

#!/usr/bin/perl
#Program: t-test

use MyMods::Log;

.....

initlog($channel); #This initializes the Log functions

Then, in MyMods/Log.pm, I have:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# used w/out problem
return;
}

When I do this, it works just fine. However, when I add another level, by
having a program use a module that uses MyMods::Log, then MyMod::Log cannot
access routines in MyMods::Channel. Here's an example of what does not
work:

#!/usr/bin/perl
#Program: t-fetch

use MyMods::Search;

......
initsearch($channel); #This initializes Search

Then, in MyMods/Search.pm, I have:

use MyMods::Log;

....

sub initsearch {
my $channel = shift(@_);
initlog($channel); #Same initchannel as before, but now
#called by a function in a module, not
#directly from the main program
return;
}

Then, in MyMods/Log.pm, again, I have the same as before:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# Now won't work when called from a mod
# that is, in turn, called from a mod
return;
}

This time I'm using the same module MyMods::Log, and that module is using
the same module, MyMods::Channel, but this time, it is NOT able to use the
functions in MyMods::Channel. All other routines in other mods are
accessible, it's just the Channel.pm file I'm having trouble with.

So what am I doing wrong? Why can MyMods::Log access MyMods::Channel when
called from a module used by program, but NOT when called from a module
that is used by a module that is used by a program?

Thanks!

Hal
 
M

Mark Clements

Hal said:
I've had a similar problem before and now I realize it was resolved by
removing a level of modules. I don't see how I can include sample code
unless I include entire modules, but basically, when I do a "use Module;",
in some cases the functions in that Module aren't available. Here's an
example that works:

#!/usr/bin/perl
#Program: t-test

use MyMods::Log;

....

initlog($channel); #This initializes the Log functions

Then, in MyMods/Log.pm, I have:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# used w/out problem
return;
}

When I do this, it works just fine. However, when I add another level, by
having a program use a module that uses MyMods::Log, then MyMod::Log cannot
access routines in MyMods::Channel. Here's an example of what does not
work:

#!/usr/bin/perl
#Program: t-fetch

use MyMods::Search;

.....
initsearch($channel); #This initializes Search

Then, in MyMods/Search.pm, I have:

use MyMods::Log;

...

sub initsearch {
my $channel = shift(@_);
initlog($channel); #Same initchannel as before, but now
#called by a function in a module, not
#directly from the main program
return;
}

Then, in MyMods/Log.pm, again, I have the same as before:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# Now won't work when called from a mod
# that is, in turn, called from a mod
return;
}

This time I'm using the same module MyMods::Log, and that module is using
the same module, MyMods::Channel, but this time, it is NOT able to use the
functions in MyMods::Channel. All other routines in other mods are
accessible, it's just the Channel.pm file I'm having trouble with.

So what am I doing wrong? Why can MyMods::Log access MyMods::Channel when
called from a module used by program, but NOT when called from a module
that is used by a module that is used by a program?

A few thoughts:

make sure the package declarations match up with the filenames

ie

package MyMods::Channel;

is at the start of MyMods/Channel.pm

Check out the Exporter

perldoc Exporter

Mark
 
A

Anno Siegel

Hal Vaughan said:
I've had a similar problem before and now I realize it was resolved by
removing a level of modules. I don't see how I can include sample code
unless I include entire modules, but basically, when I do a "use Module;",
in some cases the functions in that Module aren't available. Here's an
example that works:

#!/usr/bin/perl
#Program: t-test

use MyMods::Log;

....

initlog($channel); #This initializes the Log functions

Then, in MyMods/Log.pm, I have:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# used w/out problem
return;
}

When I do this, it works just fine.

I doubt that. MyMods/Log.pm doesn't return a true value, Perl
will not accept it.
However, when I add another level, by
having a program use a module that uses MyMods::Log, then MyMod::Log cannot
access routines in MyMods::Channel. Here's an example of what does not
work:

Oh man! Would you please be so kind and explain *what* doesn't work?
What error message do you get?
#!/usr/bin/perl
#Program: t-fetch

use MyMods::Search;

.....
initsearch($channel); #This initializes Search

Then, in MyMods/Search.pm, I have:

use MyMods::Log;

...

sub initsearch {
my $channel = shift(@_);
initlog($channel); #Same initchannel as before, but now
#called by a function in a module, not
#directly from the main program
return;
}

Then, in MyMods/Log.pm, again, I have the same as before:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# Now won't work when called from a mod
# that is, in turn, called from a mod
return;
}

None of your modules returns a true value. The module MyMod/Channel.pm
is missing.

I have reconstructed your setup. After adding the missing return values
and providing MyMod/Channel.pm

sub setchannelprogram {
print "setchannelprogram( $_[ 0])\n";
}

1;

things work exactly as expected: Top level calls initsearch(), which
calls initlog(), which calls setchannelprogram(). Since your presented
code is incomplete, I have probably fixed something you didn't show.

Result: I spent about 20 minutes trying to find out wtf you are
complaining about and came up empty. Frustration for me, no help
for you.

Now please show the exact and complete code that is giving you trouble,
and include the error message you're getting.

Anno
 
H

Hal Vaughan

Anno said:
I doubt that. MyMods/Log.pm doesn't return a true value, Perl
will not accept it.

Sorry. I was so focused on the "use" statements and the beginning I forgot
to include that all modules end with "1;" as the last line, so it does work
fine without error messages.
Oh man! Would you please be so kind and explain *what* doesn't work?
What error message do you get?

Undefined subroutine &MyMods::Log::setchannelprogram called at MyMods/Log.pm
line 150.
#!/usr/bin/perl
#Program: t-fetch

use MyMods::Search;

.....
initsearch($channel); #This initializes Search

Then, in MyMods/Search.pm, I have:

use MyMods::Log;

...

sub initsearch {
my $channel = shift(@_);
initlog($channel); #Same initchannel as before, but now
#called by a function in a module, not
#directly from the main program
return;
}

Then, in MyMods/Log.pm, again, I have the same as before:

use MyMods::Channel;

sub initlog {
my $channel = shift(@_);
setchannelprogram($channel); #Routine in MyMods::Channel --
# Now won't work when called
# from a mod that is, in turn,
# called from a mod
return;
}

None of your modules returns a true value. The module MyMod/Channel.pm
is missing.

I have reconstructed your setup. After adding the missing return values
and providing MyMod/Channel.pm

sub setchannelprogram {
print "setchannelprogram( $_[ 0])\n";
}

1;

things work exactly as expected: Top level calls initsearch(), which
calls initlog(), which calls setchannelprogram(). Since your presented
code is incomplete, I have probably fixed something you didn't show.

Result: I spent about 20 minutes trying to find out wtf you are
complaining about and came up empty. Frustration for me, no help
for you.

Now please show the exact and complete code that is giving you trouble,
and include the error message you're getting.

Each module is about 500 lines. I am not clear on just how much to include.
I've read up on Exporter, as another response suggested, but it seems to me
there is nothing there to help. I've gone through and not only re-typed
the module and function names, but actually copied the names from the
Channel.pm file into the Log.pm file. (I have a learning disability, which
makes it almost impossible to spot misspellings without them being
highlighted by syntax highlighting, so I went through carefully to make
sure that was not the problem -- at least it wasn't in any obvious way I
could understand. I also don't see how it could be a problem when both
modules work fine in one program.) I'm 100% self taught, so while I try to
go by what FAQs and other guides say, there are often "obvious" areas that
I have missed because I just never read a particular topic. I've been
hoping that, in this case, there might have been some rule about module use
that was so obvious and clear that while I missed it, most people would see
what I'm not doing.

I can post more, but, as I said, without posting the entire program and
hundreds of lines in each module, I'm not sure just how much to post.

Hal
 
A

Anno Siegel

Hal Vaughan said:
Sorry. I was so focused on the "use" statements and the beginning I forgot
to include that all modules end with "1;" as the last line, so it does work
fine without error messages.


Undefined subroutine &MyMods::Log::setchannelprogram called at MyMods/Log.pm
line 150.

Okay. That tells me that in your original code there were packages other
than "main" involved. Your code didn't show that.

[more code snipped]
I have reconstructed your setup. After adding the missing return values
and providing MyMod/Channel.pm
[...]
things work exactly as expected: Top level calls initsearch(), which
calls initlog(), which calls setchannelprogram(). Since your presented
code is incomplete, I have probably fixed something you didn't show.
[...]
Now please show the exact and complete code that is giving you trouble,
and include the error message you're getting.

Each module is about 500 lines. I am not clear on just how much to include.

Exactly as much as is necessary to reproduce your problem. Apparently
you need three modules and one main program.

[...]
I have missed because I just never read a particular topic. I've been
hoping that, in this case, there might have been some rule about module use
that was so obvious and clear that while I missed it, most people would see
what I'm not doing.

Nothing of this sort. What you describe should work, and does work when
coded up consistently.

Make a copy of your program and all involved libraries. Throw out every-
thing (in a step-wise process) that doesn't contribute to one of the
functions involved. Replace with dummies what can't be thrown out.
During the process, get the source in runnable condition often and
check if the error is still there. If it goes away, check your last
change. If it is still there, go on paring down the problem.

You will either find your error that way (which is rather likely), or
you'll end up with a minimal program that inexplicably shows the error.
In that case, post it, using copy-and-paste to get the code into the
posting. Then we can talk.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top