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

Add more context information when raising WARN_REDEFINE #16145

Closed
p5pRT opened this issue Sep 12, 2017 · 12 comments
Closed

Add more context information when raising WARN_REDEFINE #16145

p5pRT opened this issue Sep 12, 2017 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 12, 2017

Migrated from rt.perl.org#132072 (status was 'rejected')

Searchable as RT132072$

@p5pRT
Copy link
Author

p5pRT commented Sep 12, 2017

From @atoomic

This is a bug report for perl from atoomic@​cpan.org,
generated with the help of perlbug 1.40 running under perl 5.26.0.


When a function is redefined, rather than printing the location of the
redefined function, it would be better to also know what caused the
redefinition of the function and where.

This is an idea introduced by Reini Urban in cperl via
perl11/cperl#113 which I think we migth consider
adopting in perl.

I'm aware that adding this behavior, this might break some CPAN unit tests
relying on the 'hardcoded warning string'. I think they should be easy to
fix to work with both flavors of the error message. The only one I'm aware
that needs to be fixed with this patch is Sub​::Install which Reini already
provided a patch via
rurban/distroprefs@6a163af
.



Flags​:
  category=core
  severity=wishlist


Site configuration information for perl 5.26.0​:

Configured by cPanel at Thu Aug 31 17​:31​:39 CDT 2017.

Summary of my perl5 (revision 5 version 26 subversion 0) configuration​:

  Platform​:
  osname=linux
  osvers=3.10.0-123.20.1.el7.x86_64
  archname=x86_64-linux-64int
  uname='linux rpmbuild-64-centos-7.dev.cpanel.net
3.10.0-123.20.1.el7.x86_64 #1 smp thu jan 29 18​:05​:33 utc 2015 x86_64
x86_64 x86_64 gnulinux '
  config_args='-des -Dusedevel -Darchname=x86_64-linux-64int
-Dcc=/usr/bin/gcc -Dcpp=/usr/bin/cpp -Dusemymalloc=n -DDEBUGGING=none
-Doptimize=-Os -Accflags=-m64 -Dccflags=-DPERL_DISABLE_PMC -fPIC -DPIC
-I/usr/local/cpanel/3rdparty/perl/526/include
-I/usr/local/cpanel/3rdparty/include -L/usr/local/cpanel/3rdparty/lib64
-Duseshrplib -Duselargefiles=yes -Duseposix=true -Dhint=recommended
-Duseperlio=yes -Dcppflags=-I/usr/local/cpanel/3rdparty/perl/526/include
-I/usr/local/cpanel/3rdparty/include -L/usr/local/cpanel/3rdparty/lib64
-Dldflags=-L/usr/local/cpanel/3rdparty/lib64
-Dprefix=/usr/local/cpanel/3rdparty/perl/526
-Dsiteprefix=/opt/cpanel/perl5/526 -Dsitebin=/opt/cpanel/perl5/526/bin
-Dsitelib=/opt/cpanel/perl5/526/site_lib -Dusevendorprefix=true
-Dvendorbin=/usr/local/cpanel/3rdparty/perl/526/bin
-Dvendorprefix=/usr/local/cpanel/3rdparty/perl/526/lib64/perl5
-Dvendorlib=/usr/local/cpanel/3rdparty/perl/526/lib64/perl5/cpanel_lib
-Dprivlib=/usr/local/cpanel/3rdparty/perl/526/lib64/perl5/5.26.0
-Dman1dir=none -Dman3dir=none
-Dscriptdir=/usr/local/cpanel/3rdparty/perl/526/bin
-Dscriptdirexp=/usr/local/cpanel/3rdparty/perl/526/bin -Dsiteman1dir=none
-Dsiteman3dir=none -Dinstallman1dir=none -Dversiononly=no
-Dinstallusrbinperl=no -Dcf_by=cPanel -Dmyhostname=localhost
-Dperladmin=root@​localhost -Dcf_email=support@​cpanel.net
-Di_dbm=/usr/local/cpanel/3rdparty/include
-Di_gdbm=/usr/local/cpanel/3rdparty/include
-Di_ndbm=/usr/local/cpanel/3rdparty/include -DDB_File=true -Ud_dosuid
-Uuserelocatableinc -Umad -Uusethreads -Uusemultiplicity -Uusesocks
-Uuselongdouble -Aldflags=-L/usr/local/cpanel/3rdparty/lib64 -L/usr/lib64
-L/lib64 -lgdbm -Dlocincpth=/usr/local/cpanel/3rdparty/perl/526/include
/usr/local/cpanel/3rdparty/include /usr/local/include
-Duse64bitint -Uuse64bitall -Dlibpth=/usr/local/cpanel/3rdparty/lib64
/usr/local/lib64 /usr/local/lib /lib64 /usr/lib64 '
  hint=recommended
  useposix=true
  d_sigaction=define
  useithreads=undef
  usemultiplicity=undef
  use64bitint=define
  use64bitall=undef
  uselongdouble=undef
  usemymalloc=n
  default_inc_excludes_dot=define
  bincompat5005=undef
  Compiler​:
  cc='/usr/bin/gcc'
  ccflags ='-DPERL_DISABLE_PMC -fPIC -DPIC
