On 3/13/22 15:08, Diab Jerius via module-authors wrote:
On 3/13/22 16:13, David Christensen wrote:
module-authors:

I have been wrestling with the Exporter module and subroutine circular dependencies between modules for a number of years.  I have yet to find a satisfactory solution.

If you move import of modules with circular dependencies to runtime rather than compile time:


    $ diff Exporter-circular-use{.orig,.new}
    diff Exporter-circular-use.orig/Bar11.pm
    Exporter-circular-use.new/Bar11.pm
    13c13,14
    < use Foo11;
    ---
     > require Foo11;
     > Foo11->import;
    diff Exporter-circular-use.orig/Foo11.pm
    Exporter-circular-use.new/Foo11.pm
    13c13,14
    < use Bar11;
    ---
     > require Bar11;
     > Bar11->import;


    $ perl Exporter-circular-use.t
    ok 1 - foo00
    ok 2 - foo01
    ok 3 - foo10
    ok 4 - foo11
    1..4


Thank you for the reply.  :-)


Yes, that works.


  Or move the export completely into compile time:

    $ diff Exporter-circular-use{.orig,.new}
    diff Exporter-circular-use.orig/Bar11.pm
    Exporter-circular-use.new/Bar11.pm
    9,11c9,11
    < require Exporter;
    < our @ISA    = qw( Exporter );
    < our @EXPORT    = qw( bar );
    ---
     > use parent 'Exporter';
     > our @EXPORT;
     > BEGIN{ @EXPORT = qw( bar ); }
    diff Exporter-circular-use.orig/Foo11.pm
    Exporter-circular-use.new/Foo11.pm
    9,11c9,11
    < require Exporter;
    < our @ISA    = qw( Exporter );
    < our @EXPORT    = qw( foo );
    ---
     > use parent 'Exporter';
     > our @EXPORT;
     > BEGIN { @EXPORT = qw( foo ); }


Yes, that also works. Putting the @EXPORT allocation and initialization in a BEGIN block ahead of the 'use parent' looks even better:

2022-03-13 18:15:46 dpchrist@tinkywinky ~/samba/dpchrist/sandbox/perl/Exporter-circular-use
$ diff Foo11.pm Foo33.pm
1c1
< package Foo11;
---
> package Foo33;
9,11c9,10
< require Exporter;
< our @ISA   = qw( Exporter );
< our @EXPORT        = qw( foo );
---
> BEGIN { our @EXPORT = qw( foo ) }
> use parent 'Exporter';
13c12
< use Bar11;
---
> use Bar33;


David



2022-03-13 18:38:24 dpchrist@tinkywinky ~/samba/dpchrist/sandbox/perl/Exporter-circular-use
$ cat /etc/debian_version ; uname -a ; perl -v | head -n 2
9.13
Linux tinkywinky 4.9.0-17-amd64 #1 SMP Debian 4.9.290-1 (2021-12-12) x86_64 GNU/Linux

This is perl 5, version 24, subversion 1 (v5.24.1) built for x86_64-linux-gnu-thread-multi

2022-03-13 18:40:00 dpchrist@tinkywinky ~/samba/dpchrist/sandbox/perl/Exporter-circular-use
$ ./Exporter-circular-use.t
ok 1 - foo00
ok 2 - foo01
ok 3 - foo10
Undefined subroutine &Bar11::foo called at Bar11.pm line 22.
not ok 4 - foo11
#   Failed test 'foo11'
#   at ./Exporter-circular-use.t line 24.
#          got: 'main=7
#  foo=6
#   bar=5
# '
#     expected: 'main=7
#  foo=6
#   bar=5
#    foo=4
#     bar=3
#      foo=2
#       bar=1
# '
Undefined subroutine &Bar12::foo called at Bar12.pm line 23.
not ok 5 - foo12
#   Failed test 'foo12'
#   at ./Exporter-circular-use.t line 24.
#          got: 'main=7
#  foo=6
#   bar=5
# '
#     expected: 'main=7
#  foo=6
#   bar=5
#    foo=4
#     bar=3
#      foo=2
#       bar=1
# '
ok 6 - foo21
ok 7 - foo22
ok 8 - foo33
1..8
# Looks like you failed 2 tests of 8.

Attachment: Exporter-circular-use-20220313-181541.tar.gz
Description: application/gzip

Reply via email to