The code in question:
#a.pl use bspace; use cspace; bgo(); cgo(); #bspace.pm package bspace; use Exporter; use cspace; @ISA='Exporter'; @EXPORT=qw( bgo bhelp ); sub bgo { chelp(); } sub bhelp { print "bhelp\n"; } 1; #cspace.pm package cspace; use Exporter; use bspace; @ISA='Exporter'; @EXPORT=qw( cgo chelp ); sub cgo { bhelp(); } sub chelp { print "chelp\n"; } 1;
Yes, you can do this, but only carefully. You have to make sure that @ISA and @EXPORT are set by the time they are needed. Remember that a use statement temporarily stops compiling the current file while the used file is compiled, executed, and then import called. (If the module had previously been used or required, the compilation and execution is skipped.)

In your case, this is what happens:

a.pl line 1 compiled: "use bspace" bspace line 1 compiled: package bspace; bspace line 2 compiled: use Exporter; Exporter.pm compiled main code of Exporter.pm executed Exporter::->import called (uselessly) bspace line 3 compiled: use cspace; cspace line 1 compiled: package cspace; cspace line 2 compiled: use Exporter; Exporter::import called (uselessly) cspace line 3 compiled: use bspace; bspace::->import called (but doesn't yet exist since bspace::ISA is no +t yet set to inherit import() from Exporter, so bgo and bhelp are not + imported into cspace) cspace line 4 compiled but not executed: @ISA = 'Exporter' cspace line 5 compiled but not executed: @EXPORT = qw(cgo chelp); cspace line 6 compiled: sub cgo { bhelp(); } cspace line 7 compiled: sub chelp { print "chelp\n"; } cspace line 8 compiled but not executed: 1; cspace lines 4,5,8 executed cspace::->import called: cgo and chelp are exported into bspace bspace line 4 compiled but not executed: @ISA = 'Exporter' bspace line 5 compiled but not executed: @EXPORT = qw(bgo bhelp); bspace line 6 compiled: sub bgo { chelp(); } bspace line 7 compiled: sub bhelp { print "bhelp\n"; } bspace line 8 compiled but not executed: 1; bspace lines 4,5,8 executed bspace::->import called: bgo and bhelp are exported into main a.pl line 2 compiled: use cspace cspace::->import called: cgo and chelp are exported into main a.pl line 3 compiled but not executed: bgo() a.pl line 4 compiled but not executed: cgo() a.pl line 3 executed: bgo() (imported from bspace) bspace::bgo calls chelp() (imported from cspace) cspace::chelp prints "chelp\n" a.pl line 4 executed: cgo() (imported from cspace) cspace::cgo calls bhelp() which was not imported from bspace and so do +esn't exist.
So the solution is to start your packages like:
package bspace; use strict; use warnings; use Exporter (); # () avoids (harmless but) useless call to Exporter:: +import; BEGIN { our @ISA = 'Exporter'; our @EXPORT = qw(bgo bhelp); }
and only after that use any modules that might do recursive use. The same technique is needed when putting packages in the same file that use each other, e.g.:
# A.pm package A; use strict; use warnings; use Exporter (); BEGIN { our @ISA = 'Exporter'; our @EXPORT = 'foo' } sub foo { print "foo" } # and in the same file A.pm package A::B; use A; sub bar { foo() } # without the BEGIN block above, the use A won't hav +e imported foo into A::B

In reply to Re: Circular usage by ysth
in thread Circular usage by Sprad

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.