develooper Front page | perl.perl5.porters | Postings from April 2007

matters of no import (was: Smack!)

Thread Next
From:
Tom Christiansen
Date:
April 19, 2007 21:19
Subject:
matters of no import (was: Smack!)
Message ID:
12130.1177042719@chthon
>But I don't want to use 'warnings -> unimport'.
>I want to do 'use warnings' and 'no warnings'.

>> >             *{"warnings::unimport"} =3D sub {0};
>>
>> Why define your own unimport?

>    $ /opt/perl/5.005/bin/perl -le 'BEGIN {$INC {"warnings.pm"} = 1;}
>                                    no warnings;'
>    Can't locate object method "unimport" via package "warnings" at -e line
> 1.
>    BEGIN failed--compilation aborted at -e line 1.

>    $ /opt/perl/5.005/bin/perl -le 'BEGIN {$INC {"warnings.pm"} = 1;
>                                    *{"warnings::unimport"} = sub {0};}
>                                    no warnings;'

You know, it's bad enough that a missing import is silently suppressed, but
the asymmetric treatment of unimport() compared with import() is one of
those add-insult-to-silliness go-figger kinds of things.  Yes, I perfectly
understand why a missing import is ignored: so one can use() modules that
have no import()s of their own:

    % perl -e 'Tirnanog->import'
    Exit 0

That said, I do not quite see why one should in the best of all worlds
be quite so lenient with specific import targets silently failing:

    % perl -e 'Tirnanog->import("dreams")'
    Exit 0

In fact, I almost think that only the failed argless import of a use should
be silently suppressed, but no other.   Thus:

    #WRITTEN#
    use Module;

    #COMPILED#
    BEGIN {
	require Module;
	eval { Module::->import };  # 
    } 

but 

    #WRITTEN#
    use Module LIST;

    #COMPILED#
    BEGIN {
	require Module;
	Module::->import(LIST);  # NB: no error suppression here
    } 

and leaving as always 

    #WRITTEN#
    use Module ();

    #COMPILED#
    BEGIN {
	require Module;
    }

Except for the fact that an import that raises an exception has
that go through:

    % perl -e 'sub import { print "importing\n" } main::->import'
    importing
    Exit 0

    % perl -e 'sub import { die "importing" } main::->import'
    importing at -e line 1.
    Exit 255

So you you'd really prefer something more like 

    #WRITTEN#
    use Module;

    #COMPILED#
    BEGIN {
	require Module;
	Module::->import if Module::->can("import");
	# XXX: undeclared import()s triggered by AUTOLOAD()s missed here
    }

Still, something along that lines doesn't seem too egregious.  It's 
not all that much more of a hack than the way use() is hacked so that

    use Module 4.20;

works even when there is no real import().  Actually, that hack 
*also* leads to unpleasant asymmetries:

    % perl -e 'use lib "9"; print "ok\n"'
    Exit 0

    % perl -e 'use lib 9; print "ok\n"'
    lib version 9 required--this is only version 0.5565 at -e line 1.
    BEGIN failed--compilation aborted at -e line 1.
    Exit 255

compared with:

    % perl -e 'use File::Basename "3"; print "ok\n"'
    File::Basename version 3 required--this is only version 2.73 at /usr/local/lib/perl5/5.8.7/Exporter/Heavy.pm line 121.
    BEGIN failed--compilation aborted at -e line 1.
    Exit 255

    % perl -e 'use File::Basename 3; print "ok\n"'
    File::Basename version 3 required--this is only version 2.73 at -e line 1.
    BEGIN failed--compilation aborted at -e line 1.
    Exit 255

Hard to look favorably on that disparity from where I sit.

--tom

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About