Zettai has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I apologise for the duplicate post. I have read the other posts similar to this and my lack of Perl understanding has finally gotten me into trouble.

My project is separated into different files and different directories.

An example structure is as follows:

main.pl:

#!/camelbox/bin/perl package main; use strict; use Gtk2 -init; use Log::Log4perl; # Init Logger from config file. Log::Log4perl::init_and_watch( 'log\root-logger.conf', 30 ); our $logger = Log::Log4perl->get_logger; # Run main loop. Gtk2->main;

I then have a number of packages using the logger from main:

Subdir/Foo.pm

package Foo; $main::logger->debug("Here is a debug message in Foo."); 1;

Subdir/Bar.pm

package Bar; $main::logger->debug("Here is a debug message in Bar."); 1;

Subdir/Baz.pm

package Baz; $main::logger->debug("Here is a debug message in Baz."); 1;

As an example in my project, Foo and Baz are both able to use $main::logger->debug or $main::logger->error but for some reason Bar returns the error message:

Can't call method "error" on an undefined value at...

or

Can't call method "debug" on an undefined value at...

What could be some of the reasons that only package Bar cannot 'see' or use the $main::logger method? In my project there are a number of other files in the same directory that contains Bar all of which are able to use $main::logger->debug/error without any problems.

Thank you for any suggestions.

Replies are listed 'Best First'.
Re: Can't call method on an undefined value
by andal (Hermit) on Nov 16, 2011 at 08:37 UTC

    Check when the method is called. It might happen that you call it before the variable "$logger" is created in main. For example this might happen if you call it directly in the body of the module you "use". Here's example.

    package MyModule; $main::logger->debug("This may fail"); sub func { $main::logger->debug("This is OK"); } 1;

Re: Can't call method on an undefined value
by Anonymous Monk on Nov 15, 2011 at 23:57 UTC

    For arguments sake A and C are fine but for some reason B returns the error message:

    B is already a module, a core module, pick different names, say Zettai::B

      Sorry, I was using A and B as examples and didn't realise they were already core modules. I have updated the question.

        cpan's log4perlsays "You can get a logger anytime via a singleton mechanism:".

        I think you can reproduce your situation if you make simple example codes. I am not sure about relation between main package and foo/bar/baz packages,especially. Readmore tag seems to be recommended for a sample code which becomes long, I put them below.

        regards
Re: Can't call method on an undefined value
by johnny_carlos (Scribe) on Nov 15, 2011 at 23:13 UTC
    I notice it is failing to call method "error", not method "logger". I don't know the solution, but thought that might be a helpful clue.

    EDIT: Hmm, ok I just read the api and my comment isn't very helpful. I think it would be helpful though to post the real code that throws the error, unless this sample code is also failing. Packages A,B,C appear to be standalone. How do they know anything about main or logger?

Re: Can't call method on an undefined value
by anneli (Pilgrim) on Nov 16, 2011 at 00:46 UTC

    When you say use B;, that's probably loading the core B, not yours. What's the path you've elided in the quoted error message?

Re: Can't call method on an undefined value
by thargas (Deacon) on Nov 16, 2011 at 13:34 UTC

    You're almost certainly using the Bar module before you're defining your $main::logger.

    However, your example doesn't demonstrate the problem. Rather than attempting to guess, I'm going to wait for you to fix the example.

    My expectation is that if you can produce an example which demonstrates the problem, you'll also work out why it happens and what to do to avoid it. If you still need help after producing the example, I'm sure that we'll be able to help you.