You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this ticket I raise the question of which of two (or perhaps more) approaches we should take to modifying unit tests in the Perl core distribution test suite as we try to upgrade it to run with "strict-by-default".
Let's start by looking at a simple data file and a simple Perl 5 program.
$ cat file-to-be-tied
alpha
beta
gamma
$ cat tie.pl
#!/usr/bin/env perl
use Tie::File;
$filename = './file-to-be-tied';
tie @array, Tie::File, $filename or die "Unable to tie to $filename";
print "$_\n" for @array;
untie @array;
print "Finished\n";
We run the program as is with Perl 5.
$ perl tie.pl
alpha
beta
gamma
Finished
But now we notice that we failed to include a use strict; statement. Let's modify the file to do only that.
$ cat tie-strict.pl
#!/usr/bin/env perl
use strict;
use Tie::File;
$filename = './file-to-be-tied';
tie @array, Tie::File, $filename or die "Unable to tie to $filename";
print "$_\n" for @array;
untie @array;
print "Finished\n";
Now, if I asked you to identify the changes that would be needed in this file to bring it into compliance with strict, the first thing that you would be likely to say is: "Change the global variables to 'my' variables."
Okay, let's do that.
$ cat $ cat tie-first-attempt-at-correction.pl
#!/usr/bin/env perl
use strict;
use Tie::File;
my($filename, @array);
$filename = './file-to-be-tied';
tie @array, Tie::File, $filename or die "Unable to tie to $filename";
print "$_\n" for @array;
untie @array;
print "Finished\n";
Let's try to compile that and see what happens.
$ perl -c tie-first-attempt-at-correction.pl
Bareword "Tie::File" not allowed while "strict subs" in use at tie-first-attempt-at-correction.pl line 8.
tie-first-attempt-at-correction.pl had compilation errors.
So scoping the variables was necessary but not sufficient to achieve strict-compliance. Let's try the following.
$ cat tie-second-attempt-at-correction.pl
#!/usr/bin/env perl
use strict;
use Tie::File;
my($filename, @array);
$filename = './file-to-be-tied';
{
no strict 'subs';
tie @array, Tie::File, $filename or die "Unable to tie to $filename";
}
print "$_\n" for @array;
untie @array;
print "Finished\n";
That's cool, but we could have taken a different approach to fixing the 'Bareword ... not allowed while "strict subs" in use' problem. We could have done this.
$ cat tie-third-attempt-at-correction.pl
#!/usr/bin/env perl
use strict;
use Tie::File;
my($filename, @array);
$filename = './file-to-be-tied';
tie @array, 'Tie::File', $filename or die "Unable to tie to $filename";
print "$_\n" for @array;
untie @array;
print "Finished\n";
In the above, rather than placing the offending statement -- unaltered -- in a block and relaxing strict 'subs' for the duration of that block, we alter the offending statement by quoting the bareword.
So, even within Perl 5, there are different ways to bring code into compliance with strictures.
By now you can guess where I'm going with this. In upgrading the core distribution test suite to run with strict compliance as per Objective 1, we have choices as to how to accomplish that.
Consider this Perl 7 program.
$ cat tie.p7.pl
#!/usr/bin/env perl
use Tie::File;
$filename = './file-to-be-tied';
tie @array, Tie::File, $filename or die "Unable to tie to $filename";
print "$_\n" for @array;
untie @array;
print "Finished\n";
This is, of course, exactly the same program as the first one in this ticket, tie.pl. But if we run it against a Perl 7 executable, we get:
$ p7 tie.p7.pl
Global symbol "$filename" requires explicit package name (did you forget to declare "my $filename"?) at tie.p7.pl line 5.
Global symbol "@array" requires explicit package name (did you forget to declare "my @array"?) at tie.p7.pl line 6.
Global symbol "$filename" requires explicit package name (did you forget to declare "my $filename"?) at tie.p7.pl line 6.
Global symbol "$filename" requires explicit package name (did you forget to declare "my $filename"?) at tie.p7.pl line 6.
Global symbol "@array" requires explicit package name (did you forget to declare "my @array"?) at tie.p7.pl line 8.
Global symbol "@array" requires explicit package name (did you forget to declare "my @array"?) at tie.p7.pl line 10.
Bareword "Tie::File" not allowed while "strict subs" in use at tie.p7.pl line 6.
Execution of tie.p7.pl aborted due to compilation errors.
Which, of course, is the same error output we would have gotten by running perl -Mstrict tie.pl.
And, just as in Perl 5, we have two different ways of fixing the problem.
First:
$ cat tie.no-strict-subs.p7.pl
#!/usr/bin/env perl
use Tie::File;
my($filename, @array);
$filename = './file-to-be-tied';
{
no strict 'subs';
tie @array, Tie::File, $filename or die "Unable to tie to $filename";
}
print "$_\n" for @array;
untie @array;
print "Finished\n";
$ perl tie.no-strict-subs.p7.pl
alpha
beta
gamma
Finished
Second:
$ cat tie.quote-bareword.p7.pl
#!/usr/bin/env perl
use Tie::File;
my($filename, @array);
$filename = './file-to-be-tied';
tie @array, 'Tie::File', $filename or die "Unable to tie to $filename";
print "$_\n" for @array;
untie @array;
print "Finished\n";
$ perl tie.quote-bareword.p7.pl
alpha
beta
gamma
Finished
For the past five weeks of work on the test suite, I have usually taken the first approach to correction, i.e., I have been placing the offending statement unaltered into a code block and starting that code block off with no strict 'subs';. I did so for two reasons: (1) because that's what the error message prompts me to do; and (2) because I figured I'd get less pushback from the developer who originally wrote the code way back when in a no strict environment.
But now I'm thinking that the Perl 7 test suite code would be cleaner and easier for a newcomer to understand if I corrected that source code that gave rise to the "bareword" exception in the first place, rather than saying (in effect), "Let's revert to 1994 defaults for just this block."
In working on the test suite, we'll face this dilemma repeatedly. For example, when we get to Objective 3: Warnings by Default, we'll be faced with this situation repeatedly. For example, when getting an "uninitialized value" warning, do we resolve the problem by (1) placing the offending statement unaltered into a block and then opening that block with no warnings 'uninitialized';; or by (2) initializing the variable that was cited in the warning.
So, my immediate question for you is, in addressing 'bareword' exceptions now in Objective 1 (and assuming both approaches are feasible), should we prefer suspending strict 'subs' for a block or putting clothing on the bareword.
@atoomic, @toddr, @xsawyerx: I'd appreciate your feedback at your earliest opportunity, as we need to provide guidance for new recruits who may start looking at the code base as early as tomorrow (Aug 12).
Thank you very much.
Jim Keenan
The text was updated successfully, but these errors were encountered:
In this ticket I raise the question of which of two (or perhaps more) approaches we should take to modifying unit tests in the Perl core distribution test suite as we try to upgrade it to run with "strict-by-default".
Let's start by looking at a simple data file and a simple Perl 5 program.
We run the program as is with Perl 5.
But now we notice that we failed to include a
use strict;
statement. Let's modify the file to do only that.Now, if I asked you to identify the changes that would be needed in this file to bring it into compliance with
strict
, the first thing that you would be likely to say is: "Change the global variables to 'my' variables."Okay, let's do that.
Let's try to compile that and see what happens.
So scoping the variables was necessary but not sufficient to achieve
strict
-compliance. Let's try the following.Let's try to run this.
The program and compiles and runs as intended.
That's cool, but we could have taken a different approach to fixing the 'Bareword ... not allowed while "strict subs" in use' problem. We could have done this.
In the above, rather than placing the offending statement -- unaltered -- in a block and relaxing
strict 'subs'
for the duration of that block, we alter the offending statement by quoting the bareword.Let's run this.
The program compiles and runs as intended.
So, even within Perl 5, there are different ways to bring code into compliance with strictures.
By now you can guess where I'm going with this. In upgrading the core distribution test suite to run with strict compliance as per Objective 1, we have choices as to how to accomplish that.
Consider this Perl 7 program.
This is, of course, exactly the same program as the first one in this ticket,
tie.pl
. But if we run it against a Perl 7 executable, we get:Which, of course, is the same error output we would have gotten by running
perl -Mstrict tie.pl
.And, just as in Perl 5, we have two different ways of fixing the problem.
First:
Second:
For the past five weeks of work on the test suite, I have usually taken the first approach to correction, i.e., I have been placing the offending statement unaltered into a code block and starting that code block off with
no strict 'subs';
. I did so for two reasons: (1) because that's what the error message prompts me to do; and (2) because I figured I'd get less pushback from the developer who originally wrote the code way back when in ano strict
environment.But now I'm thinking that the Perl 7 test suite code would be cleaner and easier for a newcomer to understand if I corrected that source code that gave rise to the "bareword" exception in the first place, rather than saying (in effect), "Let's revert to 1994 defaults for just this block."
In working on the test suite, we'll face this dilemma repeatedly. For example, when we get to Objective 3: Warnings by Default, we'll be faced with this situation repeatedly. For example, when getting an "uninitialized value" warning, do we resolve the problem by (1) placing the offending statement unaltered into a block and then opening that block with
no warnings 'uninitialized';
; or by (2) initializing the variable that was cited in the warning.So, my immediate question for you is, in addressing 'bareword' exceptions now in Objective 1 (and assuming both approaches are feasible), should we prefer suspending
strict 'subs'
for a block or putting clothing on the bareword.@atoomic, @toddr, @xsawyerx: I'd appreciate your feedback at your earliest opportunity, as we need to provide guidance for new recruits who may start looking at the code base as early as tomorrow (Aug 12).
Thank you very much.
Jim Keenan
The text was updated successfully, but these errors were encountered: