use and BEGIN are executed as soon as they are compiled. Without the BEGIN, the following would happen:
- Spiderman's use strict; is compiled.
- Spiderman's use strict; is executed.
- Spiderman's use warnings; is compiled.
- Spiderman's use warnings; is executed.
- What was in Spiderman's BEGIN is compiled.
- Spiderman's use Doctor::Octopus; is compiled.
- Spiderman's use Doctor::Octopus; is executed.
- require Doctor::Octopus is executed.
- Octopus's use strict; is compiled.
- Octopus's use strict; is executed.
- Octopus's use warnings; is compiled.
- Octopus's use warnings; is executed.
- What was in Octopus's BEGIN is compiled.
- Octopus's use Spiderman; is compiled.
- Octopus's use Spiderman; is executed.
- Spiderman is already loaded, so it's not loaded again.
- Spiderman is already loaded, so it's not executed again.
- Spiderman->import doesn't exist, so it isn't called.
This is the problem.
Exporter hasn't been loaded yet,
and the variables telling Exporter
what Spiderman should export haven't been initialized.
- The rest of Octopus is compiled.
- What was in Octopus's BEGIN is executed.
- The rest of Octopus is executed.
- The rest of Spiderman is compiled.
- What was in Spiderman's BEGIN is executed.
- The rest of Spiderman is executed.
- Doctor::Octopus->import is called.
Remember that
use Module
means
BEGIN {
require Module;
Module->import if Module->can('import');
}