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

Hi monks! If I had a file system that looked something like this
FOO ----Bar.pl ----FOO -------Fubar.pm
Is it possible that Fubar.pm can call a method in Bar.pl? I tried to use use FOO::Bar.pl; in the Fubar.pm file but it doesn't work.

Can you use a method in a file that's higher in the directory tree? If so what is the syntax to do it?

Thanks.

Replies are listed 'Best First'.
Re: Paths to Packages
by jimt (Chaplain) on Jul 17, 2006 at 19:34 UTC

    I have an advantage over other people reading the original question, inasmuch as I can simply walk over to the OP and ask for clarification.

    The basic situation is this:

    in file FOO/Bar/Baz.pm package FOO::Bar::Baz; sub some_function { login(); } in file FOO/Bar.pl package FOO::Bar; sub login { # something interesting }

    Bar.pl is the executable script (with its own defined package) that defines a function. She then wanted to call this function from the separate module file. The original version was slightly off from the functional one I posted.

    Obviously, this is a not-so-hot approach. FOO::Bar is now dependent upon a function being defined in the symbol table in advance at some point in some separate file beyond its control. So if that function in that other package somehow changes or ceases to be, this module breaks and it's not immediately clear why. Side effects are bad.

    I proposed two solutions. (1) is to rip out the function into a separate module and import it.

    --- in the new module FOO/Bar.pm package FOO::Bar sub login { } --- in FOO/Bar/Baz.pm package FOO::Bar::Baz use FOO::Bar; sub some_function { FOO::Bar::login(); } --- in the script (remove the login function and proceed as normal)

    This is better inasmuch as it's now quite clear that the function is declared in a new module that's explicitly used by the original module. Hopefully you'd be more careful modifiying it, and at a minimum it'd be easier to spot the error.

    But, it's still tying FOO::Bar into the specific method that works in this one case. A (better?) more generic approach would be to use some sort of a function lookup table and define the callback method you want. Roughly,

    --- in FOO/Bar/Baz.pm my %function_table; sub set_callback { my ($key, $function) = @_; $function_table{$key} = $function; } sub some_function { if (defined $function_table{'login'}) { $function_table{'login'}->(); } else { die "No callback declared for login"; } } --- in FOO/Bar.pl use FOO::Bar; sub login { } FOO::Bar->set_callback('login', \&login);

    FOO::Bar's some_function is now completely decoupled from the original login function, and you can drop in any new one you'd like. I wouldn't be surprised if there's some CPAN module to give an enhanced version of this sketched out functionality.

      Thanks for your explanation Jim.
      It makes sense to put that function in it's own pm file.
Re: Paths to Packages
by philcrow (Priest) on Jul 17, 2006 at 18:42 UTC
    Usually use Bar; would be enough. The perl interpreter infers the .pm on a bare word use.

    Phil

    Update: Looking more closely at your file structure I see two FOO dirs at different levels. Try use FOO::Bar.

      uh? My question is about the location path not really the name of the module. If I have FOO::FOO:Fubar. How do I call a method that is in FOO:: instead of in the same directory of FOO::FOO::? (In a sense, going back up the tree.)

      Is my question clear?