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

Clarify that __clean_eval does not use strict or warnings. #35

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

toddr
Copy link

@toddr toddr commented Aug 18, 2020

MM's code to determine version does a local on $VERSION without having
first declared it. Instead it should do 'my' on it unless the variable
is defined at a distance.

my $VERSION = ...
# or
local $Foo::Bar::VERSION = ...

Doing this causes this code to pass strict where it did not previously
do so.

@atoomic
Copy link

atoomic commented Aug 18, 2020

this is incomplete needs an extra no strict vars

diff --git a/cpan/Module-Metadata/lib/Module/Metadata.pm b/cpan/Module-Metadata/lib/Module/Metadata.pm
index 0309d768ae..1013a7e0bc 100644
--- a/cpan/Module-Metadata/lib/Module/Metadata.pm
+++ b/cpan/Module-Metadata/lib/Module/Metadata.pm
@@ -691,6 +691,7 @@ sub _evaluate_version_line {
   my $eval = qq{ my \$dummy = q#  Hide from _packages_inside()
     #; package Module::Metadata::_version::p${pn};
     use version;
+    no strict 'vars';
     sub {
       local $sigil$variable_name;
       $line;

atoomic added a commit to atoomic/perl that referenced this pull request Aug 18, 2020
Copy link

@atoomic atoomic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when strict is enabled the test suite fails with this change when trying to parse something like this

package Simple;
  our $CVSVERSION   = '$Revision: 1.7 $';
  our ($VERSION)    = ($CVSVERSION =~ /(\d+\.\d+)/);
}

@karenetheridge
Copy link
Member

my $VERSION = .. makes no sense as $VERSION must be a package variable in global scope.

@toddr toddr force-pushed the local_version branch 2 times, most recently from 77e5af9 to 2afad13 Compare August 18, 2020 20:18
@toddr
Copy link
Author

toddr commented Aug 18, 2020

my $VERSION = .. makes no sense as $VERSION must be a package variable in global scope.

Agreed. Changed it to our.

@toddr toddr force-pushed the local_version branch 4 times, most recently from fbd275f to 693a8fd Compare August 18, 2020 21:25
@Grinnz
Copy link

Grinnz commented Aug 18, 2020

Sorry this doesn't make any sense. Can you give an example that is currently failing?

@Grinnz
Copy link

Grinnz commented Aug 18, 2020

Perhaps what it should be doing is local our $variablename; (if the variable is not namespaced).

@karenetheridge karenetheridge marked this pull request as draft August 18, 2020 22:00
@Grinnz
Copy link

Grinnz commented Aug 18, 2020

  • The variables this is dealing with are always package variables.
  • This is perfectly legal without strict 'vars' enabled since variables are then package variables by default. So if that line is added there should not be a need for any other changes.
  • This line is intending to localize the package variable, it must continue to do so in all cases.

corpus/BOMTest/UTF8.pm Outdated Show resolved Hide resolved
@toddr
Copy link
Author

toddr commented Aug 19, 2020

  • The variables this is dealing with are always package variables.
  • This is perfectly legal without strict 'vars' enabled since variables are then package variables by default. So if that line is added there should not be a need for any other changes.
  • This line is intending to localize the package variable, it must continue to do so in all cases.

Right but you can't localize a variable that hasn't yet been declared in the package. In this case, $VERSION was never declared.

perl -Mstrict -e'{ local $VERSION = 5; }' 
Global symbol "$VERSION" requires explicit package name (did you forget to declare "my $VERSION"?) at -e line 1.

So in the end, the issue was that __clean_eval explicitly had strict/warnings off. I think this is hiding some issues but not in scope for this PR.

@toddr toddr marked this pull request as ready for review August 19, 2020 20:21
@toddr toddr requested a review from Grinnz August 19, 2020 20:21
@toddr toddr changed the title Do not do local on a variable when it has not yet been declared. Clarify that __clean_eval does not use strict or warnings. Aug 19, 2020
@Leont
Copy link
Member

Leont commented Aug 19, 2020

this is incomplete needs an extra no strict vars

That's one of the tricky things here. Ideally it would eval that line in the same environment as it has in the source file, but it may not be easy to establish if it should be strict or not (or something in between). Not evaluating any of the other lines only complicates that further.

@toddr
Copy link
Author

toddr commented Aug 19, 2020

That's one of the tricky things here.

The change has been re-worked. This part is no longer a part of the merge.

@@ -10,7 +10,7 @@ package Module::Metadata;
# perl modules (assuming this may be expanded in the distant
# parrot future to look at other types of modules).

sub __clean_eval { eval $_[0] }
sub __clean_eval { no strict; no warnings; eval $_[0] }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mostly ok with this, but just would like to note that "no warnings" does not currently bring things to the "default" state, it in fact disables default warnings. However, I don't believe there is any reason for this module to care about default warnings here either.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific warning category that is being targeted here? If so, can't we just disable that one?

In other words, what forms of syntax are being tripped up by having warnings enabled?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is meant to guard against anything specific, but against the possibility of warnings being enabled in an outer scope.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was simply trying to explicitly do what I guessed the intentions were by declaring this sub prior to use warnings/strict.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And as far as I know there is no way to declare that a scope should use what is currently the default set of warnings, which is an unfortunate limitation of the warnings.pm api.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO the current change make the original intent clear.

The function __clean_eval as it stands (before this fix) is eval without warnings and strict hint set.
With this patch, it stays the same but would avoid someone to figure out what's happening and make the intent clear.

Yes this is hiding some issues that would have been exposed with strict and warnings, but I think this is a different case, no?

That code runs without warnings and strict being set.

sub alien { $x = "2:" + 3; return $x }

use strict;
use warnings;

print alien() . "\n";

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. I am pointing out that it is not in fact the same as without warnings and strict set. "no warnings" also disables default warnings.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. I am pointing out that it is not in fact the same as without warnings and strict set. "no warnings" also disables default warnings.

What do you suggest instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would note that this sub is only used in 2 places and the change that created it seemed to want to turn off all strict/warnings regardless. I didn't write it so I can only speculate on the intention.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I had a better suggestion I would not have approved it 😉

jkeenan pushed a commit to jkeenan/perl that referenced this pull request Sep 21, 2020
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

Successfully merging this pull request may close these issues.

5 participants