Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

import() magic

by ferrency (Deacon)
on May 29, 2002 at 19:23 UTC ( #170196=perlquestion: print w/replies, xml ) Need Help??

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

Please excuse me if this has been answered elsewhere.

What nature of magic causes this code...

#!/usr/local/bin/perl -w use strict; use Data::Dumper; my $x = bless {}, 'Foo'; print Dumper(\%Foo::); $x->import(qw(:blah foo whatever 123)); print Dumper(\%Foo::); $x->almost_any_method_besides_import(qw(:blah foo whatever 123)); print Dumper(\%Foo::);

...to output the following:

$VAR1 = {}; $VAR1 = { 'import' => *Foo::import }; Can't locate object method "almost_any_method_besides_import" via pack +age "Foo"\ at test.pl line 9.
According to all the perldoc I can find, import isn't special: it's just a class method of your class, which may or may not exist. And "use" doesn't care if it doesn't exist. (I notice that the pod at perlmonks.com says use doesn't raise an error if import doesn't exist, but my pod says use doesn't call import if it doesn't exist.)

However, the test above demonstrates that independant of use, trying to call method import which doesn't exist is handled differently than with almost any other method ("almost" only because I'm not 100% sure there is no other similar case... I don't know of any offhand, however).

I'd expect the above code to bomb on the $x->import line with an error message similar to the one shown for the second method call. Instead, it creates an import method in package Foo. Not only that, but the method does nothing instead of bombing because the things I'm trying to import don't exist.

Not only that, but use strict and warnings don't have anything to say on the matter either.

I have no problem with the fact that there's magic here, but I'd like to know what the magic is and where it's documented, to train myself that this is actually predictable :)

Thanks,

Alan

Replies are listed 'Best First'.
Re: import() magic
by Ovid (Cardinal) on May 29, 2002 at 20:00 UTC

    From perldoc -f use on 5.6.1: If no "import" method can be found then the call is skipped.

    What that means (to me) is that the appropriate typeglob in the appropriate namespace is searched for an import() method. However, we can't look for a slot in the typeglob without the typeglob existing, so Perl is autovivifying *import for you, if it doesn't exist. I don't know that this is documented anywhere, though.

    ferrency wrote:

    However, the test above demonstrates that independant of use, trying to call method import which doesn't exist is handled differently than with almost any other method ("almost" only because I'm not 100% sure there is no other similar case... I don't know of any offhand, however).

    There are other methods. Specifically, those that are inherited from the UNIVERSAL class (all objects inherit from there).

    Ovid@OT-D1 ~ $ perl -MData::Dumper -e ' my $x = bless {}, 'Foo'; print Dumper (\%Foo::); $x->can('bar'); print Dumper (\%Foo::); print Dumper (\%UNIVERSAL::)'

    That produces:

    $VAR1 = {}; $VAR1 = { 'can' => *Foo::can, 'bar' => *Foo::bar }; $VAR1 = { 'can' => *UNIVERSAL::can, 'bar' => *UNIVERSAL::bar, 'isa' => *UNIVERSAL::isa, 'VERSION' => *UNIVERSAL::VERSION };

    I think it's very interesting to note that testing to see if the your object can perform a particular method will autovivify the appropriate entry in the UNIVERSAL namespace if it's not found. I can't think of any way this will screw things up, but it seems a bit odd.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: import() magic
by broquaint (Abbot) on May 29, 2002 at 20:03 UTC
    Well this sure is crazy and appears to be undocumented behaviour[1]. But poking at the source for perl 5.6.1 it looks like it's quite normal for perl behave in this way. If you look at the Perl_gv_fetchmethod_autoload function in gv.c you'll find the following lines of code
    gv = gv_fetchmeth(stash, name, nend - name, 0); if (!gv) { if (strEQ(name,"import") || strEQ(name,"unimport")) gv = (GV*)&PL_sv_yes; else if (autoload) gv = gv_autoload4(stash, name, nend - name, TRUE); }
    So from what I gather the import and unimport methods are automatically handled by perl and internally autoloaded as scalar variables. As to why this is and what purpose it serves I am in totally in the dark.
    HTH

    _________
    broquaint

    [1] I sit corrected as Ovid points out in his node that this behaviour is documented albeit surreptitiously

      Actually, according to the docs: If no "unimport" method can be found the call fails with a fatal error., so this should fail:

      $ perl -e ' *UNIVERSAL::import = sub { print "Whoops!" }; my $x = bless {}, 'Foo'; $x->import; no Foo'

      Except it doesn't fail. This appears to be misdocumented. If you use strict, you'll get a baredword warning, but that's still not what the docs say. Am I misreading?

      Further, I think the symbol table entries should not be autovivified. If you're doing some funky work walking the symbol table, those 'faux' entries could cause bad results. I don't like it. Nosireebob. I don't.

      Cheers,
      Ovid

      Update: Added the word 'not'. Kinda changes the meaning, doncha think? :)

      Update 2: I submitted a POD patch to P5P, but Abigail beat me to it.

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

        From perldelta for perl 5.6.1:
        no Module; does not produce an error even if Module does not have an unimport() method. This parallels the behavior of use vis-a-vis import.

        Seems like they just forgot to update perlfunc.

        Cheers,
        -Anomo
Re: import() magic
by Anonymous Monk on May 29, 2002 at 21:58 UTC
    it creates an import method in package Foo

    Not really. While *Foo::import is defined &Foo::import isn't.

    Whenever a symbol is seen an entry in the symbol table is created. For instance, if you do
    use Data::Dumper; print Dumper(\%Foo::); exit; Foo::bar(); @Foo::baz;
    you see that both *Foo::bar and *Foo::baz exists in %Foo::.

    Cheers,
    -Anomo

      If the function is not being created, then how is it possible to call the function without crashing? This does not crash, for example:

      $x = bless {}, 'Foo'; $x->import( 'whatever' );

        If you read the docs carefully, you'll see that even though import is not a built-in, it is has 'magic' treatment.

        Ovid@OT-D1 ~ $ perl -e '$x=bless{}, "Foo";$x->import;print "Defined" if defined &Fo +o::import' Ovid@OT-D1 ~ $ perl -e 'print "Defined" if defined &UNIVERSAL::isa' Defined

        As you can see from the above snippet, even though we call an import method, none is actually defined in %Foo::. I threw in the %UNIVERSAL:: test so you can see how that test works. Here's proof that it is "special". Note that the call to the non-existent method &Foo::import is successful, but the second call to a non-existent method is not.

        $ perl -e '$x=bless{}, "Foo";$x->import;$x->no_way' Can't locate object method "no_way" via package "Foo" (perhaps you for +got to load "Foo"?) at -e line 1.

        Cheers,
        Ovid

        Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://170196]
Approved by VSarkiss
Front-paged by ehdonhon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2019-11-17 00:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (85 votes). Check out past polls.

    Notices?