Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggested warning on attempt to 'use' with arguments when no import() subroutine exists #16237

Open
p5pRT opened this issue Nov 10, 2017 · 31 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 10, 2017

Migrated from rt.perl.org#132425 (status was 'open')

Searchable as RT132425$

@p5pRT
Copy link
Author

p5pRT commented Nov 10, 2017

From @epa

If a module doesn't define an import subroutine, but the caller tries
to 'use' that module specifying an import list, this should generate a
warning. For example

% echo 'package A; sub foo {}; 1;' >A.pm
% perl -wE 'use A qw(foo)'

This should print something like

  You asked to import 'foo' from package A, but that package does not
  define an import() subroutine, so nothing has been imported.

Of course, if the module uses Exporter or some other code, that will
handle all the cases of generating warnings for things that aren't
exported. I am talking only about the case when

  - the module does not define any import() subroutine, and
  - the caller has provided extra arguments in the 'use' call.

Since those extra arguments are useless, and quite likely indicate
some confusion of the programmer, they should trigger a warning.


Flags​:
  category=core
  severity=low


Site configuration information for perl 5.22.2​:

Configured by Red Hat, Inc. at Fri Nov 4 14​:35​:02 UTC 2016.

Summary of my perl5 (revision 5 version 22 subversion 2) configuration​:

  Platform​:
  osname=linux, osvers=4.7.9-200.fc24.x86_64, archname=x86_64-linux-thread-multi
  uname='linux buildvm-12.phx2.fedoraproject.org 4.7.9-200.fc24.x86_64 #1 smp thu oct 20 14​:26​:16 utc 2016 x86_64 x86_64 x86_64 gnulinux '
  config_args='-des -Doptimize=none -Dccflags=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Dldflags=-Wl,-z,relro -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.22.2 -Dmyhostname=localhost -Dperladmin=root@​localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize=' -g',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include'
  ccversion='', gccversion='5.3.1 20160406 (Red Hat 5.3.1-6)', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='gcc', ldflags ='-Wl,-z,relro -fstack-protector-strong -L/usr/local/lib'
  libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib
  libs=-lpthread -lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
  perllibs=-lpthread -lresolv -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=libc-2.22.so, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version='2.22'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro '
  cccdlflags='-fPIC', lddlflags='-shared -Wl,-z,relro -L/usr/local/lib -fstack-protector-strong'