-I/usr/local/cpanel/3rdparty/perl/526/include
-I/usr/local/cpanel/3rdparty/include -L/usr/local/cpanel/3rdparty/lib64
-m64 -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-D_FORTIFY_SOURCE=2'
  optimize='-Os'
  cppflags='-I/usr/local/cpanel/3rdparty/perl/526/include
-I/usr/local/cpanel/3rdparty/include -L/usr/local/cpanel/3rdparty/lib64
-DPERL_DISABLE_PMC -fPIC -DPIC
-I/usr/local/cpanel/3rdparty/perl/526/include
-I/usr/local/cpanel/3rdparty/include -L/usr/local/cpanel/3rdparty/lib64
-m64 -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong
-I/usr/local/include'
  ccversion=''
  gccversion='4.8.2 20140120 (Red Hat 4.8.2-16)'
  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='/usr/bin/gcc'
  ldflags ='-L/usr/local/cpanel/3rdparty/lib64
-L/usr/local/cpanel/3rdparty/lib64 -L/usr/lib64 -L/lib64 -lgdbm
-fstack-protector-strong -L/usr/local/lib'
  libpth=/usr/local/cpanel/3rdparty/lib64 /usr/local/lib64 /usr/local/lib
/lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64
/lib
  libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
-lgdbm_compat
  perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=libc-2.17.so
  so=so
  useshrplib=true
  libperl=libperl.so
  gnulibc_version='2.17'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs
  dlext=so
  d_dlsymun=undef
  ccdlflags='-Wl,-E
-Wl,-rpath,/usr/local/cpanel/3rdparty/perl/526/lib64/perl5/5.26.0/x86_64-linux-64int/CORE'
  cccdlflags='-fPIC'
  lddlflags='-shared -Os -L/usr/local/cpanel/3rdparty/lib64 -L/usr/lib64
-L/lib64 -L/usr/local/lib -fstack-protector-strong'

Locally applied patches​:
  cPanel patches
  cPanel INC path changes
  cPanel performance improvements to modules
  cPanel Immortal COW
  cPanel B and O performance fixups
  cPanel B​::C Declare Static Memory malloc patches
  cPanel Disable XS handshake


@​INC for perl 5.26.0​:
  /root/.dotfiles/perl-must-have/lib
  /root/perl5/lib/perl5/
  /usr/local/cpanel

/usr/local/cpanel/3rdparty/perl/526/lib64/perl5/cpanel_lib/x86_64-linux-64int
  /usr/local/cpanel/3rdparty/perl/526/lib64/perl5/cpanel_lib

/usr/local/cpanel/3rdparty/perl/526/lib64/perl5/5.26.0/x86_64-linux-64int
  /usr/local/cpanel/3rdparty/perl/526/lib64/perl5/5.26.0
  /opt/cpanel/perl5/526/site_lib/x86_64-linux-64int
  /opt/cpanel/perl5/526/site_lib


Environment for perl 5.26.0​:
  HOME=/root
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=/usr/local/cpanel/3rdparty/perl/526/bin​:/usr/local/cpanel/3rdparty/perl/524/bin​:/usr/local/cpanel/3rdparty/perl/522/bin​:/usr/local/cpanel/3rdparty/perl/514/bin​:/usr/local/cpanel/3rdparty/bin​:/root/bin/​:/opt/local/bin​:/opt/local/sbin​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/opt/cpanel/composer/bin​:/root/.dotfiles/bin​:/root/perl5/bin​:/root/.rvm/bin​:/root/bin
  PERL5DB=use Devel​::NYTProf
  PERL5LIB=/root/.dotfiles/perl-must-have/lib​::/root/perl5/lib/perl5/
  PERL_BADLANG (unset)
  PERL_CPANM_OPT=--quiet
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Sep 12, 2017

From @atoomic

0001-Improve-WARN_REDEFINE-at-caller-file-line.patch
From e550d600a26f4fb3211aaa4ae0ba1ce3578df895 Mon Sep 17 00:00:00 2001
From: Reini Urban <rurban@cpanel.net>
Date: Wed, 23 Mar 2016 11:24:06 +0100
Subject: [PATCH] Improve WARN_REDEFINE, at caller file:line

When a function is redefined, rather than printing
the location of the redefined function, it would be
better to also know what caused the redefinition
of the function and where.

Adjust some core tests for improved WARN_REDEFINE.
Add a couple of ", called by file:line " strings to the warning.

References: BC-GH #113 https://github.com/perl11/cperl/issues/113

(cherry picked from commit a46cfee0292121906841e17ccfefc6a659509ff9)
(cherry picked from commit a1ee3de7ea8e0ed5246dde11d827df2bb56b0548)
Signed-off-by: Nicolas R <atoomic@cpan.org>
---
 ext/XS-APItest/t/newCONSTSUB.t |  6 +++---
 op.c                           | 21 +++++++++++++++++++--
 pod/perlsub.pod                |  9 +++++++++
 t/lib/warnings/op              | 10 +++++-----
 t/lib/warnings/sv              |  8 ++++----
 t/op/anonconst.t               |  2 +-
 t/op/const-optree.t            |  2 +-
 t/op/lexsub.t                  |  6 +++---
 t/op/stash.t                   |  2 +-
 t/run/fresh_perl.t             | 10 ++++++++--
 10 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/ext/XS-APItest/t/newCONSTSUB.t b/ext/XS-APItest/t/newCONSTSUB.t
index 2df850e0c0..63d9224186 100644
--- a/ext/XS-APItest/t/newCONSTSUB.t
+++ b/ext/XS-APItest/t/newCONSTSUB.t
@@ -14,7 +14,7 @@ use XS::APItest;
  local $SIG{__WARN__} = sub { $w .= shift };
  sub frimple() { 78 }
  newCONSTSUB_flags(\%::, "frimple", 0, undef);
- like $w, qr/Constant subroutine frimple redefined at /,
+ like $w, qr/Constant subroutine frimple redefined/,
    'newCONSTSUB constant redefinition warning is unaffected by $^W=0';
  undef $w;
  newCONSTSUB_flags(\%::, "frimple", 0, undef);
@@ -62,11 +62,11 @@ eval q{
  my $w;
  local $SIG{__WARN__} = sub { $w .= shift };
  newCONSTSUB_flags(\%foo::, "\x{100}", 0, undef);
- like $w, qr/Subroutine \x{100} redefined at /,
+ like $w, qr/Subroutine \x{100} redefined/,
    'newCONSTSUB redefinition warning + utf8';
  undef $w;
  newCONSTSUB_flags(\%foo::, "\x{100}", 0, 54);
- like $w, qr/Constant subroutine \x{100} redefined at /,
+ like $w, qr/Constant subroutine \x{100} redefined/,
    'newCONSTSUB constant redefinition warning + utf8';
 }
 
diff --git a/op.c b/op.c
index 06ec00b1e9..0affc4bf25 100644
--- a/op.c
+++ b/op.c
@@ -15441,12 +15441,29 @@ Perl_report_redefined_cv(pTHX_ const SV *name, const CV *old_cv,
 	 && ckWARN_d(WARN_REDEFINE)
 	 && (!new_const_svp || sv_cmp(old_const_sv, *new_const_svp))
 	)
-    )
-	Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
+      ) {
+        /* which module/srcline caused this forced require/do/eval redefinition */
+        if (cxstack_ix >= 0) {
+            const COP* const  cop  = cxstack[cxstack_ix].blk_oldcop;
+            const char* const file = cop ? OutCopFILE(cop) : "";
+            const char* const display_file = file ? file : "";
+            const long line = cop ? (long)CopLINE(cop) : 0;
+
+            if (!*file && !line) goto no_caller;
+            Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
+			  is_const
+			    ? "Constant subroutine %" SVf " redefined, called by %s:%ld"
+			    : "Subroutine %" SVf " redefined, called by %s:%ld",
+                          SVfARG(name), display_file, line);
+        } else {
+        no_caller:
+            Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
 			  is_const
 			    ? "Constant subroutine %" SVf " redefined"
 			    : "Subroutine %" SVf " redefined",
 			  SVfARG(name));
+        }
+    }
 }
 
 /*
diff --git a/pod/perlsub.pod b/pod/perlsub.pod
index 689d4a3837..ca0b5829f2 100644
--- a/pod/perlsub.pod
+++ b/pod/perlsub.pod
@@ -1769,6 +1769,15 @@ different than the warning for overriding non-inlined subroutines:
     $ perl -we 'sub one {1} sub one {2}'
     Subroutine one redefined at -e line 1.
 
+When the redefinition is caused by a wrong action in an upper scope,
+this location is printed also. E.g. by a C<require> and after messing
+with C<%INC>, a C<do FILE> statement, or an C<eval>. You generally
+want to know who caused this error, not where the function is defined.
+
+    $ perl -we 'do "utf8.pm";
+    do "utf8.pm";'
+    Subroutine import redefined, called by -e:2 at lib/utf8.pm line 7.
+
 The warning is considered severe enough not to be affected by the
 B<-w> switch (or its absence) because previously compiled invocations
 of the function will still be using the old value of the function.  If
diff --git a/t/lib/warnings/op b/t/lib/warnings/op
index d9116fa9d7..1a701890d6 100644
--- a/t/lib/warnings/op
+++ b/t/lib/warnings/op
@@ -1012,7 +1012,7 @@ Constant subroutine fred redefined at - line 3.
 sub fred () { 1 }
 *fred = sub () { 2 };
 EXPECT
-Constant subroutine main::fred redefined at - line 3.
+Constant subroutine main::fred redefined, called by -:0 at - line 3.
 ########
 # op.c
 use feature "lexical_subs", "state";
@@ -1784,7 +1784,7 @@ use open qw( :utf8 :std );
 sub fr��d () { 1 }
 *fr��d = sub () { 2 };
 EXPECT
-Constant subroutine main::fr��d redefined at - line 5.
+Constant subroutine main::fr��d redefined, called by -:0 at - line 5.
 ########
 # op.c
 use warnings 'redefine' ;
@@ -1822,7 +1822,7 @@ use open qw( :utf8 :std );
 sub �������� () { 1 }
 *�������� = sub () { 2 };
 EXPECT
-Constant subroutine main::�������� redefined at - line 5.
+Constant subroutine main::�������� redefined, called by -:0 at - line 5.
 ########
 # OPTION regex
 sub DynaLoader::dl_error {};
@@ -1841,9 +1841,9 @@ BEGIN {
 EOC
 EXPECT
 OPTION regex
-\ASubroutine DynaLoader::dl_error redefined at \(eval 1\) line 2\.
+\ASubroutine DynaLoader::dl_error redefined, called by \(eval 1\):2 at \(eval 1\) line 2\.
 ?(?s).*
-Subroutine DynaLoader::dl_error redefined at \(eval 2\) line 2\.
+Subroutine DynaLoader::dl_error redefined, called by \(eval 2\):3 at \(eval 2\) line 2\.
 ########
 # op.c
 use warnings;
diff --git a/t/lib/warnings/sv b/t/lib/warnings/sv
index 64f624c5ed..a4036e33d3 100644
--- a/t/lib/warnings/sv
+++ b/t/lib/warnings/sv
@@ -282,7 +282,7 @@ no warnings 'redefine' ;
 sub jim {} 
 *jim = \&joe ;
 EXPECT
-Subroutine main::fred redefined at - line 5.
+Subroutine main::fred redefined, called by -:0 at - line 5.
 ########
 # sv.c
 use warnings 'printf' ;
@@ -384,7 +384,7 @@ no warnings 'redefine' ;
 sub j��m {} 
 *j��m = \&j���� ;
 EXPECT
-Subroutine main::fr��d redefined at - line 7.
+Subroutine main::fr��d redefined, called by -:0 at - line 7.
 ########
 # sv.c
 use warnings 'redefine' ;
@@ -397,7 +397,7 @@ no warnings 'redefine' ;
 sub ��� {} 
 *��� = \&����� ;
 EXPECT
-Subroutine main::������ redefined at - line 7.
+Subroutine main::������ redefined, called by -:0 at - line 7.
 ########
 # sv.c
 my $x = "a_c";
@@ -423,4 +423,4 @@ sub Foo::f {}
 undef *Foo::;
 *Foo::f =sub {};
 EXPECT
-Subroutine f redefined at - line 5.
+Subroutine f redefined, called by -:0 at - line 5.
diff --git a/t/op/anonconst.t b/t/op/anonconst.t
index 89a6acbaba..2bfe08fc7b 100644
--- a/t/op/anonconst.t
+++ b/t/op/anonconst.t
@@ -39,7 +39,7 @@ is &{sub () : const { 42 }}, 42, ':const with truly constant sub';
     my $w;
     local $SIG{__WARN__} = sub { $w .= shift };
     *foo = sub (){};
-    like $w, qr/^Constant subroutine main::foo redefined at /,
+    like $w, qr/^Constant subroutine main::foo redefined/,
         ':const subs are constant';
 }
 
diff --git a/t/op/const-optree.t b/t/op/const-optree.t
index 4d897d247e..015486179e 100644
--- a/t/op/const-optree.t
+++ b/t/op/const-optree.t
@@ -457,7 +457,7 @@ for \%_ (@tests) {
         *temp_inlinability_test = sub (){};
 	my $S = $_{inlinable} ? "Constant s" : "S";
         my $not = " not" x! $_{inlinable};
-        like $w, qr/^${S}ubroutine .* redefined at /,
+        like $w, qr/^${S}ubroutine .* redefined/,
                 "$nickname is$not inlinable";
     }
     if (exists $_{method}) {
diff --git a/t/op/lexsub.t b/t/op/lexsub.t
index 3fa17acdda..2e23d9f8ff 100644
--- a/t/op/lexsub.t
+++ b/t/op/lexsub.t
@@ -1,5 +1,5 @@
 #!perl
-
+my $file = __FILE__;
 BEGIN {
     chdir 't' if -d 't';
     require './test.pl';
@@ -332,7 +332,7 @@ sub make_anon_with_state_sub{
   state $w;
   local $SIG{__WARN__} = sub { $w .= shift };
   eval "#line 56 pygpyf\nsub redef {}";
-  is $w, "Subroutine redef redefined at pygpyf line 56.\n",
+  is $w, "Subroutine redef redefined, called by $file:334 at pygpyf line 56.\n",
          "sub redefinition warnings from state subs";
 }
 {
@@ -669,7 +669,7 @@ sub make_anon_with_my_sub{
   my $w;
   local $SIG{__WARN__} = sub { $w .= shift };
   eval "#line 56 pygpyf\nsub redef {}";
-  is $w, "Subroutine redef redefined at pygpyf line 56.\n",
+  is $w, "Subroutine redef redefined, called by $file:671 at pygpyf line 56.\n",
          "sub redefinition warnings from my subs";
 
   undef $w;
diff --git a/t/op/stash.t b/t/op/stash.t
index c9634a370a..6c3940da99 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -29,7 +29,7 @@ SKIP: {
  skip_if_miniperl('requires XS');
   fresh_perl_like(
     'sub foo::bar{}; $mro::{get_mro}=*foo::bar; undef %foo::; require mro',
-     qr/^Subroutine mro::get_mro redefined at /,
+     qr/^Subroutine mro::get_mro redefined/,
     { switches => [ '-w' ] },
     q(Defining an XSUB over an existing sub with no stash under warnings),
   );
diff --git a/t/run/fresh_perl.t b/t/run/fresh_perl.t
index 411ff04b9c..53b99bf005 100644
--- a/t/run/fresh_perl.t
+++ b/t/run/fresh_perl.t
@@ -52,7 +52,13 @@ foreach my $prog (@prgs) {
 
     $expected =~ s/\n+$//;
 
-    fresh_perl_is($prog, $expected, { switches => [$switch || ''] }, $name);
+    # expand temp filename to a regex
+    if ($expected =~ m/^(.*)tmpXXXXXX(.*)$/s) {
+        $expected = qr/\Q$1\Etmp\w+\Q$2\E/;
+        fresh_perl_like($prog, $expected, { switches => [$switch || ''] }, $name);
+    } else {
+        fresh_perl_is($prog, $expected, { switches => [$switch || ''] }, $name);
+    }
 }
 
 __END__
@@ -336,7 +342,7 @@ foo;
 foo;
 EXPECT
 In foo1
-Subroutine foo redefined at (eval 1) line 1.
+Subroutine foo redefined, called by tmpXXXXXX:4 at (eval 1) line 1.
 Exiting foo1
 In foo2
 ########
-- 
2.14.1

@p5pRT
Copy link
Author

p5pRT commented Sep 12, 2017

From zefram@fysh.org

Nicolas R. wrote​:

When a function is redefined, rather than printing the location of the
redefined function, it would be better to also know what caused the
redefinition of the function and where.

Carp​::Always. There's no need for this to be done in core, and no reason
for it to be specific to function redefinition.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Sep 12, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Sep 13, 2017

From @atoomic

Thanks for your answer, I agree with you that we could extend this behavior to other warnings.

I was currently mainly focused on the "redefined sub" which is very annoying when you deal with a script using many packages... [ and is compiled ].

I think this we can use an iterative approach by improving similar warnings as we noticed them over time? Feel free to submit extra patches on top of this merge request.

That does not sound like a reasonable argument to me, why requiring more than 1Mo of memory when you can have it for free in core?

Does not it seem like legitimate by default to know where a code redefined a function?

As you can notice Carp​::Always comes with its own cost and is not suitable for every scripts.
perl -e 'print qx{grep RSS /proc/$$/status}'
VmRSS​: 1856 kB
perl -MCarp​::Always -e 'print qx{grep RSS /proc/$$/status}'
VmRSS​: 3068 kB

thanks
nicolas

On Tue, 12 Sep 2017 09​:40​:57 -0700, zefram@​fysh.org wrote​:

Nicolas R. wrote​:

When a function is redefined, rather than printing the location of the
redefined function, it would be better to also know what caused the
redefinition of the function and where.

Carp​::Always. There's no need for this to be done in core, and no reason
for it to be specific to function redefinition.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Sep 13, 2017

From zefram@fysh.org

Atoomic via RT wrote​:

I think this we can use an iterative approach by improving similar
warnings as we noticed them over time?

No, we should just take advantage of the genericity of the warning
mechanism, by using the existing hook mechanism to make whatever changes
we want to all warnings at once. This is what Carp​::Always does.

That does not sound like a reasonable argument to me, why requiring
more than 1Mo of memory when you can have it for free in core?

Adding such a thing to the core is not free (in maintenance). Using
Carp​::Always does have a memory cost, but most of that megabyte is Carp,
which most programs will be loading anyway. But even including Carp,
a megabyte is pretty cheap, especially for something that's only needed
on a debugging run.

Does not it seem like legitimate by default to know where a code
redefined a function?

It's legitimate to be able to extract that information, which we can,
as Carp​::Always does. This is not at all specific to the function
redefinition warning; the same desire for contextual information is
applicable to every kind of warning.

As you can notice Carp​::Always comes with its own cost and is not
suitable for every scripts.

What is it not suitable for?

This ticket should be closed as rejected.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2017

From @xsawyerx

On 09/13/2017 06​:36 PM, Zefram wrote​:

Atoomic via RT wrote​:

I think this we can use an iterative approach by improving similar
warnings as we noticed them over time?
No, we should just take advantage of the genericity of the warning
mechanism, by using the existing hook mechanism to make whatever changes
we want to all warnings at once. This is what Carp​::Always does.

That does not sound like a reasonable argument to me, why requiring
more than 1Mo of memory when you can have it for free in core?
Adding such a thing to the core is not free (in maintenance). Using
Carp​::Always does have a memory cost, but most of that megabyte is Carp,
which most programs will be loading anyway. But even including Carp,
a megabyte is pretty cheap, especially for something that's only needed
on a debugging run.

Does not it seem like legitimate by default to know where a code
redefined a function?
It's legitimate to be able to extract that information, which we can,
as Carp​::Always does. This is not at all specific to the function
redefinition warning; the same desire for contextual information is
applicable to every kind of warning.

As you can notice Carp​::Always comes with its own cost and is not
suitable for every scripts.
What is it not suitable for?

This ticket should be closed as rejected.

While I concur with the "easier to use Carp​::Always or Devel​::Confess"
and keeping the ability in, but not the use of it, I wish we wouldn't
close this ticket just yet. I would be happy to hear other opinions
about it. I think this might be such a useful feature that maybe we
should consider elevating it into core (though not as featureful as
Devel​::Confess, for example). What is the maintenance cost of it?

@p5pRT
Copy link
Author

p5pRT commented Sep 19, 2017

From @toddr

On Sun, 17 Sep 2017 11​:37​:46 -0700, xsawyerx@​gmail.com wrote​:

On 09/13/2017 06​:36 PM, Zefram wrote​:

Atoomic via RT wrote​:

I think this we can use an iterative approach by improving similar
warnings as we noticed them over time?
No, we should just take advantage of the genericity of the warning
mechanism, by using the existing hook mechanism to make whatever changes
we want to all warnings at once. This is what Carp​::Always does.

That does not sound like a reasonable argument to me, why requiring
more than 1Mo of memory when you can have it for free in core?
Adding such a thing to the core is not free (in maintenance). Using
Carp​::Always does have a memory cost, but most of that megabyte is Carp,
which most programs will be loading anyway. But even including Carp,
a megabyte is pretty cheap, especially for something that's only needed
on a debugging run.

Does not it seem like legitimate by default to know where a code
redefined a function?
It's legitimate to be able to extract that information, which we can,
as Carp​::Always does. This is not at all specific to the function
redefinition warning; the same desire for contextual information is
applicable to every kind of warning.

As you can notice Carp​::Always comes with its own cost and is not
suitable for every scripts.
What is it not suitable for?

This ticket should be closed as rejected.

While I concur with the "easier to use Carp​::Always or Devel​::Confess"
and keeping the ability in, but not the use of it, I wish we wouldn't
close this ticket just yet. I would be happy to hear other opinions
about it. I think this might be such a useful feature that maybe we
should consider elevating it into core (though not as featureful as
Devel​::Confess, for example). What is the maintenance cost of it?

For me this falls in the "Can't we have nice things?" category. Perl has improved warnings over the years and I applaud the efforts. To my mind, the same should apply here. Just cause CPAN did it, doesn't mean Perl 5 can't steal the idea. Right?

If we want to expand the patch to include all the other warnings that need this sort of information, I think atoomic and I would be up for the challenge. If you guys are cool with merging this and asking for more, we could also take that approach.

Todd

@p5pRT
Copy link
Author

p5pRT commented Sep 19, 2017

From zefram@fysh.org

Todd Rinaldo via RT wrote​:

If we want to expand the patch to include all the other warnings that
need this sort of information,

Wouldn't that be all of the warnings? (Either all or none; "need" is a
strong word.) There are something like 150 locations in the core that
issue a warning. And why just warnings? Much the same argument for
usefulness of this information also applies to exceptions. There are
something like 600 locations that croak.

This is absolutely not something to do to specific warning/exception
messages. The only sensible way to core any version of this is to make
it part of the warning/exception infrastructure, alongside the logic for
"at foo.pl line 123, <STDIN> line 456".

But then you have to decide whether this information is always added or
controlled by a switch. If it's always added, you're adding a lot of
verbosity that's rarely needed. If a switch, then that's yet another
API to support. Given that "use Carp​::Always" already functions as
a switched version of this, that expense of coring seems to be buying
exactly no value.

If the objective of coring is more like "batteries included in the core
distro", then the way to go is to bundle Carp​::Always with the core,
not to reimplement it in the core proper. But this seems like it would
be a gratuitous bundling. This is a dev tool, not especially closely
tied to the core, and not required for CPAN bootstrapping.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2017

From @xsawyerx

In essence, I think the issues Zefram raises here would need to be
addressed (or solutions suggested) before we just go for it.
(More inlined.)

On 09/19/2017 05​:51 PM, Zefram wrote​:

Todd Rinaldo via RT wrote​:

If we want to expand the patch to include all the other warnings that
need this sort of information,
Wouldn't that be all of the warnings? (Either all or none; "need" is a
strong word.) There are something like 150 locations in the core that
issue a warning. And why just warnings? Much the same argument for
usefulness of this information also applies to exceptions. There are
something like 600 locations that croak.

This does not seem to me like a scalable solution. The work on
correcting them is too much, and every new warning would require it.

This is absolutely not something to do to specific warning/exception
messages. The only sensible way to core any version of this is to make
it part of the warning/exception infrastructure, alongside the logic for
"at foo.pl line 123, <STDIN> line 456".

This is the faster to implement and more sustainable solution moving
forward.

But then you have to decide whether this information is always added or
controlled by a switch. If it's always added, you're adding a lot of
verbosity that's rarely needed. If a switch, then that's yet another
API to support. Given that "use Carp​::Always" already functions as
a switched version of this, that expense of coring seems to be buying
exactly no value.

Also, whether this is triggered for everything or optionally. The last
time we changed a warning, we broke CPAN. :)

If the objective of coring is more like "batteries included in the core
distro", then the way to go is to bundle Carp​::Always with the core,
not to reimplement it in the core proper. But this seems like it would
be a gratuitous bundling. This is a dev tool, not especially closely
tied to the core, and not required for CPAN bootstrapping.

Stacktraces are not cheap. Having such a functionality built-in (not
coring Carp​::Always) makes sense. Perhaps we should think of it in the
greater scope of providing levels of Carp​::Always (none, some - as this
small change achieves, and all).

@p5pRT
Copy link
Author

p5pRT commented Nov 8, 2017

From @atoomic

after discussion, we are rejecting this idea

On Sat, 23 Sep 2017 03​:25​:46 -0700, xsawyerx@​gmail.com wrote​:

In essence, I think the issues Zefram raises here would need to be
addressed (or solutions suggested) before we just go for it.
(More inlined.)

On 09/19/2017 05​:51 PM, Zefram wrote​:

Todd Rinaldo via RT wrote​:

If we want to expand the patch to include all the other warnings that
need this sort of information,
Wouldn't that be all of the warnings? (Either all or none; "need" is a
strong word.) There are something like 150 locations in the core that
issue a warning. And why just warnings? Much the same argument for
usefulness of this information also applies to exceptions. There are
something like 600 locations that croak.

This does not seem to me like a scalable solution. The work on
correcting them is too much, and every new warning would require it.

This is absolutely not something to do to specific warning/exception
messages. The only sensible way to core any version of this is to make
it part of the warning/exception infrastructure, alongside the logic for
"at foo.pl line 123, <STDIN> line 456".

This is the faster to implement and more sustainable solution moving
forward.

But then you have to decide whether this information is always added or
controlled by a switch. If it's always added, you're adding a lot of
verbosity that's rarely needed. If a switch, then that's yet another
API to support. Given that "use Carp​::Always" already functions as
a switched version of this, that expense of coring seems to be buying
exactly no value.

Also, whether this is triggered for everything or optionally. The last
time we changed a warning, we broke CPAN. :)

If the objective of coring is more like "batteries included in the core
distro", then the way to go is to bundle Carp​::Always with the core,
not to reimplement it in the core proper. But this seems like it would
be a gratuitous bundling. This is a dev tool, not especially closely
tied to the core, and not required for CPAN bootstrapping.

Stacktraces are not cheap. Having such a functionality built-in (not
coring Carp​::Always) makes sense. Perhaps we should think of it in the
greater scope of providing levels of Carp​::Always (none, some - as this
small change achieves, and all).

@p5pRT
Copy link
Author

p5pRT commented Nov 8, 2017

@atoomic - Status changed from 'open' to 'rejected'

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

1 participant