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

Wise Monks, I find I have written code that works fine, at least it seems. But I cannot understand _why_ it works. It seems like it should not, there for I'm seeking understanding

I am generating a report, using PDF::API2. I've created myself a little helper object:

package AReport; use common::sense; use PDF::API2; use Exporter qw( import ); use constant mm => 25.4 / 72; use constant in => 1 / 72; use constant pt => 1; our @EXPORT = qw(mm in pt); use Class::Tiny qw(api x y pageW pageH bodyW bodyH); <etc...>
In my main file, I can use the constants, as well the AReport object:
use AReport; my $pdf = AReport->new( file => 'junk.pdf', pageW => 8.5/in );

It all seems to work, but there should be two import() procedures, one for Class:Tiny and one for Exporter. Only one should get called, but seems as both do? How?

Thank you for your time,

-Andy

Replies are listed 'Best First'.
Re: Class::Tiny and Exporter at the same time
by haukex (Archbishop) on Nov 13, 2016 at 17:47 UTC

    Hi jaandy,

    use Exporter qw(import); calls Exporter's import function at compile time, which simply copies &Exporter::import to &AReport::import.

    use constant mm => 25.4 / 72; etc. calls constant's import function at compile time, which sets up &AReport::mm etc.

    use Class::Tiny qw(api x ...); calls Class::Tiny's import function at compile time, which sets up &AReport::api, &AReport::x, etc. The key point here is that it does not set up &AReport::import, because a class doesn't need an import method.

    use AReport; calls &AReport::import - which is just Exporter's import - at compile time, which exports the functions you listed in @AReport::EXPORT in the caller's package (I guess main).

    Hope this helps,
    -- Hauke D

Re: Class::Tiny and Exporter at the same time
by choroba (Cardinal) on Nov 13, 2016 at 17:51 UTC
    The Exporter::import gets called when you run use Exporter , Class::Tiny::import gets called when you run use Class::Tiny . The former makes it possible to export the constants from your module (which happens when AReport::import is run, i.e. on use AReport ), the latter generates the accessors in your class.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Ahh! Now I understand. Thank you both very much.

      -Andy