Locally applied patches​:
  Fedora Patch1​: Removes date check, Fedora/RHEL specific
  Fedora Patch3​: support for libdir64
  Fedora Patch4​: use libresolv instead of libbind
  Fedora Patch5​: USE_MM_LD_RUN_PATH
  Fedora Patch6​: Skip hostname tests, due to builders not being network capable
  Fedora Patch7​: Dont run one io test due to random builder failures
  Fedora Patch15​: Define SONAME for libperl.so
  Fedora Patch16​: Install libperl.so to -Dshrpdir value
  Fedora Patch22​: Document Math​::BigInt​::CalcEmu requires Math​::BigInt (CPAN RT#85015)
  Fedora Patch26​: Make *DBM_File desctructors thread-safe (RT#61912)
  Fedora Patch27​: Make PadlistNAMES() lvalue again (CPAN RT#101063)
  Fedora Patch28​: Make magic vtable writable as a work-around for Coro (CPAN RT#101063)
  Fedora Patch29​: Fix duplicating PerlIO​::encoding when spawning threads (RT#31923)
  Fedora Patch30​: Do not let XSLoader load relative paths (CVE-2016-6185)
  Fedora Patch31​: Avoid loading optional modules from default . (CVE-2016-1238)
  Fedora Patch32​: Fix a crash in lexical scope warnings (RT#128597)
  Fedora Patch33​: Do not mangle errno from failed socket calls (RT#128316)
  Fedora Patch34​: Fix crash in "evalbytes S" (RT#129196)
  Fedora Patch35​: Fix crash in "evalbytes S" (RT#129196)
  Fedora Patch36​: Fix crash in "evalbytes S" (RT#129196)
  Fedora Patch37​: Fix crash in splice (RT#129164, RT#129166, RT#129167)
  Fedora Patch38​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch39​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch40​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch41​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch42​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch43​: Fix crash when matching UTF-8 string with non-UTF-8 substrings (RT#129350)
  Fedora Patch44​: Fix parsing perl options in shell bang line (RT#129336)
  Fedora Patch45​: Fix firstchar bitmap under UTF-8 with prefix optimization (RT#129950)
  Fedora Patch46​: Avoid infinite loop in h2xs tool if enum and type have the same name (RT130001)
  Fedora Patch47​: Fix stack handling when calling chdir without an argument (RT#129130)
  Fedora Patch200​: Link XS modules to libperl.so with EU​::CBuilder on Linux
  Fedora Patch201​: Link XS modules to libperl.so with EU​::MM on Linux


@​INC for perl 5.22.2​:
  /home/eda/lib64/perl5/
  /usr/local/lib64/perl5
  /usr/local/share/perl5
  /usr/lib64/perl5/vendor_perl
  /usr/share/perl5/vendor_perl
  /usr/lib64/perl5
  /usr/share/perl5


Environment for perl 5.22.2​:
  HOME=/home/eda
  LANG=en_GB.UTF-8
  LANGUAGE (unset)
  LC_COLLATE=C
  LC_CTYPE=en_GB.UTF-8
  LC_MESSAGES=en_GB.UTF-8
  LC_MONETARY=en_GB.UTF-8
  LC_NUMERIC=en_GB.UTF-8
  LC_TIME=en_GB.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/eda/bin​:/home/eda/bin​:/home/eda/bin​:/usr/local/bin​:/usr/bin​:/usr/local/sbin​:/usr/sbin​:/sbin​:/usr/sbin​:/home/eda/.local/bin​:/home/eda/bin​:/sbin​:/usr/sbin​:/sbin​:/usr/sbin
  PERL5LIB=/home/eda/lib64/perl5/
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 10, 2017

From @epa

The bug tracker ate the message text, or at least refuses to show it on the web page, so here it is​:

If a module doesn't define an import subroutine, but the caller tries
to 'use' that module specifying an import list, this should generate a
warning. For example

% echo 'package A; sub foo {}; 1;' >A.pm
% perl -wE 'use A qw(foo)'

This should print something like

  You asked to import 'foo' from package A, but that package does not
  define an import() subroutine, so nothing has been imported.

Of course, if the module uses Exporter or some other code, that will
handle all the cases of generating warnings for things that aren't
exported. I am talking only about the case when

  - the module does not define any import() subroutine, and
  - the caller has provided extra arguments in the 'use' call.

Since those extra arguments are useless, and quite likely indicate
some confusion of the programmer, they should trigger a warning.


Flags​:
  category=core
  severity=low


Site configuration information for perl 5.22.2​:

Configured by Red Hat, Inc. at Fri Nov 4 14​:35​:02 UTC 2016.

Summary of my perl5 (revision 5 version 22 subversion 2) configuration​:
 
  Platform​:
  osname=linux, osvers=4.7.9-200.fc24.x86_64, archname=x86_64-linux-thread-multi
  uname='linux buildvm-12.phx2.fedoraproject.org 4.7.9-200.fc24.x86_64 #1 smp thu oct 20 14​:26​:16 utc 2016 x86_64 x86_64 x86_64 gnulinux '
  config_args='-des -Doptimize=none -Dccflags=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Dldflags=-Wl,-z,relro -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.22.2 -Dmyhostname=localhost -Dperladmin=root@​localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize=' -g',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include'
  ccversion='', gccversion='5.3.1 20160406 (Red Hat 5.3.1-6)', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='gcc', ldflags ='-Wl,-z,relro -fstack-protector-strong -L/usr/local/lib'
  libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib
  libs=-lpthread -lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
  perllibs=-lpthread -lresolv -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=libc-2.22.so, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version='2.22'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro '
  cccdlflags='-fPIC', lddlflags='-shared -Wl,-z,relro -L/usr/local/lib -fstack-protector-strong'

Locally applied patches​:
  Fedora Patch1​: Removes date check, Fedora/RHEL specific
  Fedora Patch3​: support for libdir64
  Fedora Patch4​: use libresolv instead of libbind
  Fedora Patch5​: USE_MM_LD_RUN_PATH
  Fedora Patch6​: Skip hostname tests, due to builders not being network capable
  Fedora Patch7​: Dont run one io test due to random builder failures
  Fedora Patch15​: Define SONAME for libperl.so
  Fedora Patch16​: Install libperl.so to -Dshrpdir value
  Fedora Patch22​: Document Math​::BigInt​::CalcEmu requires Math​::BigInt (CPAN RT#85015)
  Fedora Patch26​: Make *DBM_File desctructors thread-safe (RT#61912)
  Fedora Patch27​: Make PadlistNAMES() lvalue again (CPAN RT#101063)
  Fedora Patch28​: Make magic vtable writable as a work-around for Coro (CPAN RT#101063)
  Fedora Patch29​: Fix duplicating PerlIO​::encoding when spawning threads (RT#31923)
  Fedora Patch30​: Do not let XSLoader load relative paths (CVE-2016-6185)
  Fedora Patch31​: Avoid loading optional modules from default . (CVE-2016-1238)
  Fedora Patch32​: Fix a crash in lexical scope warnings (RT#128597)
  Fedora Patch33​: Do not mangle errno from failed socket calls (RT#128316)
  Fedora Patch34​: Fix crash in "evalbytes S" (RT#129196)
  Fedora Patch35​: Fix crash in "evalbytes S" (RT#129196)
  Fedora Patch36​: Fix crash in "evalbytes S" (RT#129196)
  Fedora Patch37​: Fix crash in splice (RT#129164, RT#129166, RT#129167)
  Fedora Patch38​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch39​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch40​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch41​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch42​: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267)
  Fedora Patch43​: Fix crash when matching UTF-8 string with non-UTF-8 substrings (RT#129350)
  Fedora Patch44​: Fix parsing perl options in shell bang line (RT#129336)
  Fedora Patch45​: Fix firstchar bitmap under UTF-8 with prefix optimization (RT#129950)
  Fedora Patch46​: Avoid infinite loop in h2xs tool if enum and type have the same name (RT130001)
  Fedora Patch47​: Fix stack handling when calling chdir without an argument (RT#129130)
  Fedora Patch200​: Link XS modules to libperl.so with EU​::CBuilder on Linux
  Fedora Patch201​: Link XS modules to libperl.so with EU​::MM on Linux


@​INC for perl 5.22.2​:
  /home/eda/lib64/perl5/
  /usr/local/lib64/perl5
  /usr/local/share/perl5
  /usr/lib64/perl5/vendor_perl
  /usr/share/perl5/vendor_perl
  /usr/lib64/perl5
  /usr/share/perl5


Environment for perl 5.22.2​:
  HOME=/home/eda
  LANG=en_GB.UTF-8
  LANGUAGE (unset)
  LC_COLLATE=C
  LC_CTYPE=en_GB.UTF-8
  LC_MESSAGES=en_GB.UTF-8
  LC_MONETARY=en_GB.UTF-8
  LC_NUMERIC=en_GB.UTF-8
  LC_TIME=en_GB.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/eda/bin​:/home/eda/bin​:/home/eda/bin​:/usr/local/bin​:/usr/bin​:/usr/local/sbin​:/usr/sbin​:/sbin​:/usr/sbin​:/home/eda/.local/bin​:/home/eda/bin​:/sbin​:/usr/sbin​:/sbin​:/usr/sbin
  PERL5LIB=/home/eda/lib64/perl5/
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 10, 2017

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2017

From @hvds

On Fri, 10 Nov 2017 04​:33​:52 -0800, eda@​waniasset.com wrote​:

If a module doesn't define an import subroutine

But every module gets an import subroutine​: if not their own, their parent's (and at least UNIVERSAL's).

Hugo

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2017

From zefram@fysh.org

Hugo van der Sanden via RT wrote​:

But every module gets an import subroutine​: if not their own, their
parent's (and at least UNIVERSAL's).

No, UNIVERSAL doesn't contain an import method. There's specific logic
in the method calling mechanism that provides what amounts to an empty
method if "import" or "unimport" is being looked up and there isn't any
actual method, but ->can can see the lack of a method​:

$ perl -lwe 'print "main"->can("import") // "no method"; print eval { "main"->import; 1 } ? "ok" : "fail"'
no method
ok

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2017

From @hvds

On Sat, 11 Nov 2017 02​:44​:01 -0800, zefram@​fysh.org wrote​:

Hugo van der Sanden via RT wrote​:

But every module gets an import subroutine​: if not their own, their
parent's (and at least UNIVERSAL's).

No, UNIVERSAL doesn't contain an import method. There's specific logic
in the method calling mechanism that provides what amounts to an empty
method if "import" or "unimport" is being looked up and there isn't any
actual method, but ->can can see the lack of a method​:

$ perl -lwe 'print "main"->can("import") // "no method"; print eval {
"main"->import; 1 } ? "ok" : "fail"'
no method
ok

That looks hard to distinguish from 'has an import method, but can() lies about it'. :)

But in any case the answer changes if anything has loaded UNIVERSAL​:
% perl -MUNIVERSAL -lwe 'print "main"->can("import") // "no method"; print eval { "main"->import(1); 1 } ? "ok" : "fail"'
CODE(0x1561678)
ok
%

For Ed's original suggestion​: if we can reliably detect that there's no explicit import() in the inheritance chain, the suggestion of warning on a useless import arg seems valid, but the above suggests to me that the result would vary depending on whether UNIVERSAL had been loaded, which would at best make it less useful and at worst invalidate the idea.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Nov 13, 2017

From @epa

Wouldn't the answer be to also tweak UNIVERSAL​::import? It could be something like

sub import {
  return unless @​_ > 1;
  require Carp;
  if ($_[0] eq __PACKAGE__) {
  # Called as UNIVERSAL​::import.
  Carp​::croak("UNIVERSAL does not export anything");
  }
  else {
  # Called as part of lookup from some other package.
  Carp​::carp("Useless arguments provided to $_[0]​::import​: @​_");
  }
}

Combined with a warning in the core language to cover the case when UNIVERSAL hasn't been loaded.

@p5pRT
Copy link
Author

p5pRT commented Nov 16, 2017

From @xsawyerx

On 11/11/2017 06​:43 PM, Hugo van der Sanden via RT wrote​:

On Sat, 11 Nov 2017 02​:44​:01 -0800, zefram@​fysh.org wrote​:

Hugo van der Sanden via RT wrote​:

But every module gets an import subroutine​: if not their own, their
parent's (and at least UNIVERSAL's).
No, UNIVERSAL doesn't contain an import method. There's specific logic
in the method calling mechanism that provides what amounts to an empty
method if "import" or "unimport" is being looked up and there isn't any
actual method, but ->can can see the lack of a method​:

$ perl -lwe 'print "main"->can("import") // "no method"; print eval {
"main"->import; 1 } ? "ok" : "fail"'
no method
ok
That looks hard to distinguish from 'has an import method, but can() lies about it'. :)

But in any case the answer changes if anything has loaded UNIVERSAL​:
% perl -MUNIVERSAL -lwe 'print "main"->can("import") // "no method"; print eval { "main"->import(1); 1 } ? "ok" : "fail"'
CODE(0x1561678)
ok
%

For Ed's original suggestion​: if we can reliably detect that there's no explicit import() in the inheritance chain, the suggestion of warning on a useless import arg seems valid, but the above suggests to me that the result would vary depending on whether UNIVERSAL had been loaded, which would at best make it less useful and at worst invalidate the idea.

I agree this is a good suggestion if we could reliably detect it.

I'm not versed enough with the technical details on this but if we can
determine we cannot reliably detect this, we should close the ticket.

@p5pRT
Copy link
Author

p5pRT commented Nov 16, 2017

From zefram@fysh.org

Sawyer X wrote​:

I agree this is a good suggestion if we could reliably detect it.

The import method from the UNIVERSAL module is itself a way of detecting
a bad import call. It has explicit code to do nothing if called on a
package other than UNIVERSAL, imitating the core behaviour when there's no
import method. At the same time as introducing different core behaviour,
we could extend this import method to imitate the new core behaviour.

It's nasty to have a non-empty UNIVERSAL module. That import method
exists only to support "use UNIVERSAL;", but that's a pretty silly usage
since the only thing it installs is that import method. (It's also not
a usage advised by the module's synopsis.) I think, independent of what
we do with unhandled import calls, we should deprecate "use UNIVERSAL;"
and ultimately delete that import method. People who just want to
load the module to check its version number can "use UNIVERSAL ();".
Or, more radically, we could remove the module entirely and turn it
into just a .pod file, though we'd want to make sure the package name
remained reserved in PAUSE.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 16, 2017

From @davidnicol

untested draft. Extra points for revising to pull file, line data out of
correct layer of caller() data.

cat > NoImportWarning.pm <<END
package WarnOnUseWithoutImport;

sub UNIVERSAL​::import {
@​_ == 1 and return;
warn "PACKAGE $_[0] USED WITH ARGUMENTS\n"
};
END

On Fri, Nov 10, 2017 at 6​:33 AM, Ed Avis <perlbug-followup@​perl.org> wrote​:

% echo 'package A; sub foo {}; 1;' >A.pm
% perl -wE 'use A qw(foo)'

This should print something like

You asked to import 'foo' from package A, but that package does not
define an import() subroutine, so nothing has been imported.

--
Hi-jinks ensue.

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From zefram@fysh.org

Ed Avis wrote​:

If a module doesn't define an import subroutine, but the caller tries
to 'use' that module specifying an import list, this should generate a
warning.

I'm not interested in this warning per se, but it seems like
an excellent thing to deprecate. I have implemented on branch
zefram/deprecate_some_fake_import a deprecation of (a) calls to undefined
"import" methods with arguments and (b) all calls to undefine "unimport"
methods.

We can expect that this deprecation wouldn't get triggered very much, and
that almost all things that hit it would actually be bugs. It reveals a
handful of bugs in the core distro, for example that Porting/GitUtils.pm
doesn't declare a package and so drops its subs straight into the main
package (which accidentally works, because that's where the caller wanted
to import them).

A few days ago I had a stab at a more radical deprecation that would also
cover no-args calls to "import" methods, but that produces a surprisingly
large amount of noise. Of course it would be deprecating some things that
are not bugs, because of the use of "use Some​::Class;", but I was taken
aback at how numerous they were. The deprecation that I'm proposing
now doesn't touch that usage at all. I'd still like to tackle no-args
"import" calls in some way in the future, because the current behaviour
hides bugs involving mismatched package names, but it would require a
more nuanced approach. In any case, that's for a future decision.

If there's a consensus that this deprecation is in principle a good idea,
then there's nothing preventing us merging this for 5.28.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From @hvds

On Mon, 11 Dec 2017 17​:41​:34 -0800, zefram@​fysh.org wrote​:

I have implemented on branch
zefram/deprecate_some_fake_import a deprecation of (a) calls to undefined
"import" methods with arguments and (b) all calls to undefine "unimport"
methods.

We can expect that this deprecation wouldn't get triggered very much, and
that almost all things that hit it would actually be bugs. It reveals a
handful of bugs in the core distro [...]

I like this; I suspect it's going to reveal a bunch of bugs on CPAN though (and probably, eventually, in the darkPAN).

It also suggests to me the perlfunc entry for 'use' may be insufficient (despite already being pretty long), and would benefit from a more canonically proscriptive definition of VERSION and a couple of examples - I'd have walked straight past C<use App​::Cpan '1.64';> or C<use ExtUtils​::ParseXS​::Constants $VERSION;>, for example, without noticing anything amiss.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From zefram@fysh.org

Hugo van der Sanden via RT wrote​:

It also suggests to me the perlfunc entry for 'use' may be insufficient
(despite already being pretty long), and would benefit from a more
canonically proscriptive definition of VERSION

Yes, good point. I've expanded it a bit in commit
d540724.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From @epa

Thanks for your work on this. How do you feel about another warning (or deprecation)
when the source file that gets 'used' does not declare a package?

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From zefram@fysh.org

Ed Avis via RT wrote​:

How do you feel about another warning (or deprecation)
when the source file that gets 'used' does not declare a package?

I'm still not interested in warnings per se. The question of what should
warn is too subjective; the significance of a warning is too woolly.
I'd be interested in actual deprecation.

But module/package mismatch is a tricky area. Unlike
undefined-import-with-args, there's real code doing that intentionally.
I'd really like to do something more to rein in the potential for bugs,
but almost anything beyond the deprecation that I've already proposed
would hit some legitimate code.

There are multiple things not being checked around here, which interact
to provide a profound failure to detect errors, and make the resulting
bugs quite frustrating to track down. A module file might fail to
specify a package, as you suggest; it can also specify a package other
than the one corresponding to the module name. That can happen through
renaming, or a typo, or a module reachable under multiple names because
of a case-insensitive filesystem. With neither that nor the lack of an
import method being an error, it takes quite a while for a module/package
mismatch to show up.

At a previous workplace I instituted a stricture to avoid these problems.
The rule was that every module file must have a package declaration,
matching the module file name, as the first thing apart from comments
and pod. This was enforced by a test script that would search for all
the module files in the codebase and read their content.

We could potentially implement some version of that stricture in the core
at module load time. It would catch all module/package mismatch bugs,
but would require some tricky modules that weren't otherwise buggy to add
a package declaration to satisfy this new requirement. They're still free
to change to a different package afterwards, of course. But currently
there's also the option to have no package declaration, in which case,
bizarrely, the module is compiled in the caller's package. If there's
any code using that behaviour deliberately then we'd be denying it an
ability that can't be achieved another way. It's something that modules
shouldn't be doing anyway, but it's inevitable that someone would complain
about losing it.

Incidentally, there's a question about how warnings should be managed
here. I'm thinking about a deprecation warning, but it would also apply
to any just-a-warning. The question is which set of lexical warning flags
should govern the warning about module/package mismatch. It doesn't make
a lot of sense for it to be the caller's flags, because the `caller' here
isn't really a caller as usually understood. Not every site "use"ing
a module causes the module to be loaded and parsed, so not every site
gets the opportunity to have its warning state applied to the module.
The effective caller for the module load is an accidental selection from
the "use"rs, whichever one happens to execute first. So that leaves
the module's own lexical warning state. But if the thing being warned
about is whatever comes first in the module code, that gives the module
no opportunity to set the warning flags first. So if the warning is to
appear at all, it would be effectively unmufflable except through the
-X option. This would probably be acceptable for a deprecation warning
(though it's not nice), but would surely not fly for a permanent warning.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From @epa

Maybe the small number of oddball modules that don't want any package declaration should have a way to declare that explicitly.

  no package;

or whatever syntax you think appropriate.

If a module source file is loaded by 'use', and does not declare a package or explicitly declare no-package, then it triggers a diagnostic.

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From @cpansprout

On Tue, 12 Dec 2017 03​:07​:11 -0800, zefram@​fysh.org wrote​:

But currently
there's also the option to have no package declaration, in which case,
bizarrely, the module is compiled in the caller's package. If there's
any code using that behaviour deliberately then we'd be denying it an
ability that can't be achieved another way. It's something that modules
shouldn't be doing anyway, but it's inevitable that someone would complain
about losing it.

All right, I’ll make your complaint prediction come true. ‘require "path/to/_utils_private_to_this_module.pl"’ is quite useful. Why should require be stricter when the file ends in .pm?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From @epa

Why have two different kinds of library, .pl and .pm, unless they differ in behaviour in some way?

Generally though I think that 'require' can stay as it is. It's used only by those who know what they are doing and have consciously decided to roll their own library loading and importing. It's 'use' that ought to be stricter, in my view. And if that means that 'use' is no longer exactly equivalent to BEGIN { require blah; import blah }, so be it.

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From zefram@fysh.org

Father Chrysostomos via RT wrote​:

Why should require be stricter when the file ends in .pm?

I didn't say that it should. But this raises another issue, of exactly
what should be the trigger for the stricter behaviour. Clearly there
should continue to be some facility to read and execute code from an
arbitrary file without regard to whether it satisfies our expectations
for modules. But in the common case of loading a module through "use" or
equivalents, we'd like to apply some extra stricture to make sure module
loading is having the intended effect. Currently "use" is defined in
terms of "require", and "require" on a .pm behaves the same as "require"
on any other file. Something in the chain of equivalences would have
to change, and I don't have a firm opinion about which part it should be.

An obvious way to keep interfaces clean would be for "require" to keep
its current behaviour and to introduce a new variant of it that applies
the package restriction. "use" and other module loading frontends would
switch to the new one. But this somewhat breaks the significance of
%INC​: all file loads that get once-only semantics through %INC would
not be equivalent.

Another way is what you suggest, for "require" to apply the stricture
based on the filename. This breaks the generality of "require", but
has the advantage that it applies the stricture uniformly to loads of
what we think are module files, and it doesn't require module loading
frontends to change.

Another option is that "require" behaves as it does now except that in
addition to filling %INC it also stores some record of what package
(if any) was declared at the start of the file. One can then apply
the stricture after the fact by checking this additional record.
Module loading frontends would apply the extra check, and other users
of "require" would not. This way all file loads remain equivalent,
and a .pm can be shared cleanly between module loading purposes and
non-module loads.

Is your concern strictly about keeping clean behaviour for "require",
or do you have an actual objection to imposing this sort of stricture
on module files that are being used as modules?

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2017

From @cpansprout

On Tue, 12 Dec 2017 09​:25​:14 -0800, zefram@​fysh.org wrote​:

Is your concern strictly about keeping clean behaviour for "require",
or do you have an actual objection to imposing this sort of stricture
on module files that are being used as modules?

‘use’ has already departed from equivalence with ‘require’, so I don’t think changing that equivalence further would be a problem.

I do worry, though, that requiring the very first statement to be a package declaration will break too much working code. Some people even put ‘use strict’ before the package declaration.

Maybe another approach would be to have ‘use’ check afterwards whether the right package has been defined. Of course, that does mean that code like this would prevent the check​:

  use Hash​::Util​::FieldHash;
  use Hash​::Util; # no check

(In case someone reading this does not understand why it would not work​: The Hash​::Util​::FieldHash package is *inside* the Hash​::Util package, so HU has to exist for HUFH to exist.)

But we can get around that by making package declarations set a flag on the hash. That part of the implementation would be trivial.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jan 2, 2018

From @xsawyerx

On 12/12/2017 03​:41 AM, Zefram wrote​:

Ed Avis wrote​:

If a module doesn't define an import subroutine, but the caller tries
to 'use' that module specifying an import list, this should generate a
warning.
I'm not interested in this warning per se, but it seems like
an excellent thing to deprecate. I have implemented on branch
zefram/deprecate_some_fake_import a deprecation of (a) calls to undefined
"import" methods with arguments and (b) all calls to undefine "unimport"
methods.

We can expect that this deprecation wouldn't get triggered very much, and
that almost all things that hit it would actually be bugs. It reveals a
handful of bugs in the core distro, for example that Porting/GitUtils.pm
doesn't declare a package and so drops its subs straight into the main
package (which accidentally works, because that's where the caller wanted
to import them).

I'm worried about this for several reasons. The sum of which are that
this seems like a good warning but not something to disallow.
Deprecating it is done with the intent of not allowing it. It could be
"unrecommended" but not removed.

I personally would turn it on, but I'm concerned about this as a removed
ability. We should attempt more permissive behavior, even when it
doesn't necessarily serve the user. Non-deprecation warnings with "use
warnings" provide that suggestive behavior of "Are you sure this is what
you want? I don't think so" that this achieves.

A contrived off-the-cuff example is a class that dictates you should
import things explicitly in order to allow later classes to possibly
implement an importing that does something with it. Some subclasses
won't and some will. This will fire for those that won't even though
it's part of the class API.

@p5pRT
Copy link
Author

p5pRT commented Jan 2, 2018

From zefram@fysh.org

Sawyer X wrote​:

A contrived off-the-cuff example is a class that dictates you should
import things explicitly in order to allow later classes to possibly
implement an importing that does something with it.

If the deprecation were implemented, it would provide the prompt for that
class to implement an actual import method that accepts those arguments.
An easy fix, and one of the relatively unusual cases of the fix being
on the callee side. It doesn't seem a big imposition, especially for
such a rare usage.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2018

From @xsawyerx

On 01/02/2018 04​:12 PM, Zefram wrote​:

Sawyer X wrote​:

A contrived off-the-cuff example is a class that dictates you should
import things explicitly in order to allow later classes to possibly
implement an importing that does something with it.
If the deprecation were implemented, it would provide the prompt for that
class to implement an actual import method that accepts those arguments.
An easy fix, and one of the relatively unusual cases of the fix being
on the callee side. It doesn't seem a big imposition, especially for
such a rare usage.

Following these are two questions​:

* Do we know how rare it really is? Maybe it's time to make use of
Andreas' offer to check a different branch against CPAN.
* Regardless of the breakage, is this something we want to declare as
illegal usage of the language? This is what I think deprecation truly
means and that should be a rare case.

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2018

From zefram@fysh.org

Sawyer X wrote​:

* Do we know how rare it really is? Maybe it's time to make use of
Andreas' offer to check a different branch against CPAN.

CPAN-smoking the deprecation branch, or a proof branch with that
deprecation made fatal, would not directly tell us how rare deliberate
use of the deprecated stuff is. Most things that hit the deprecation
will be minor bugs. We'd have to manually evaluate each module that
comes up to see whether it's deliberate.

* Regardless of the breakage, is this something we want to declare as
illegal usage of the language?

Yes​: it's a better language with these things ruled out.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2018

From @xsawyerx

On 01/03/2018 02​:53 PM, Zefram wrote​:

Sawyer X wrote​:

* Do we know how rare it really is? Maybe it's time to make use of
Andreas' offer to check a different branch against CPAN.
CPAN-smoking the deprecation branch, or a proof branch with that
deprecation made fatal, would not directly tell us how rare deliberate
use of the deprecated stuff is. Most things that hit the deprecation
will be minor bugs. We'd have to manually evaluate each module that
comes up to see whether it's deliberate.

Which is more worrisome since we cannot account on how much breakage
would hit.

* Regardless of the breakage, is this something we want to declare as
illegal usage of the language?
Yes​: it's a better language with these things ruled out.

Arguably one of the values of the language is its permissibility.

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2018

From zefram@fysh.org

Sawyer X wrote​:

Which is more worrisome since we cannot account on how much breakage
would hit.

That's a different question. A CPAN smoke can tell us how many modules
hit the deprecation at all, which in that context is the more significant
metric. A module that hits the deprecation ultimately needs to change,
whether it was using the deprecated behaviour deliberately or by accident.
Of course, it gets two years to change before the deprecation becomes
fatal, so depending on your definition of "breakage" maybe it doesn't
break at all.

Arguably one of the values of the language is its permissibility.

Arguably your brain would be better if every neuron were connected to
every other neuron. I wonder why it didn't evolve to be like that.
Indeed, in a late developmental period your brain gives up a lot of the
connections that it had.

It would be a rather superficial argument if permissitivity trumped
everything. The other side of that argument is that programming, as an
engineering activity, is founded on foreseeing the outcome of processes
that will take place automatically. This requires predictability; it
requires being able to rule things out. Obviously a balance needs to
be struck between flexibility and predictability.

In this case, the flexibility adds no value, and ruling out these
uses of the fake methods would have value in catching incipient bugs.
It's far from the first place we've seen where the first attempt at a
feature took the flexibility too far. It can be difficult to foresee
the emergent properties of a language design feature, especially when
flexible features start interacting. Now that we've seen the result
of the original version of fake import and unimport methods, we're in a
position to say that that was a design mistake. We are fortunate that
this is one of the mistakes that it is feasible to rectify.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 15, 2018

From @xsawyerx

On 01/03/2018 03​:57 PM, Zefram wrote​:

Sawyer X wrote​:

Which is more worrisome since we cannot account on how much breakage
would hit.
That's a different question. A CPAN smoke can tell us how many modules
hit the deprecation at all, which in that context is the more significant
metric. A module that hits the deprecation ultimately needs to change,
whether it was using the deprecated behaviour deliberately or by accident.
Of course, it gets two years to change before the deprecation becomes
fatal, so depending on your definition of "breakage" maybe it doesn't
break at all.

I would prefer to not the degree of affected modules before moving
forward with this. Deprecating this in a branch and CPAN smoking that
branch will tell us that, won't it?

Arguably one of the values of the language is its permissibility.
Arguably your brain would be better if every neuron were connected to
every other neuron. I wonder why it didn't evolve to be like that.
Indeed, in a late developmental period your brain gives up a lot of the
connections that it had.

You sweet talker. :)

It would be a rather superficial argument if permissitivity trumped
everything.

Not everything, but in many cases, yes.

The other side of that argument is that programming, as an
engineering activity, is founded on foreseeing the outcome of processes
that will take place automatically. This requires predictability; it
requires being able to rule things out. Obviously a balance needs to
be struck between flexibility and predictability.

In this case, the flexibility adds no value, and ruling out these
uses of the fake methods would have value in catching incipient bugs.

Are we certain of this in *every* case?

Is every case caught here a bug?

The problem is that any case in which it is not a bug requires an
arguably-unnecessary update and new release. This is not for free.

It's far from the first place we've seen where the first attempt at a
feature took the flexibility too far. It can be difficult to foresee
the emergent properties of a language design feature, especially when
flexible features start interacting. Now that we've seen the result
of the original version of fake import and unimport methods, we're in a
position to say that that was a design mistake. We are fortunate that
this is one of the mistakes that it is feasible to rectify.

I would be more comfortable if there was a smoked branch we could see
the effect of. If there were few catches, this would give me more
confidence in moving forward with this.

If not, there is always the next release.

@p5pRT
Copy link
Author

p5pRT commented Jan 15, 2018

From zefram@fysh.org

Sawyer X wrote​:

              Deprecating this in a branch and CPAN smoking that

branch will tell us that, won't it?

Kinda; it depends on the details of the smoking. If we attempt to install
all of CPAN on a perl built from the zefram/deprecate_some_fake_import
branch, and search the build log for instances of the deprecation warning,
that would tell us something about the prevalence of the deprecated usage.
However, we could expect a modules' deprecations to appear not only under
its own test suite, but also under the test suites of its dependents,
so there would be some (and potentially much) inflation of the count of
affected modules. Note that we have to search for the deprecation message
to get any information here, not just look for installation failures,
because the deprecation isn't expected to actually cause test failures.

Another possible approach is to construct a branch in which the
deprecation is fatal, and smoke that. This would make the affected
modules more obvious, because they'd fail their tests. Given proper care
in interpreting installation failures that arise from unmet dependencies,
this would also avoid overcounting, because dependents of affected
modules would fail that way.

Either way, we can't readily discern whether a module that depends on
an affected module is affected in its own right.

Are we certain of this in *every* case?

By the dynamic and reflective nature of Perl it is impossible to rule
out code intentionally making some bizarre use of the import mechanism
that would be affected. But such code would not be deriving value from
the mechanism​: it would only be obfuscated by the use of the fake methods.

Do you have some specific potential usage in mind?

Is every case caught here a bug?

Every case caught within the core distro was clearly a bug. Whether any
intentional use of the deprecated cases would show up on CPAN is an
open question; any that did show up would be quite a curiosity.

The problem is that any case in which it is not a bug requires an
arguably-unnecessary update and new release. This is not for free.

True, it is not free. That cost has to be weighed against the cost of
the bugs that would be caught.

I would be more comfortable if there was a smoked branch we could see
the effect of.

There's a branch there, you're free to give instructions to smoke it.
Let me know if you'd like to have the fatal version of that branch.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2018

From @xsawyerx

On 01/15/2018 10​:34 PM, Zefram wrote​:

Sawyer X wrote​:

              Deprecating this in a branch and CPAN smoking that

branch will tell us that, won't it?
Kinda; it depends on the details of the smoking. If we attempt to install
all of CPAN on a perl built from the zefram/deprecate_some_fake_import
branch, and search the build log for instances of the deprecation warning,
that would tell us something about the prevalence of the deprecated usage.
However, we could expect a modules' deprecations to appear not only under
its own test suite, but also under the test suites of its dependents,
so there would be some (and potentially much) inflation of the count of
affected modules. Note that we have to search for the deprecation message
to get any information here, not just look for installation failures,
because the deprecation isn't expected to actually cause test failures.

Another possible approach is to construct a branch in which the
deprecation is fatal, and smoke that. This would make the affected
modules more obvious, because they'd fail their tests. Given proper care
in interpreting installation failures that arise from unmet dependencies,
this would also avoid overcounting, because dependents of affected
modules would fail that way.

This is what I was thinking. Having a branch in which it is fatal. Then
testing CPAN to see how many such failures we get. I'm aware that some
modules used as dependency would be found - this is what happens now
with CPAN smoking anyway.

[...]

Are we certain of this in *every* case?
By the dynamic and reflective nature of Perl it is impossible to rule
out code intentionally making some bizarre use of the import mechanism
that would be affected. But such code would not be deriving value from
the mechanism​: it would only be obfuscated by the use of the fake methods.

This is good enough for me. I'm not expecting to find also odd
BEGIN-time string evals.

Do you have some specific potential usage in mind?

No. Just the basics.

Is every case caught here a bug?
Every case caught within the core distro was clearly a bug. Whether any
intentional use of the deprecated cases would show up on CPAN is an
open question; any that did show up would be quite a curiosity.

This is why I would like to smoke it more.

The problem is that any case in which it is not a bug requires an
arguably-unnecessary update and new release. This is not for free.
True, it is not free. That cost has to be weighed against the cost of
the bugs that would be caught.

But we do not know that cost. Testing can help illuminate both parts.

I would be more comfortable if there was a smoked branch we could see
the effect of.
There's a branch there, you're free to give instructions to smoke it.
Let me know if you'd like to have the fatal version of that branch.

If you can make a version of it fatal, we can take Andreas on his offer
to smoke a particular branch against CPAN.

@p5pRT
Copy link
Author

p5pRT commented Jan 28, 2018

From @Abigail

On Tue, Dec 12, 2017 at 11​:06​:03AM +0000, Zefram wrote​:

Ed Avis via RT wrote​:

How do you feel about another warning (or deprecation)
when the source file that gets 'used' does not declare a package?

I'm still not interested in warnings per se. The question of what should
warn is too subjective; the significance of a warning is too woolly.
I'd be interested in actual deprecation.

But module/package mismatch is a tricky area. Unlike
undefined-import-with-args, there's real code doing that intentionally.
I'd really like to do something more to rein in the potential for bugs,
but almost anything beyond the deprecation that I've already proposed
would hit some legitimate code.

Tons of code at $WORK would break if this were enforced.

  $ cat Foo.pm
  package Foo;
  #
  # Code which is available everywhere
  #
  1;
  __END__

  $ cat Foo/Special.pm
  package Foo;
  #
  # Code available on on Special roles, but still in the class Foo
  #
  1;
  __END__

is a not uncommon practise.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jan 28, 2018

From zefram@fysh.org

Sawyer X wrote​:

This is what I was thinking. Having a branch in which it is fatal.

OK. I've rebased zefram/deprecate_some_fake_import on blead,
and created zefram/deprecate_some_fake_import_fatal based on that
with the deprecation made fatal for testing. You'll want to have
zefram/deprecate_some_fake_import_fatal CPAN-smoked.

-zefram

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants