Closed p5pRT closed 17 years ago
List context split with ?? pattern delimiters is documented as setting @_ This doesn't seem to occur.
And for a real weirdy\, a void context split is supposed to give the "Use of implicit split to @_ is deprecated" warning. This doesn't happen if the split is in an eval which is in void context. If either the split or the eval is in scalar context\, the warning is correctly given.
[D:\home\sthoenna]perl #!perl -wl use vars '$x';
@_ = (); print(split ?:?\, '1:2:3'); print "list context split ?? did not clobber \@_" unless @_;
open STDERR\, ">splitwarn" or die; # $x= # uncomment to see correct warning w/ eval in scalar context eval "split //\, '1:2:3'; 1"; print $@ if $@; open STDERR\, ">&1" or die; print "void context split in void context eval did not warn" if -z 'splitwarn'; print "correctly warned: "\, `cat splitwarn` unless -z _; __END__ 123 list context split ?? did not clobber @_ void context split in void context eval did not warn
List context split with ?? pattern delimiters is documented as setting @_ This doesn't seem to occur.
And for a real weirdy\, a void context split is supposed to give the "Use of implicit split to @_ is deprecated" warning. This doesn't happen if the split is in an eval which is in void context. If either the split or the eval is in scalar context\, the warning is correctly given.
[D:\home\sthoenna]perl #!perl -wl use vars '$x';
@_ = (); print(split ?:?\, '1:2:3'); print "list context split ?? did not clobber \@_" unless @_;
open STDERR\, ">splitwarn" or die; # $x= # uncomment to see correct warning w/ eval in scalar context eval "split //\, '1:2:3'; 1"; print $@ if $@; open STDERR\, ">&1" or die; print "void context split in void context eval did not warn" if -z 'splitwarn'; print "correctly warned: "\, `cat splitwarn` unless -z _; __END__ 123 list context split ?? did not clobber @_ void context split in void context eval did not warn
sthoenna@efn.org (Yitzchak Scott-Thoennes) wrote
List context split with ?? pattern delimiters is documented as setting @_ This doesn't seem to occur.
Well\, it works in Perl4. :-)
But since it seems never to have worked in any version of Perl 5\, a documentation patch seems in order. (Patch applies to a version somewhere near the bleeding edge.)
Mike Guy
On Tue\, May 30\, 2000 at 03:21:14PM +0100\, M.J.T. Guy wrote:
--- ./pod/perlfunc.pod.orig Sun May 7 06:26:55 2000 +++ ./pod/perlfunc.pod Tue May 30 15:02:58 2000 @@ -4304\,11 +4304\,9 @@ Splits a string into a list of strings and returns that list. By default\, empty leading fields are preserved\, and empty trailing ones are deleted.
-If not in list context\, returns the number of fields found and splits into -the C\<@_> array. (In list context\, you can force the split into C\<@_> by -using C\<??> as the pattern delimiters\, but it still returns the list -value.) The use of implicit split to C\<@_> is deprecated\, however\, because -it clobbers your subroutine arguments. +In scalar context\, returns the number of fields found and splits into +the C\<@_> array. Use of split in scalar context is deprecated\, however\, +because it clobbers your subroutine arguments.
The implicit split to @_ is deprecated\, but using split in scalar context is not. Even without the implicit split to @_\, I could still call split in a scalar context to get a count of the fields. (In fact\, I recall a complaint from a programmer who was doing just that\, and was annoyed by "implicit split to @_ is deprecated" warning.)
That sentence in the documentation should not be changed.
Ronald
Ronald J Kimball \rjk@​linguist\.dartmouth\.edu wrote
The implicit split to @_ is deprecated\, but using split in scalar context is not. Even without the implicit split to @_\, I could still call split in a scalar context to get a count of the fields. (In fact\, I recall a complaint from a programmer who was doing just that\, and was annoyed by "implicit split to @_ is deprecated" warning.)
Well\, you get the "deprecated" warning on any split in scalar context\, whatever your intentions about @_. I've always regarded "implicit split to @_" and "use of split in scalar context" as different ways of saying the same thing.
Mike Guy
On Tue\, May 30\, 2000 at 03:40:16PM +0100\, M.J.T. Guy wrote:
Ronald J Kimball \rjk@​linguist\.dartmouth\.edu wrote
The implicit split to @_ is deprecated\, but using split in scalar context is not. Even without the implicit split to @_\, I could still call split in a scalar context to get a count of the fields. (In fact\, I recall a complaint from a programmer who was doing just that\, and was annoyed by "implicit split to @_ is deprecated" warning.)
Well\, you get the "deprecated" warning on any split in scalar context\, whatever your intentions about @_. I've always regarded "implicit split to @_" and "use of split in scalar context" as different ways of saying the same thing.
So\, the question is\, when the implicit split to @_ is removed from the language\, which of the following will result?
a) Using split in scalar context will be a syntax error.
b) Using split in scalar context will return the number of fields\, but will not split to @_.
M.J.T was expecting the former\, I was expecting the latter. Is there a plan for which one is the intended behavior?
Ronald
Ronald J Kimball \rjk@​linguist\.dartmouth\.edu wrote
a) Using split in scalar context will be a syntax error.
b) Using split in scalar context will return the number of fields\, but will not split to @_.
M.J.T was expecting the former\, I was expecting the latter. Is there a plan for which one is the intended behavior?
Actually\, I would expect and hope (b). But I was really expecting (c)\, namely that nothing's going to happen any time soon ...
Mike Guy
M.J.T. Guy writes:
Ronald J Kimball \rjk@​linguist\.dartmouth\.edu wrote
a) Using split in scalar context will be a syntax error.
b) Using split in scalar context will return the number of fields\, but will not split to @_.
M.J.T was expecting the former\, I was expecting the latter. Is there a plan for which one is the intended behavior?
Actually\, I would expect and hope (b). But I was really expecting (c)\, namely that nothing's going to happen any time soon ...
Very reasonable given the attension my patch for making it usable got.
Ilya
eval { my $foo = new Foo; die "oops"; };
where Foo is SelfLoaded doesn't do what is expected:
[nick@Bagpuss nick]$ cat test/selfbug.pl eval { my $foo = new Foo; die "oops"; };
print "'$@'\n";
package Foo; use SelfLoader;
sub new { bless {}\, shift }
__DATA__ package main; [nick@Bagpuss nick]$ perl test/selfbug.pl ''
Problem is that SelfLoader::AUTOLOAD is eval{}ing twice when it tried to find Foo::DESTROY\, which is resetting $@ to an empty string. The attached patch saves $@ in the style of AutoLoader::AUTOLOAD to circumvent this problem.
*** lib/SelfLoader.pm.orig Sat Mar 4 04:26:55 2000
--- lib/SelfLoader.pm Fri May 26 16:35:14 2000
***************
*** 3\,9 ****
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(AUTOLOAD);
! $VERSION = "1.0901";
sub Version {$VERSION}
$DEBUG = 0;
--- 3\,9 ----
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(AUTOLOAD);
! $VERSION = "1.0902";
sub Version {$VERSION}
$DEBUG = 0;
***************
*** 20\,25 ****
--- 20\,26 ----
AUTOLOAD {
print STDERR "SelfLoader::AUTOLOAD for $AUTOLOAD\n" if $DEBUG;
my $SL_code = $Cache{$AUTOLOAD};
+ my $save = $@; # evals in both AUTOLOAD and _load_stubs can corrupt $@
unless ($SL_code) {
# Maybe this pack had stubs before __DATA__\, and never initialized.
# Or\, this maybe an automatic DESTROY method call when none exists.
***************
*** 31\,41 ****
--- 32\,44 ----
croak "Undefined subroutine $AUTOLOAD" unless $SL_code;
}
print STDERR "SelfLoader::AUTOLOAD eval: $SL_code\n" if $DEBUG;
+
eval $SL_code;
if ($@) {
$@ =~ s/ at .*\n//;
croak $@;
}
+ $@ = $save;
defined(&$AUTOLOAD) || die "SelfLoader inconsistency error";
delete $Cache{$AUTOLOAD};
goto &$AUTOLOAD
I've taken the lib/autoloader.t regression test and made a selfloader regression test which will pick up the above bug in the current version. It also checks SelfLoading and package inheritance\, and correct behaviour with the __END__ token and \ handles.
I hope this is of use\,
Nicholas Clark
*** /dev/null Tue Jan 1 04:00:00 1980 --- t/lib/selfloader.t Fri May 26 17:07:53 2000 *************** *** 0 **** --- 1\,198 ---- + #!./perl + + BEGIN { + chdir 't' if -d 't'; + $dir = "self-$$"; + unshift @INC\, ("./$dir"\, "../lib"); + + print "1..19\n"; + + # First we must set up some selfloader files + mkdir $dir\, 0755 or die "Can't mkdir $dir: $!"; + + open(FOO\, ">$dir/Foo.pm") or die; + print FOO \<\<'EOT'; + package Foo; + use SelfLoader; + + sub new { bless {}\, shift } + sub foo; + sub bar; + sub bazmarkhianish; + sub a; + sub never; # declared but definition should never be read + 1; + __DATA__ + + sub foo { shift; shift || "foo" }; + + sub bar { shift; shift || "bar" } + + sub bazmarkhianish { shift; shift || "baz" } + + package sheep; + sub bleat { shift; shift || "baa" } + + __END__ + sub never { die "D'oh" } + EOT + + close(FOO); + + open(BAR\, ">$dir/Bar.pm") or die; + print BAR \<\<'EOT'; + package Bar; + use SelfLoader; + + @ISA = 'Baz'; + + sub new { bless {}\, shift } + sub a; + + 1; + __DATA__ + + sub a { 'a Bar'; } + sub b { 'b Bar' } + + __END__ DATA + sub never { die "D'oh" } + EOT + + close(BAR); + }; + + + package Baz; + + sub a { 'a Baz' } + sub b { 'b Baz' } + sub c { 'c Baz' } + + + package main; + use Foo; + use Bar; + + $foo = new Foo; + + print "not " unless $foo->foo eq 'foo'; # selfloaded first time + print "ok 1\n"; + + print "not " unless $foo->foo eq 'foo'; # regular call + print "ok 2\n"; + + # Try an undefined method + eval { + $foo->will_fail; + }; + if ($@ =~ /^Undefined subroutine/) { + print "ok 3\n"; + } else { + print "not ok 3 $@\n"; + } + + # Used to be trouble with this + eval { + my $foo = new Foo; + die "oops"; + }; + if ($@ =~ /oops/) { + print "ok 4\n"; + } else { + print "not ok 4 $@\n"; + } + + # Pass regular expression variable to autoloaded function. This used + # to go wrong in AutoLoader because it used regular expressions to generate + # autoloaded filename. + "foo" =~ /(\w+)/; + print "not " unless $1 eq 'foo'; + print "ok 5\n"; + + print "not " unless $foo->bar($1) eq 'foo'; + print "ok 6\n"; + + print "not " unless $foo->bar($1) eq 'foo'; + print "ok 7\n"; + + print "not " unless $foo->bazmarkhianish($1) eq 'foo'; + print "ok 8\n"; + + print "not " unless $foo->bazmarkhianish($1) eq 'foo'; + print "ok 9\n"; + + # Check nested packages inside __DATA__ + print "not " unless sheep::bleat() eq 'baa'; + print "ok 10\n"; + + # Now check inheritance: + + $bar = new Bar; + + # Before anything is SelfLoaded there is no declaration of Foo::b so we should + # get Baz::b + print "not " unless $bar->b() eq 'b Baz'; + print "ok 11\n"; + + # There is no Bar::c so we should get Baz::c + print "not " unless $bar->c() eq 'c Baz'; + print "ok 12\n"; + + # This selfloads Bar::a because it is stubbed. It also stubs Bar::b as a side + # effect + print "not " unless $bar->a() eq 'a Bar'; + print "ok 13\n"; + + print "not " unless $bar->b() eq 'b Bar'; + print "ok 14\n"; + + print "not " unless $bar->c() eq 'c Baz'; + print "ok 15\n"; + + + + # Check that __END__ is honoured + # Try an subroutine that should never be noticed by selfloader + eval { + $foo->never; + }; + if ($@ =~ /^Undefined subroutine/) { + print "ok 16\n"; + } else { + print "not ok 16 $@\n"; + } + + # Try to read from the data file handle + my $foodata = \<Foo::DATA>; + if (defined $foodata) { + print "not ok 17 # $foodata\n"; + } else { + print "ok 17\n"; + } + + # Check that __END__ DATA is honoured + # Try an subroutine that should never be noticed by selfloader + eval { + $bar->never; + }; + if ($@ =~ /^Undefined subroutine/) { + print "ok 18\n"; + } else { + print "not ok 18 $@\n"; + } + + # Try to read from the data file handle + my $bardata = \<Bar::DATA>; + if ($bardata ne "sub never { die \"D'oh\" }\n") { + print "not ok 19 # $bardata\n"; + } else { + print "ok 19\n"; + } + + # cleanup + END { + return unless $dir && -d $dir; + unlink "$dir/Foo.pm"\, "$dir/Bar.pm"; + rmdir "$dir"; + }
List context split with ?? pattern delimiters is documented as setting @_ This doesn't seem to occur.
And for a real weirdy\, a void context split is supposed to give the "Use of implicit split to @_ is deprecated" warning. This doesn't happen if the split is in an eval which is in void context. If either the split or the eval is in scalar context\, the warning is correctly given.
[D:\home\sthoenna]perl #!perl -wl use vars '$x';
@_ = (); print(split ?:?\, '1:2:3'); print "list context split ?? did not clobber \@_" unless @_;
open STDERR\, ">splitwarn" or die; # $x= # uncomment to see correct warning w/ eval in scalar context eval "split //\, '1:2:3'; 1"; print $@ if $@; open STDERR\, ">&1" or die; print "void context split in void context eval did not warn" if -z 'splitwarn'; print "correctly warned: "\, `cat splitwarn` unless -z _; __END__ 123 list context split ?? did not clobber @_ void context split in void context eval did not warn
On Tue May 30 00:21:19 2000\, RT_System wrote:
sthoenna \<!-- x --> at efn.org (Yitzchak Scott-Thoennes) wrote
List context split with ?? pattern delimiters is documented as setting @_ This doesn't seem to occur.
Well\, it works in Perl4. :-)
But since it seems never to have worked in any version of Perl 5\, a documentation patch seems in order. (Patch applies to a version somewhere near the bleeding edge.)
Mike Guy
--- ./pod/perlfunc.pod.orig Sun May 7 06:26:55 2000 +++ ./pod/perlfunc.pod Tue May 30 15:02:58 2000 @@ -4304\,11 +4304\,9 @@ Splits a string into a list of strings and returns that list. By default\, empty leading fields are preserved\, and empty trailing ones are deleted.
-If not in list context\, returns the number of fields found and splits into -the C\<@_> array. (In list context\, you can force the split into C\<@_> by -using C\<??> as the pattern delimiters\, but it still returns the list -value.) The use of implicit split to C\<@_> is deprecated\, however\, because -it clobbers your subroutine arguments. +In scalar context\, returns the number of fields found and splits into +the C\<@_> array. Use of split in scalar context is deprecated\, however\, +because it clobbers your subroutine arguments.
If EXPR is omitted\, splits the C\<$_> string. If PATTERN is also omitted\, splits on whitespace (after skipping any leading whitespace). Anything --- ./pod/perltrap.pod.orig Tue May 2 07:50:46 2000 +++ ./pod/perltrap.pod Tue May 30 15:07:56 2000 @@ -586\,6 +586\,12 @@
=item * Discontinuance
+In Perl 4\, if in list context the delimiters to the first argument of +C\<split()> were C\<??>\, the result would be placed in C\<@_> as well as +being returned. Perl 5 has more respect for your subroutine arguments. + +=item * Discontinuance + Some bugs may have been inadvertently removed. :-)
=back
End of patch
This patch was applied as change #6185.
The original problem does now seem to be resolved\, as Perl is now warning about the implicit split to @_;
[steve@kirk rt_testing]$ perl rt_3285.pl 123 list context split ?? did not clobber @_ correctly warned: Use of implicit split to @_ is deprecated at (eval 1) line 1.
@smpeters - Status changed from 'open' to 'resolved'
Migrated from rt.perl.org#3285 (status was 'resolved')
Searchable as RT3285$