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

Hello,

How do you deal with modules which includes eachs others ? (ie package a uses package b. package b uses package a)

I guess it would be possible to overcome this with the C preprocessor but I would like not to use it.

Thanx for your help


Edited: ~Wed Oct 2 15:26:45 2002 (GMT) by footpad: Replaced <PRE> tags with proper HTML formatting, per Consideration

Replies are listed 'Best First'.
Re: modules which includes eachs other
by Joost (Canon) on Oct 02, 2002 at 13:56 UTC
    Like this:
    # in file Module1.pm package Module1; use Module2; # in file Module2.pm package Module2; use Module1;
    Perl will remember which modules are already loaded (in the %INC hash) and everything sorts itself out in the end™.
    -- Joost downtime n. The period during which a system is error-free and immune from user input.
Re: modules which includes eachs other
by Abigail-II (Bishop) on Oct 02, 2002 at 14:01 UTC
    If module A uses module B, a typical way is for A to use use B;. If module B uses module A, B could just do use A;.

    I don't see a problem.

    Abigail

      When package B executes use A, the A::import sub will not be compiled yet. That might cause trouble if side-effects from the import are expected.

      I'd probably use require A to make it explicit that I'm not expecting A::import to run.

      Update: Here's a little bit of code that lets you see how modules are loaded and imported. Each file needs to be saved separately -- if you combine packages into the same file, it won't work the same.

      red.vulpes.com:~% more t.pl BEGIN { unshift @INC, sub { my($self, $file) = @_; print "loading $file\n"; return } } use Foo qw(t.pl); print "in t.pl\n"; red.vulpes.com:~% more Foo.pm package Foo; use Bar qw(Foo.pm); sub import { local $" = ', '; print "Foo::import(@_)\n"; } 1; red.vulpes.com:~% more Bar.pm package Bar; use Foo qw(Bar.pm); sub import { local $" = ', '; print "Bar::import(@_)\n"; } 1; red.vulpes.com:~% perl -w t.pl loading Foo.pm loading Bar.pm Bar::import(Bar, Foo.pm) Foo::import(Foo, t.pl) in t.pl

      In the last bit of output above, notice the expected line "Foo::import(Foo, Bar.pm)" is missing. That's because Foo::import hasn't been compiled when Bar tries to execute it.

        Well, in this simple case, you could just move the use Bar qw(Foo.pm); in Foo.pm to after the sub import { ... } declaration.

        Of course, that might not work for some, more complicated situations. *shrug*

        bbfu
        Black flowers blossum
        Fearless on my breath