Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Perl-Critic CPAN distribution.

Report information
The Basics
Id: 38673
Status: resolved
Priority: 0/
Queue: Perl-Critic

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: NamingConventions::ProhibitMixedCaseVars denies $Foo
NamingConventions::ProhibitMixedCaseVars does not allow $Foo. This appears to be a bug. Patch attached.
Subject: mixedcase.patch
--- lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseVars.pm (revision 60174) +++ lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseVars.pm (local) @@ -54,6 +54,10 @@ #are defined in other packages. next if $elem->type() eq 'local' && $variable_name =~ m/$PACKAGE_RX/xms; + + # Allow $Foo + return 0 if $variable_name =~ m/^.[[:upper:]][[:lower:]]+$/; + return 1 if $variable_name =~ m/$MIXED_RX/xms; } return 0; --- t/NamingConventions/ProhibitMixedCaseVars.run (revision 60174) +++ t/NamingConventions/ProhibitMixedCaseVars.run (local) @@ -34,7 +34,7 @@ our (%FOO_BAR, @BAR_FOO); local ($FOO_BAR, %BAR_foo) = @_; my ($foo_bar, $foo); - +my $Foo; #-----------------------------------------------------------------------------
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 17:14:31 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Michael G Schwern via RT wrote: Show quoted text
> NamingConventions::ProhibitMixedCaseVars does not allow $Foo. This > appears to be a bug.
Why is this a bug? Mixed case means you can't have both upper and lower case in a variable name, which "Foo" definitely does.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 15:46:45 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > Michael G Schwern via RT wrote:
>> NamingConventions::ProhibitMixedCaseVars does not allow $Foo. This >> appears to be a bug.
> > Why is this a bug? Mixed case means you can't have both upper and lower case in a variable name, which "Foo" definitely does.
The intent of the policy is to prohibit $StudlyCaps style in favor of $Using_Underscores (Chapter 3.5 of PBP, "Underscores"). The $StudlyCaps vs $Using_Underscores decision only applies to how you separate words in names. $Foo is just one word and thus is not $StudlyCaps any more than $foo is. It suffers from none of the readability concerns of $StudlyCaps smashing words together. $Foo variables are never discussed in 3.5, never mentioned in the docs and never tested for. Strong evidence that it was simply overlooked. Controlling capitalization would be a different policy. Chapter 3.6 discusses how to use capitalization and uses rather different reasoning from 3.5. I don't agree with that policy's use of capitalization (IMHO distinguishing $local vs $Global is more important) and would like to be able to turn it off separate from prohibiting $StudlyCaps. NamingConventions::ProhibitMixedCaseSubs has the same bug. Here's a patch for that. --- lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseSubs.pm (revision 60181) +++ lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseSubs.pm (local) @@ -38,9 +38,12 @@ sub violates { my ( $self, $elem, undef ) = @_; (my $name = $elem->name() ) =~ s/\A.*:://mx; - if ( $name =~ m/$MIXED_RX/xms ) { - return $self->violation( $DESC, $EXPL, $elem ); - } + + # Allow Foo() + return if $name =~ m/^[[:upper:]][[:lower:]]+$/; + + return $self->violation( $DESC, $EXPL, $elem ) if $name =~ m/$MIXED_RX/xms; + return; #ok! } --- t/NamingConventions/ProhibitMixedCaseSubs.run (revision 60181) +++ t/NamingConventions/ProhibitMixedCaseSubs.run (local) @@ -18,6 +18,7 @@ sub FOO_bar {} sub Foo::Bar::grok {} sub Class::Encapsulate::_hidden::_hash_overload {} +sub Foo { return "foo" } #----------------------------------------------------------------------------- # Local Variables: -- package Outer::Space; use Test::More tests => 9;
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 18:17:50 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
Show quoted text
> $Foo variables are never discussed in 3.5, never mentioned in the > docs and > never tested for. Strong evidence that it was simply overlooked.
I had always intended for that policy to forbid all mixed case words. When someone shouts out the name of a variable or subroutine from across the room, I don't want to have to guess at how it is capitalized. I don't have a copy of PBP handy right now, so I can't verify my thinking. Perhaps I misinterpreted Conway. If the correct action is to split the policy in two (one for underscores, one for capitalization) then let's do that. And if Conway doesn't specifically address the capitalization of one- word symbols, then there is room for interpretation. Rather than impose your interpretation or mine, let's just make it configurable. Does that sound reasonable? Jeffrey Thalhammer Imaginative Software Systems vcard: http://www.imaginative-software.com/contact/jeff.vcf
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 20:17:32 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Michael G Schwern via RT wrote: Show quoted text
>> Why is this a bug? Mixed case means you can't have both upper and >> lower case in a variable name, which "Foo" definitely does.
> > The intent of the policy is to prohibit $StudlyCaps style in favor of > $Using_Underscores (Chapter 3.5 of PBP, "Underscores"). The > $StudlyCaps vs $Using_Underscores decision only applies to how you > separate words in names. $Foo is just one word and thus is not > $StudlyCaps any more than $foo is. It suffers from none of the > readability concerns of $StudlyCaps smashing words together. > > $Foo variables are never discussed in 3.5, never mentioned in the > docs and never tested for. Strong evidence that it was simply > overlooked. > > Controlling capitalization would be a different policy. Chapter 3.6 > discusses how to use capitalization and uses rather different > reasoning from 3.5. I don't agree with that policy's use of > capitalization (IMHO distinguishing $local vs $Global is more > important) and would like to be able to turn it off separate from > prohibiting $StudlyCaps.
I agree that the policy picks the wrong page number as its reference. However, there's no way that we're going to be able to differentiate words within a variable name and tell where the underscores should go. So, I'm for simply changing the policy to point to the correct pages, which state, unambiguously: "Use lowercase only for the names of subroutines, methods, variables, and labeled arguments ($controller,new(),src=>$fh)." I feel that $Foo should fall under the same rules as $Foo_Bar. It's mixed case, period. However, I understand your standard of using mixed case for global values. The question is how to handle this. Given the name of the existing policy, my thought is that it should have an option to give an exception to global and file scope variables. Then, we could create a separate policy that requires the first character in global/file scope variables be upper case. Show quoted text
> NamingConventions::ProhibitMixedCaseSubs has the same bug. Here's a > patch for that.
This I completely disagree with. One could come up with a separate standard saying that regular subs are "global", where as methods are not. But I'm not sure that such a standard would be widely accepted.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 20:51:55 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Elliot Shank via RT wrote: Show quoted text
> Michael G Schwern via RT wrote:
>> $Foo variables are never discussed in 3.5, never mentioned in the >> docs and never tested for. Strong evidence that it was simply >> overlooked. >> >> Controlling capitalization would be a different policy. Chapter >> 3.6 discusses how to use capitalization and uses rather different >> reasoning from 3.5. I don't agree with that policy's use of >> capitalization (IMHO distinguishing $local vs $Global is more >> important) and would like to be able to turn it off separate from >> prohibiting $StudlyCaps.
> > I agree that the policy picks the wrong page number as its reference. > However, there's no way that we're going to be able to differentiate > words within a variable name and tell where the underscores should > go. So, I'm for simply changing the policy to point to the correct > pages...
I've changed the page numbers.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 19:39:11 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 >
>> $Foo variables are never discussed in 3.5, never mentioned in the >> docs and >> never tested for. Strong evidence that it was simply overlooked.
> > I had always intended for that policy to forbid all mixed case words. > When someone shouts out the name of a variable or subroutine from > across the room, I don't want to have to guess at how it is capitalized. > > I don't have a copy of PBP handy right now, so I can't verify my > thinking. Perhaps I misinterpreted Conway. If the correct action is > to split the policy in two (one for underscores, one for > capitalization) then let's do that. > > And if Conway doesn't specifically address the capitalization of one- > word symbols, then there is room for interpretation. Rather than > impose your interpretation or mine, let's just make it configurable.
PBP does address capitalization, but in a wholly different chapter from StudlyCaps. Chapter 3.5: Underscores. "Use underscores to separate words in multiword identifiers." Chapter 3.6: Capitalization. "Distinguish different program components by case." These two considerations are orthogonal. For example, the $local/$Global capitalization style says nothing about whether you use $localFoo/$GlobalFoo or $local_foo/$Global_Foo. The prohibition on StudyCaps has little need for configuration and it's fairly straight-forward rule about multi-word identifiers. You join multiple words with an underscore, not with a capitalization change. You agree with it, or you don't. There's nothing to configure. Also the prohibition of studlyCaps is very common in Perl culture. It's right there in perlstyle and it dominates CPAN code. A StudlyCaps prohibition is safe and can be placed at a relatively high severity. In contrast, there's little agreement on capitalization policies. PBP and perlstyle do not agree. They are much more complicated and require a lot more tweaking than a StudlyCaps prohibition. Any capitalization policy chosen to be the default by perlcritic will be contentious and have to be placed at a low severity. Here's PBP's: * use lowercase only for names of subroutines, methods, variables and labeled arguments ($controller, new(), src => $fh) * ucfirst for package and class names (Foo::Bar) * all upper-case for constants ($SRC, $NODE) Here's the perlstyle policy: * $local (function scope) * $Global (package scope) * $CONSTANT (constants) * ucfirst for package and class names (Foo::Bar) * lower case for functions and methods Others might prefer to ucfirst exported subroutines. Some might want to ucfirst named args. Some folks like $GLOBAL. A complete capitalization policy needs to allow control over whether your identifiers are $lowercase, $Ucfirst or $ALL_CAPS. It needs to distinguish between single subroutine, multi-subroutine and constant variables. Also package names, subroutines in general vs methods vs exported subroutines and somehow pick out named args. PBP's capitalization policy might be configured as: subroutines = lower variables = lower labeled_arguments = lower packages = ucfirst constants = upper perlstyle's is: local_variables = lower global_variables = ucfirst constants = upper packages = ucfirst subroutines = lower A lot of that may not be technically feasible, but I hope you get the point that capitalization policy is a rather different beastie than just StudlyCaps vs under_score and rather more involved. StudlyCaps is a simple, safe policy. It shouldn't be dragged down by the capitalization quagmire. PS "Mixed case" is a poor description for StudlyCaps. PBP and perlstyle describes "IO::Controller" as "mixed-case". It's ambiguous. This is why I avoid "mixed case" prefer the terms StudlyCaps and ucfirst. The name of the policy, "ProhibitMixedCase", reflects this confusion. It should probably be "ProhibitStudlyCaps". Ironically, the name of the policy is in StudlyCaps. -- 170. Not allowed to "defect" to OPFOR during training missions. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 19:39:50 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
>>> Why is this a bug? Mixed case means you can't have both upper and >>> lower case in a variable name, which "Foo" definitely does.
>> The intent of the policy is to prohibit $StudlyCaps style in favor of >> $Using_Underscores (Chapter 3.5 of PBP, "Underscores"). The >> $StudlyCaps vs $Using_Underscores decision only applies to how you >> separate words in names. $Foo is just one word and thus is not >> $StudlyCaps any more than $foo is. It suffers from none of the >> readability concerns of $StudlyCaps smashing words together. >> >> $Foo variables are never discussed in 3.5, never mentioned in the >> docs and never tested for. Strong evidence that it was simply >> overlooked. >> >> Controlling capitalization would be a different policy. Chapter 3.6 >> discusses how to use capitalization and uses rather different >> reasoning from 3.5. I don't agree with that policy's use of >> capitalization (IMHO distinguishing $local vs $Global is more >> important) and would like to be able to turn it off separate from >> prohibiting $StudlyCaps.
> > However, there's no way that we're going to be able to differentiate words within > a variable name and tell where the underscores should go.
There's no need to do that. The policy is just about FooBar vs foo_bar. It's not about guessingwherethewordbreakis. Show quoted text
> So, I'm for simply changing the policy to point to the correct pages, which state, unambiguously: > > "Use lowercase only for the names of subroutines, methods, variables, and > labeled arguments ($controller,new(),src=>$fh)."
This is in an different chapter from the discussion on underscores vs StudlyCaps with different reasoning. I'll address that fully in another reply. Show quoted text
>> NamingConventions::ProhibitMixedCaseSubs has the same bug. Here's a >> patch for that.
> > This I completely disagree with. One could come up with a separate standard saying that > regular subs are "global", where as methods are not. But I'm not sure that
such a standard Show quoted text
> would be widely accepted.
Whichever way ProhibitMixedCaseVars goes, ProhibitMixedCaseSubs should. -- E: "Would you want to maintain a 5000 line Perl program?" d: "Why would you write a 5000 line program?"
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 19:38:14 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
>>> Why is this a bug? Mixed case means you can't have both upper and >>> lower case in a variable name, which "Foo" definitely does.
>> The intent of the policy is to prohibit $StudlyCaps style in favor of >> $Using_Underscores (Chapter 3.5 of PBP, "Underscores"). The >> $StudlyCaps vs $Using_Underscores decision only applies to how you >> separate words in names. $Foo is just one word and thus is not >> $StudlyCaps any more than $foo is. It suffers from none of the >> readability concerns of $StudlyCaps smashing words together. >> >> $Foo variables are never discussed in 3.5, never mentioned in the >> docs and never tested for. Strong evidence that it was simply >> overlooked. >> >> Controlling capitalization would be a different policy. Chapter 3.6 >> discusses how to use capitalization and uses rather different >> reasoning from 3.5. I don't agree with that policy's use of >> capitalization (IMHO distinguishing $local vs $Global is more >> important) and would like to be able to turn it off separate from >> prohibiting $StudlyCaps.
> > However, there's no way that we're going to be able to differentiate words within > a variable name and tell where the underscores should go.
There's no need to do that. The policy is just about FooBar vs foo_bar. It's not about guessingwherethewordbreakis. Show quoted text
> So, I'm for simply changing the policy to point to the correct pages, which state, unambiguously: > > "Use lowercase only for the names of subroutines, methods, variables, and > labeled arguments ($controller,new(),src=>$fh)."
This is in an different chapter from the discussion on underscores vs StudlyCaps with different reasoning. I'll address that fully in another reply. Show quoted text
>> NamingConventions::ProhibitMixedCaseSubs has the same bug. Here's a >> patch for that.
> > This I completely disagree with. One could come up with a separate standard saying that > regular subs are "global", where as methods are not. But I'm not sure that
such a standard Show quoted text
> would be widely accepted.
Whichever way ProhibitMixedCaseVars goes, ProhibitMixedCaseSubs should. -- E: "Would you want to maintain a 5000 line Perl program?" d: "Why would you write a 5000 line program?"
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 19:39:08 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
>>> Why is this a bug? Mixed case means you can't have both upper and >>> lower case in a variable name, which "Foo" definitely does.
>> The intent of the policy is to prohibit $StudlyCaps style in favor of >> $Using_Underscores (Chapter 3.5 of PBP, "Underscores"). The >> $StudlyCaps vs $Using_Underscores decision only applies to how you >> separate words in names. $Foo is just one word and thus is not >> $StudlyCaps any more than $foo is. It suffers from none of the >> readability concerns of $StudlyCaps smashing words together. >> >> $Foo variables are never discussed in 3.5, never mentioned in the >> docs and never tested for. Strong evidence that it was simply >> overlooked. >> >> Controlling capitalization would be a different policy. Chapter 3.6 >> discusses how to use capitalization and uses rather different >> reasoning from 3.5. I don't agree with that policy's use of >> capitalization (IMHO distinguishing $local vs $Global is more >> important) and would like to be able to turn it off separate from >> prohibiting $StudlyCaps.
> > However, there's no way that we're going to be able to differentiate words within > a variable name and tell where the underscores should go.
There's no need to do that. The policy is just about FooBar vs foo_bar. It's not about guessingwherethewordbreakis. Show quoted text
> So, I'm for simply changing the policy to point to the correct pages, which state, unambiguously: > > "Use lowercase only for the names of subroutines, methods, variables, and > labeled arguments ($controller,new(),src=>$fh)."
This is in an different chapter from the discussion on underscores vs StudlyCaps with different reasoning. I'll address that fully in another reply. Show quoted text
>> NamingConventions::ProhibitMixedCaseSubs has the same bug. Here's a >> patch for that.
> > This I completely disagree with. One could come up with a separate standard saying that > regular subs are "global", where as methods are not. But I'm not sure that
such a standard Show quoted text
> would be widely accepted.
Whichever way ProhibitMixedCaseVars goes, ProhibitMixedCaseSubs should. -- E: "Would you want to maintain a 5000 line Perl program?" d: "Why would you write a 5000 line program?"
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 19:38:31 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 >
>> $Foo variables are never discussed in 3.5, never mentioned in the >> docs and >> never tested for. Strong evidence that it was simply overlooked.
> > I had always intended for that policy to forbid all mixed case words. > When someone shouts out the name of a variable or subroutine from > across the room, I don't want to have to guess at how it is capitalized. > > I don't have a copy of PBP handy right now, so I can't verify my > thinking. Perhaps I misinterpreted Conway. If the correct action is > to split the policy in two (one for underscores, one for > capitalization) then let's do that. > > And if Conway doesn't specifically address the capitalization of one- > word symbols, then there is room for interpretation. Rather than > impose your interpretation or mine, let's just make it configurable.
PBP does address capitalization, but in a wholly different chapter from StudlyCaps. Chapter 3.5: Underscores. "Use underscores to separate words in multiword identifiers." Chapter 3.6: Capitalization. "Distinguish different program components by case." These two considerations are orthogonal. For example, the $local/$Global capitalization style says nothing about whether you use $localFoo/$GlobalFoo or $local_foo/$Global_Foo. The prohibition on StudyCaps has little need for configuration and it's fairly straight-forward rule about multi-word identifiers. You join multiple words with an underscore, not with a capitalization change. You agree with it, or you don't. There's nothing to configure. Also the prohibition of studlyCaps is very common in Perl culture. It's right there in perlstyle and it dominates CPAN code. A StudlyCaps prohibition is safe and can be placed at a relatively high severity. In contrast, there's little agreement on capitalization policies. PBP and perlstyle do not agree. They are much more complicated and require a lot more tweaking than a StudlyCaps prohibition. Any capitalization policy chosen to be the default by perlcritic will be contentious and have to be placed at a low severity. Here's PBP's: * use lowercase only for names of subroutines, methods, variables and labeled arguments ($controller, new(), src => $fh) * ucfirst for package and class names (Foo::Bar) * all upper-case for constants ($SRC, $NODE) Here's the perlstyle policy: * $local (function scope) * $Global (package scope) * $CONSTANT (constants) * ucfirst for package and class names (Foo::Bar) * lower case for functions and methods Others might prefer to ucfirst exported subroutines. Some might want to ucfirst named args. Some folks like $GLOBAL. A complete capitalization policy needs to allow control over whether your identifiers are $lowercase, $Ucfirst or $ALL_CAPS. It needs to distinguish between single subroutine, multi-subroutine and constant variables. Also package names, subroutines in general vs methods vs exported subroutines and somehow pick out named args. PBP's capitalization policy might be configured as: subroutines = lower variables = lower labeled_arguments = lower packages = ucfirst constants = upper perlstyle's is: local_variables = lower global_variables = ucfirst constants = upper packages = ucfirst subroutines = lower A lot of that may not be technically feasible, but I hope you get the point that capitalization policy is a rather different beastie than just StudlyCaps vs under_score and rather more involved. StudlyCaps is a simple, safe policy. It shouldn't be dragged down by the capitalization quagmire. PS "Mixed case" is a poor description for StudlyCaps. PBP and perlstyle describes "IO::Controller" as "mixed-case". It's ambiguous. This is why I avoid "mixed case" prefer the terms StudlyCaps and ucfirst. The name of the policy, "ProhibitMixedCase", reflects this confusion. It should probably be "ProhibitStudlyCaps". Ironically, the name of the policy is in StudlyCaps. -- 170. Not allowed to "defect" to OPFOR during training missions. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Sorry about the spammage. Dodgy cafe wireless meant the message had to be submitted multiple times before it was confirmed sent.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 22:53:28 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Michael G Schwern via RT wrote: Show quoted text
> PS "Mixed case" is a poor description for StudlyCaps. PBP and perlstyle > describes "IO::Controller" as "mixed-case". It's ambiguous. This is why I > avoid "mixed case" prefer the terms StudlyCaps and ucfirst. The name of the > policy, "ProhibitMixedCase", reflects this confusion. It should probably be > "ProhibitStudlyCaps". Ironically, the name of the policy is in StudlyCaps.
I'd agree that it's a bad name because, to me, "mixed case" unambiguously means "more than one case". As far as the "proper" name for it, I refer to it as "CamelCase". :]
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Fri, 22 Aug 2008 23:38:29 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
> As far as the "proper" name for it, I refer to it as "CamelCase". :]
Fine by me. -- Don't try the paranormal until you know what's normal. -- "Lords and Ladies" by Terry Prachett
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sat, 23 Aug 2008 23:52:35 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
Ok, so how about this: * Rename ProhibitMixedCase(Subs|Vars) to ProhibitCamelCase(Subs|Vars). * Modify both of these policies to forbid $fooBar, but not $Foo or $Foo_Bar. * Create a new configurable policy that enforces the capitalization patterns that Schwern outlined. * The defaults for this new policy should be consistent with PBP prohibition on mixed-case vars and subs. Would that address everyone's concerns? -Jeff
Can you add ProhibitCamelCasePolicyNames?
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 11:41:12 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> Ok, so how about this: > > * Rename ProhibitMixedCase(Subs|Vars) to ProhibitCamelCase(Subs|Vars). > * Modify both of these policies to forbid $fooBar, but not $Foo or > $Foo_Bar.
No. As Schwern pointed out, the policies don't well implement the points in PBP section 3.5, but they do properly implement the stuff in section 3.6, which says single case, full stop, with variable and sub names. I've changed the page numbers in the policies, but we probably need to revisit the DESCRIPTIONs. The other issue with renaming them is just the general issue of uninstallation of installed modules in Perl. Show quoted text
> * Create a new configurable policy that enforces the capitalization > patterns that Schwern outlined. > * The defaults for this new policy should be consistent with PBP > prohibition on mixed-case vars and subs.
Yes, this is a separate issue. But the mention of perlstyle does make me think we should mine it for new potential policies.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 11:40:58 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > Ok, so how about this: > > * Rename ProhibitMixedCase(Subs|Vars) to ProhibitCamelCase(Subs|Vars). > * Modify both of these policies to forbid $fooBar, but not $Foo or > $Foo_Bar. > * Create a new configurable policy that enforces the capitalization > patterns that Schwern outlined. > * The defaults for this new policy should be consistent with PBP > prohibition on mixed-case vars and subs. > > Would that address everyone's concerns?
Splendid. -- The mind is a terrible thing, and it must be stopped.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 11:51:13 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > Jeffrey Thalhammer via RT wrote:
>> Ok, so how about this: >> >> * Rename ProhibitMixedCase(Subs|Vars) to ProhibitCamelCase(Subs|Vars). >> * Modify both of these policies to forbid $fooBar, but not $Foo or >> $Foo_Bar.
> > No. > > As Schwern pointed out, the policies don't well implement the points in PBP section 3.5, > but they do properly implement the stuff in section 3.6, which says single
case, full stop, Show quoted text
> with variable and sub names. > > I've changed the page numbers in the policies, but we probably need to revisit the DESCRIPTIONs. > > The other issue with renaming them is just the general issue of uninstallation of installed > modules in Perl.
You could ship empty versions of the exiting MixedCase modules to overwrite the existing ones. If an empty policy module will make Perl::Critic choke, you can add a disabled() or deleted() method or for it to look for. The important thing is eliminating the ambiguous "mixed case" term and separating CamelCase from capitalization. -- I'm pale as formica, social skills stunted small. But I'm accurate like a pica, I know the capital of nepal. I'm the nemesis of error, dreadful diction fears my skills, more inquisitive than Jim Lehrer, snottier than Beverly Hills. -- I.L.O.P. Secret Rap http://goats.com/archive/020830.html
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 14:43:49 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Chris Dolan <chris [...] chrisdolan.net>
On Aug 24, 2008, at 1:52 PM, Michael G Schwern via RT wrote: Show quoted text
> Queue: Perl-Critic > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > You could ship empty versions of the exiting MixedCase modules to > overwrite > the existing ones. If an empty policy module will make > Perl::Critic choke, > you can add a disabled() or deleted() method or for it to look for. > > The important thing is eliminating the ambiguous "mixed case" term and > separating CamelCase from capitalization.
I disagree. MixedCase and CamelCase are indeed two different styles, and I want neither in my code, so the MixedCase policy is exactly what I want. $Foo is a *terrible* variable name. Chris
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 12:52:21 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
Show quoted text
>>
> I disagree. MixedCase and CamelCase are indeed two different styles, > and I want neither in my code, so the MixedCase policy is exactly > what I want.
Me too. So that's why I was thinking that ProhibitCamelCase + CapitalizationPolicyToBeWritten would effectively default to a total ban on mixed-case symbols (just as we have now). But this would allow folks to address WordSeparation and Capitalization_Strategies issues separately. Which I believe is the main thrust of Schwern's suggestions. -Jeff
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 12:55:29 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
Show quoted text
>> The other issue with renaming them is just the general issue of >> uninstallation of installed >> modules in Perl.
> > You could ship empty versions of the exiting MixedCase modules to > overwrite > the existing ones. If an empty policy module will make Perl::Critic > choke, > you can add a disabled() or deleted() method or for it to look for.
Ick. There's got to be a better way. Would it be evil if we rigged Build.PL to delete deprecated Policies upon installation? -Jeff
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 18:09:53 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
>>> The other issue with renaming them is just the general issue of >>> uninstallation of installed modules in Perl.
>> You could ship empty versions of the exiting MixedCase modules to >> overwrite the existing ones. If an empty policy module will make >> Perl::Critic choke, you can add a disabled() or deleted() method or >> for it to look for.
> > Ick. There's got to be a better way. Would it be evil if we rigged > Build.PL to delete deprecated Policies upon installation?
There's already a mechanism for doing this: initialize_if_enabled(). But it doesn't matter, because there's no reason to do the rename.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 24 Aug 2008 18:10:46 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> Queue: Perl-Critic > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > >
>> I disagree. MixedCase and CamelCase are indeed two different styles, >> and I want neither in my code, so the MixedCase policy is exactly >> what I want.
> > Me too. So that's why I was thinking that ProhibitCamelCase + > CapitalizationPolicyToBeWritten would effectively default to a total > ban on mixed-case symbols (just as we have now). But this would allow > folks to address WordSeparation and Capitalization_Strategies issues > separately. Which I believe is the main thrust of Schwern's > suggestions.
There's nothing ambiguous about "mixed case". It means no lower case and upper case characters in the same name.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Mon, 25 Aug 2008 16:49:13 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > Jeffrey Thalhammer via RT wrote:
>> Queue: Perl-Critic >> Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > >>
>>> I disagree. MixedCase and CamelCase are indeed two different styles, >>> and I want neither in my code, so the MixedCase policy is exactly >>> what I want.
>> Me too. So that's why I was thinking that ProhibitCamelCase + >> CapitalizationPolicyToBeWritten would effectively default to a total >> ban on mixed-case symbols (just as we have now). But this would allow >> folks to address WordSeparation and Capitalization_Strategies issues >> separately. Which I believe is the main thrust of Schwern's >> suggestions.
> > There's nothing ambiguous about "mixed case". It means no lower case > and upper case characters in the same name.
In the end, the important thing is that I can enforce a word separation policy (fooBar vs foo_bar) separate from a capitalization policy (foo vs Foo vs FOO) and that it's clear to the user what each policy is going to do. If the two concepts are conflated into one policy, that becomes difficult. Ambiguous name or not. With that made clear, everyone sensible can stop reading now. Ok, only the pedants are left. I would not be allowed to keep my membership in the ILoP [1] if I didn't drive the point into the ground. :) So I decided to google for "mixed case variable names" and see how it's used: whether "mixed case" means all letters within a word or just interword-separation (fooBar). Below is the first dozen or so uses off Google. As you can see, they all use some variation of camelCase or sTudLyCaPs for their examples and none refer to a simple ucfirst "Foo" variable as being mixed case. They're all discussing capitalization as a means of interword separation. They all use "foo_bar" or "foobar" as counters. They're all discussing multi-word names. None discuss the capitalization of single-word names. If whether the first letter should be capitalized is significant it's explicitly spelled out. None use "mixed case" to mean just "lower case and upper case characters in the same name". They all use it to mean "case-switch as an interword separator". So you're right, there isn't anything ambiguous about "mixed case". ;) http://support.sas.com/kb/7/174.html From webEIS software within AppDev Studio, you could get an error such as: ERROR: _GET_UNIQUE_VALUES_ failed. Invalid class list. Arguments passed to SEND: 1 (Character Literal) = '_get_unique_values_' Parameters passed to SEND ENTRY: 1 table=TABLE1 2 nextLevel= Program returning prematurely at line 581 AF Program: SASHELP.RSASMOD.MDAXIS.SCL https://secure.wikimedia.org/wikipedia/en/wiki/Mixed_case The systematic use of capitalized and uncapitalized words in running text is called "mixed case" http://forum.wordreference.com/showthread.php?t=941391 Make all variable names mixed case. That is, each word or abbreviation within the variable name should be capitalized. http://everything2.com/node/1253565 Why do programmers have annoyingly mixed case function names? ConvertFormatAToFormatB(A, B); http://everything2.com/node/1253565 And SmallTalk is pretty much the parent of modern object oriented languages. Presumably mixedCaseNames (as opposed to underscore_separated_names) are more a forgotten legacy of SmallTalk than some carefully-conceived ergonomic device. http://everything2.com/e2node/CamelCase A special form of mixed-case identifiers widely used mainly in Java circles, so named because they look like this: camelCaseIdentifier The first word of a multi-word identifier is in lower case (the head of the "camel"), while subsequent words are capitalized (the "humps" of the "camel"). http://books.google.com/books?id=14CSsIUQ24kC&pg=PA5&lpg=PA5&dq=mixed+case+variable+names&source=web&ots=eVnDz1orqJ&sig=oDLhBgGmpOmGjqdwA1gH-OKTUl0&hl=en&sa=X&oi=book_result&resnum=6&ct=result The data set name heightweight is the same as HEIGHTWEIGHT or HeightWeight. Likewise, the variable name BirthDate is the same as BIRTHDATE and birThDaTe. However, there is one difference for variable names. SAS remembers the case of the first occurence of each variable name and uses that case when printing results. That is why, in this book, we use mixed case for variable names but lowercase for other SAS names. http://www.velocityreviews.com/forums/t434570-new-coding-standards-use-underscores-hyphens-or-mixed-case-in-command-and-identifier-names.html Before I embark on a new long-term project I'd appreciate your advice on how to split up long names. I would like to keep the standards for command names the same as that for variable names. Looking at the examples below, which ones seem better? Straight names echoclient lastcharoffset helloworld Internal underscores echo_client last_char_offset hello_world I could also use embedded hyphens as my minus sign must be surrounded by whitespace (please suspend disbelief while looking at these. I know they will look unfamiliar!) echo-client last-char-offset hello-world Mixed case EchoClient LastCharOffset HelloWorld Initial lower case then mixed echoClient lastCharOffset helloWorld http://mail.zope.org/pipermail/zope-db/2002-February/000366.html For example, in Oracle you explicitly have to name your colums in mixed case for them to be mixed case: create table "MonKey" ( "wrEnch" varchar2(2), "l33tSPeaK" number(2,2), NoMatterWhatCase varchar2(10) ) http://www.perl.com/doc/manual/html/os2/OS2/REXX/REXX.html Most REXX DLLs export function names all upper case, but there are a few which export mixed case names (such as RxExtras) http://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html Class names should be nouns, in mixed case with the first letter of each internal word capitalized. ... Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. ... Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. Internal words start with capital letters http://www.adobe.com/devnet/flash/articles/as_bestpractices_02.html Concatenate words to create names. Use mixed-cases (upper and lower case) when you concatenate words to distinguish between each word for readability. For example, select myPelican rather than mypelican. [1] International League of Pedants, "Accuracy Over Tact". -- 124. Two drink limit does not mean first and last. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Mon, 25 Aug 2008 16:58:04 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > >
>>> The other issue with renaming them is just the general issue of >>> uninstallation of installed >>> modules in Perl.
>> You could ship empty versions of the exiting MixedCase modules to >> overwrite >> the existing ones. If an empty policy module will make Perl::Critic >> choke, >> you can add a disabled() or deleted() method or for it to look for.
> > Ick. There's got to be a better way. Would it be evil if we rigged > Build.PL to delete deprecated Policies upon installation?
It's doable, but not advised. Deleting modules is sketchy. One of the problems is shadowing. For example, if there are two versions of Perl::Critic installed in different points in @INC. For example, one installed from a package (which goes into vendor) and one installed from CPAN (which goes into site). If you delete one policy you might simply reveal an older version of the policy. This depends on whether your system searches through @INC to find policies or if it searches the same directory as Perl::Critic::Policy is installed in. If it's the former, you're vulnerable. If it's the latter, you're not. Another consideration if you delete the policy, everyone who has tweaked that policy in their .perlcriticrc will start getting errors or warnings because the policy no longer exists. This is easier to control and document if there's still a policy file there. You can even make "ProhibitMixedCase" options pass through to "ProhitCamelCase" either quietly or with a deprecation warning. Finally, if the policy is simply deleted where does one go to find out what happened to it? Where does the information go to let the user know that "ProhibitMixedCase" is now "ProhibitCamelCase"? -- 191. Our Humvees cannot be assembled into a giant battle-robot. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Mon, 25 Aug 2008 22:16:23 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
On Aug 25, 2008, at 4:50 PM, Michael G Schwern via RT wrote: Show quoted text
> > > None use "mixed case" to mean just "lower case and upper case > characters in > the same name". They all use it to mean "case-switch as an interword > separator". So you're right, there isn't anything ambiguous about > "mixed > case". ;)
So that's good news (at least we don't have to worry about renaming the policy). Then I'll change ProhibitMixedCase(Vars|Subs) to target just $fooBar and not $Foobar. Schwern: do you have the tuits to write the capitalization Policy to complement this change? -Jeff
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Tue, 26 Aug 2008 08:01:39 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> On Aug 25, 2008, at 4:50 PM, Michael G Schwern via RT wrote:
>> >> None use "mixed case" to mean just "lower case and upper case >> characters in >> the same name". They all use it to mean "case-switch as an interword >> separator". So you're right, there isn't anything ambiguous about >> "mixed >> case". ;)
> > So that's good news (at least we don't have to worry about renaming > the policy). Then > I'll change ProhibitMixedCase(Vars|Subs) to target just $fooBar and > not $Foobar.
Please don't.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Tue, 26 Aug 2008 13:42:07 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
On Aug 26, 2008, at 6:02 AM, Elliot Shank via RT wrote: Show quoted text
>> >> So that's good news (at least we don't have to worry about renaming >> the policy). Then >> I'll change ProhibitMixedCase(Vars|Subs) to target just $fooBar and >> not $Foobar.
> > Please don't.
I just want to find a way to move forward on this. I think Schwern has made a good point that capitalization and word separation are separate issues. Even if you and I prefer to code in all lower-case, P::C should enable folks to choose the scheme that they want. I'm not trying to change the default rules -- the last thing I want is for everyone who has been using these Policies to have to change their coding style. The (default) net effect of these changes will be to continue the ban on mixed-case words in all variables and subroutine names, as described in PBP. However, I would like to open the possibility for folks to enforce other capitalization schemes. In particular, using ucfirst for file- scoped (non-constant) variables. Is that so awful? -Jeff
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Tue, 26 Aug 2008 20:42:12 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> On Aug 26, 2008, at 6:02 AM, Elliot Shank via RT wrote:
>>> So that's good news (at least we don't have to worry about renaming >>> the policy). Then >>> I'll change ProhibitMixedCase(Vars|Subs) to target just $fooBar and >>> not $Foobar.
>> Please don't.
> > I just want to find a way to move forward on this. I think Schwern > has made a good point that capitalization and word separation are > separate issues. Even if you and I prefer to code in all lower-case, > P::C should enable folks to choose the scheme that they want.
[chop] Show quoted text
> However, I would like to open the possibility for folks to enforce > other capitalization schemes. In particular, using ucfirst for file- > scoped (non-constant) variables. > > Is that so awful?
No, given the name of the policy, I think it should keep its current functionality and not add other. I would prefer a new CapitalizeTheSchwernWay (I'm joking, I'm joking!) policy. I actually like the Capital_With_Underscores_For_File_Scope_Variables_Standard; I just think that that is not compatible with the current policy name.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Tue, 26 Aug 2008 19:36:20 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
On Aug 26, 2008, at 6:42 PM, Elliot Shank via RT wrote: Show quoted text
> No, given the name of the policy, I think it should keep its current > functionality and not add other. I would prefer a new > CapitalizeTheSchwernWay (I'm joking, I'm joking!) policy. I > actually like the > Capital_With_Underscores_For_File_Scope_Variables_Standard; I just > think that that is not compatible with the current policy name.
Yes, the capitalization policy would be separate (I never meant to suggest otherwise). And by default, it would prohibit $Foo_Bar, but could be configured to require it. Meanwhile, ProhibitMixedCaseVars would be retasked with just finding $fooBar. Together, the two Policies would enforce the same coding style that we currently have. But it would give folks an option to enforce a different capitalization strategy, especially for file-scoped lexicals. -Jeff
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Tue, 26 Aug 2008 22:21:25 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> Meanwhile, ProhibitMixedCaseVars would be retasked with just finding > $fooBar.
No. It should continue as it works now.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Wed, 27 Aug 2008 17:24:12 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> On Aug 25, 2008, at 4:50 PM, Michael G Schwern via RT wrote:
>> >> None use "mixed case" to mean just "lower case and upper case >> characters in >> the same name". They all use it to mean "case-switch as an interword >> separator". So you're right, there isn't anything ambiguous about >> "mixed >> case". ;)
> > So that's good news (at least we don't have to worry about renaming > the policy).
I agree. Show quoted text
> Then I'll change ProhibitMixedCase(Vars|Subs) to target just $fooBar and > not $Foobar.
It occurred to me that all you need look for is [[:lower:]][[:upper:]] and not bother with [[:upper:]][[:lower:]]. That eliminates the exception for Foo and makes the MixedCase detection logic even simpler. It does, however, cause FOObar to pass so I think that's no good. Then I realized that all you have to do is ignore the first character. Attached is a patch against trunk to fix both MixedCase modules. I've also updated the Subs and Vars tests so they're testing the same names. And I eliminated a mistaken failure of Foo_Bar from Subs which did not appear in Vars. Show quoted text
> Schwern: do you have the tuits to write the > capitalization Policy to complement this change?
Sure, I kicked up the fuss I should fix it. I'll make it default to the PBP policy (even if I don't like it) and give it at least an option to follow the perlstyle policy. If I have some more time I'll try to make the individual attributes tweakable. Is there a new Policy writer's tutorial or a similar policy I can crib from? -- Stabbing you in the face for your own good.
--- lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseSubs.pm (/mirror/perlcritic-trunk/Perl-Critic) (revision 60229) +++ lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseSubs.pm (/local/Perl-Critic) (local) @@ -22,7 +22,10 @@ Readonly::Scalar my $UPPER_LOWER => qr/ [[:upper:]] [[:lower:]] /xms; Readonly::Scalar my $LOWER_UPPER => qr/ [[:lower:]] [[:upper:]] /xms; -Readonly::Scalar my $MIXED_RX => qr{ $UPPER_LOWER | $LOWER_UPPER }xmso; +Readonly::Scalar my $MIXED_RX => qr{ + ^.+ # ignore the first character in the name + (?: $UPPER_LOWER | $LOWER_UPPER ) +}xmso; Readonly::Scalar my $DESC => 'Mixed-case subroutine name'; Readonly::Scalar my $EXPL => [ 45, 46 ]; --- lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseVars.pm (/mirror/perlcritic-trunk/Perl-Critic) (revision 60229) +++ lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseVars.pm (/local/Perl-Critic) (local) @@ -24,7 +24,10 @@ Readonly::Scalar my $PACKAGE_RX => qr/ :: /xms; Readonly::Scalar my $UPPER_LOWER => qr/ [[:upper:]] [[:lower:]] /xms; Readonly::Scalar my $LOWER_UPPER => qr/ [[:lower:]] [[:upper:]] /xms; -Readonly::Scalar my $MIXED_RX => qr{ $UPPER_LOWER | $LOWER_UPPER }xmso; +Readonly::Scalar my $MIXED_RX => qr{ + ^.{2,} # ignore the sigil and the first character in the name + (?: $UPPER_LOWER | $LOWER_UPPER ) +}xmso; Readonly::Scalar my $DESC => 'Mixed-case variable name(s)'; Readonly::Scalar my $EXPL => [ 45, 46 ]; --- t/NamingConventions/ProhibitMixedCaseSubs.run (/mirror/perlcritic-trunk/Perl-Critic) (revision 60229) +++ t/NamingConventions/ProhibitMixedCaseSubs.run (/local/Perl-Critic) (local) @@ -1,10 +1,11 @@ ## name Basic failures. -## failures 4 +## failures 5 ## cut +sub fooBar {} sub fooBAR {} sub FooBar {} -sub Foo_Bar {} +sub FooBAR {} sub FOObar {} #----------------------------------------------------------------------------- @@ -18,6 +19,7 @@ sub FOO_bar {} sub Foo::Bar::grok {} sub Class::Encapsulate::_hidden::_hash_overload {} +sub Foo { return "foo" } #----------------------------------------------------------------------------- # Local Variables: --- t/NamingConventions/ProhibitMixedCaseVars.run (/mirror/perlcritic-trunk/Perl-Critic) (revision 60229) +++ t/NamingConventions/ProhibitMixedCaseVars.run (/local/Perl-Critic) (local) @@ -1,11 +1,13 @@ ## name Basic failures, one variable -## failures 4 +## failures 6 ## cut +my $fooBar; my $fooBAR; my ($fooBAR) = 'nuts'; local $FooBar; our ($FooBAR); +my $FOObar; #----------------------------------------------------------------------------- @@ -34,7 +36,7 @@ our (%FOO_BAR, @BAR_FOO); local ($FOO_BAR, %BAR_foo) = @_; my ($foo_bar, $foo); - +my $Foo; #-----------------------------------------------------------------------------
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Wed, 27 Aug 2008 17:39:07 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
Show quoted text
> Sure, I kicked up the fuss I should fix it. I'll make it default to > the PBP > policy (even if I don't like it) and give it at least an option to > follow the > perlstyle policy. If I have some more time I'll try to make the > individual > attributes tweakable.
Elliot and I still haven't reached agreement on how to handle this. But don't let that stop you. Having an actual set of Policies in front of us will help us to iron out our differences. Show quoted text
> Is there a new Policy writer's tutorial or a similar policy I can > crib from?
Check out http://search.cpan.org/~elliotjs/Perl-Critic-1.090/lib/Perl/Critic/DEVELOPER.pod
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Wed, 27 Aug 2008 20:49:08 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Michael G Schwern via RT wrote: Show quoted text
> Below is the first dozen or so uses off Google. As you can see, they all use > some variation of camelCase or sTudLyCaPs for their examples and none refer to > a simple ucfirst "Foo" variable as being mixed case. They're all discussing > capitalization as a means of interword separation. They all use "foo_bar" or > "foobar" as counters. They're all discussing multi-word names. None discuss > the capitalization of single-word names. If whether the first letter should > be capitalized is significant it's explicitly spelled out. > > None use "mixed case" to mean just "lower case and upper case characters in > the same name". They all use it to mean "case-switch as an interword > separator". So you're right, there isn't anything ambiguous about "mixed > case". ;)
Screw the programmers, I'm talking plain English.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Wed, 27 Aug 2008 19:49:04 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > Michael G Schwern via RT wrote:
>> Below is the first dozen or so uses off Google. As you can see, they all use >> some variation of camelCase or sTudLyCaPs for their examples and none refer to >> a simple ucfirst "Foo" variable as being mixed case. They're all discussing >> capitalization as a means of interword separation. They all use "foo_bar" or >> "foobar" as counters. They're all discussing multi-word names. None discuss >> the capitalization of single-word names. If whether the first letter should >> be capitalized is significant it's explicitly spelled out. >> >> None use "mixed case" to mean just "lower case and upper case characters in >> the same name". They all use it to mean "case-switch as an interword >> separator". So you're right, there isn't anything ambiguous about "mixed >> case". ;)
> > Screw the programmers, I'm talking plain English.
Let's put aside that programmers are perlcritic's audience, even in "plain English" Wikipedia defines "mixed case" as "the systematic use of capitalized and uncapitalized words in running text". https://secure.wikimedia.org/wikipedia/en/wiki/Mixed_case Elliot, just what is your goal here? -- s7ank: i want to be one of those guys that types "s/j&jd//.^$ueu*///djsls/sm." and it's a perl script that turns dog crap into gold.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Wed, 27 Aug 2008 20:00:20 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Attached is a patch for a basic Capitalization policy following PBP Chapter 3.6 the best I could. * I didn't try to tackle named arguments. * I don't know how to detect constants. PPI seems to not pick up "Readonly::Scalar my $foo" as a PPI::Statement::Variable. I just allowed any all caps variables. * I tried to keep the Capitalization policy from leaking into the MixedCase policies. Thus fooBar is allowed by the Capitalization policy, since that's how you'd do a "lower case" name in camelCase, but foo_Bar and FooBar are not. * I decided to put them together in only policy, rather than splitting it out like MixedCase is, in anticipation of having a "use the perlstyle capitalization policy" flag. I also... * switched the page numbers for the MixedCase policies back to page 44 which is the Underscore chapter in PBP. * bumped the severity of the MixedCase policies up to $SEVERITY_LOW since camelCase is widely disdained in Perl culture and is easy to detect. -- 87. If the thought of something makes me giggle for longer than 15 seconds, I am to assume that I am not allowed to do it. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
--- lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseSubs.pm (revision 60230) +++ lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseSubs.pm (local) @@ -27,12 +27,12 @@ (?: $UPPER_LOWER | $LOWER_UPPER ) }xmso; Readonly::Scalar my $DESC => 'Mixed-case subroutine name'; -Readonly::Scalar my $EXPL => [ 45, 46 ]; +Readonly::Scalar my $EXPL => [ 44 ]; #----------------------------------------------------------------------------- sub supported_parameters { return () } -sub default_severity { return $SEVERITY_LOWEST } +sub default_severity { return $SEVERITY_LOW } sub default_themes { return qw( core pbp cosmetic ) } sub applies_to { return 'PPI::Statement::Sub' } --- lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseVars.pm (revision 60230) +++ lib/Perl/Critic/Policy/NamingConventions/ProhibitMixedCaseVars.pm (local) @@ -29,12 +29,12 @@ (?: $UPPER_LOWER | $LOWER_UPPER ) }xmso; Readonly::Scalar my $DESC => 'Mixed-case variable name(s)'; -Readonly::Scalar my $EXPL => [ 45, 46 ]; +Readonly::Scalar my $EXPL => [ 44 ]; #----------------------------------------------------------------------------- sub supported_parameters { return () } -sub default_severity { return $SEVERITY_LOWEST } +sub default_severity { return $SEVERITY_LOW } sub default_themes { return qw( core pbp cosmetic ) } sub applies_to { return 'PPI::Statement::Variable' } --- lib/Perl/Critic/Policy/NamingConventions/Capitalization.pm (revision 60230) +++ lib/Perl/Critic/Policy/NamingConventions/Capitalization.pm (local) @@ -0,0 +1,171 @@ +############################################################################## +# $URL$ +# $Date$ +# $Author$ +# $Revision$ +############################################################################## + +package Perl::Critic::Policy::NamingConventions::Capitalization; + +use 5.006001; +use strict; +use warnings; + +use Readonly; + +use Perl::Critic::Utils qw{ :severities }; + +use base 'Perl::Critic::Policy'; + +our $VERSION = '1.090'; + +#----------------------------------------------------------------------------- + +Readonly::Scalar my $LOWER_RX => qr/ [[:lower:]] /xms; +Readonly::Scalar my $UPPER_RX => qr/ [[:upper:]] /xms; +Readonly::Scalar my $PACKAGE_RX => qr/ :: /xms; +Readonly::Scalar my $DESC => 'Capitalization'; +Readonly::Scalar my $EXPL => [ 45 ]; + +#----------------------------------------------------------------------------- + +sub supported_parameters { return () } +sub default_severity { return $SEVERITY_LOWEST } +sub default_themes { return qw( core pbp cosmetic ) } + +sub applies_to { + return 'PPI::Statement::Variable', + 'PPI::Statement::Package', + 'PPI::Statement::Sub'; +} + +#----------------------------------------------------------------------------- + +sub violates { + my ( $self, $elem, undef ) = @_; + + my $violates + = $elem->isa("PPI::Statement::Variable") ? _variable_capitalization($elem) + : $elem->isa("PPI::Statement::Package") ? _package_capitalization($elem) + : $elem->isa("PPI::Statement::Sub") ? _sub_capitalization($elem) + : die "Should never reach this point" + ; + + return $self->violation( $DESC, $EXPL, $elem ) if $violates; + return; +} + +sub _variable_capitalization { + my $elem = shift; + + for my $name ( $elem->variables() ) { + # Fully qualified names are exempt because we can't be responsible for + # other people's sybols. + next if $elem->type() eq 'local' && $name =~ m/$PACKAGE_RX/xms; + + # Allow CONSTANTS + next if $name !~ $LOWER_RX; + + # Words in variable names cannot be capitalized unless + # camelCase is in use + return 1 if $name =~ m{ [^[:alpha:]] $UPPER_RX }xmso; + } + + return; +} + +sub _package_capitalization { + my $elem = shift; + my @names = split /::/, $elem->namespace; + + for my $name (@names) { + # Each word should be capitalized. + return 1 unless $name =~ m{ ^ $UPPER_RX }xmso; + } + + return; +} + +sub _sub_capitalization { + my $elem = shift; + my $name = $elem->name; + + # Words in subroutine names cannot be capitalized + # unless camelCase is in use. + return 1 if $name =~ m{ + (?: ^ | [^[:alpha:]] ) + $UPPER_RX + }xmso; + return; +} + +1; + +__END__ + +#----------------------------------------------------------------------------- + +=head1 NAME + +Perl::Critic::Policy::NamingConventions::Capitalization - Distinguish different program components by case. + + +=head1 AFFILIATION + +This Policy is part of the core L<Perl::Critic|Perl::Critic> distribution. + +=head1 DESCRIPTION + +Conway recommends to distinguish different program components by case. + +Normal subroutines, methods and variables are all in lower case. + + my $foo; # ok + my $foo_bar; # ok + sub foo {} # ok + sub foo_bar {} # ok + + my $Foo; # not ok + my $foo_Bar; # not ok + sub Foo {} # not ok + sub foo_Bar {} # not ok + +Package and class names are capitalized. + + package IO::Thing; # ok + package Web::FooBar # ok + + package foo; # not ok + package foo::Bar; # not ok + +Constants are in all-caps. + + Readonly::Scalar my $FOO = 42; # ok + + Readonly::Scalar my $foo = 42; # not ok + +=head1 CONFIGURATION + +This Policy is not configurable except for the standard options. + + +=head1 BUGS + +The policy cannot currently tell that a variable is being declared as +a constant, thus any variable may be made all-caps. + + +=head1 SEE ALSO + +To control use of camelCase see L<Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseSubs|Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseSubs> and L<Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseVars|Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseVars>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 78 +# indent-tabs-mode: nil +# c-indentation-style: bsd +# End: +# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround : --- t/NamingConventions/Capitalization.run (revision 60230) +++ t/NamingConventions/Capitalization.run (local) @@ -0,0 +1,110 @@ +## name Basic Passes +## failures 0 +## cut + +my $foo; +our $bar; +my($foo, $bar) = ("BLEH", "BLEH"); +my @foo; +my %bar; +sub foo {} + +my $foo123; +my $foo123bar; +sub foo123 {} +sub foo123bar {} + +my $fooBar; # camelCase is ok +my $fooBAR; +sub fooBar {} +sub fooBAR {} + +my $CONSTANT; + +package This::SomeThing; +package This; +package This::Thing; +package Acme::12345; +package YYZ; + +#----------------------------------------------------------------------------- + +## name Basic Failures +## failures 14 +## cut + +my $Foo; +our $Bar; +my @Foo; +my %Bar; +sub Foo {} + +my $foo_Bar; +sub foo_Bar {} + +my $FooBar; +sub FooBar {} + +my $foo123Bar; +sub foo123Bar {} + +package pragma; +package Foo::baz; +package baz::FooBar; + +#----------------------------------------------------------------------------- + +## name Combined passes and fails +## failures 2 +## cut + +my($foo, $Bar); +our($Bar, $foo); + +#----------------------------------------------------------------------------- + +## name Variables from other packages should pass +## failures 0 +## cut + +local $Other::Package::Foo; +$Other::Package::Foo; + +#----------------------------------------------------------------------------- + +## name Only cares about declarations +## failures 0 +## cut +Foo(); +$Foo = 42; + +#----------------------------------------------------------------------------- + +## name Constants must be all caps, passes +## failures 0 +## cut + +Readonly::Scalar my $CONSTANT = 23; + +#----------------------------------------------------------------------------- + +## name Constants must be all caps, failures +## TODO Detect whether a scalar is constant or not +## failures 4 +## cut + +Readonly::Scalar my $Foo = 23; +Readonly::Scalar my $foo = 23; +Readonly::Scalar my $fooBAR = 23; +my $CONSTANT = 23; + + +#----------------------------------------------------------------------------- +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 78 +# indent-tabs-mode: nil +# c-indentation-style: bsd +# End: +# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Thu, 28 Aug 2008 07:55:14 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Michael G Schwern via RT wrote: Show quoted text
>> Screw the programmers, I'm talking plain English.
> > Let's put aside that programmers are perlcritic's audience, even in "plain > English" Wikipedia defines "mixed case" as "the systematic use of capitalized > and uncapitalized words in running text". > https://secure.wikimedia.org/wikipedia/en/wiki/Mixed_case > > Elliot, just what is your goal here?
I don't think /these two policies/ should be changed, except with regards to documentation. Their names, to me, are completely unambiguous. Like any other policy, you may not agree with what they do. I absolutely agree that they're inadequate and that additional functionality needs to be provided. However, changing the way that these two policies behave breaks people who depend upon their current behavior. In the past, we've added options to policies to restore old behavior, but, in this case, I don't think that such an option can be added without seriously confusing their meaning. I believe that these policies should be left as-is and a new, more capable policy with an appropriate name should be created, as in the one you wrote.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Thu, 28 Aug 2008 14:18:40 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Elliot Shank via RT wrote: Show quoted text
>> Elliot, just what is your goal here?
> > I don't think /these two policies/ should be changed, except with regards to documentation. > Their names, to me, are completely unambiguous.
As an author, the goal of clarity is not to be clear to yourself but to your audience. As demonstrated in piles, your audience uses a different definition. The name is misleading your audience and clarity is not achieved. If the policy is left using your definition, then the audience will get the wrong impression about what it does from the name. Additional documentation will be needed to reverse that impression. When you find yourself writing documentation of the form "you might think that X means it does Y, but it really means it does Z" that's a bright red flag that you have either the wrong name or the wrong functionality. It's a crack in the interface leading to misunderstanding and bugs (and tickets that go on and on and on and on). People don't study documentation to see if it does something different from what the name implies. It is better to get the functionality to line up with the audience's expectations. Show quoted text
> Like any other policy, you may not agree with what they do. > > I absolutely agree that they're inadequate and that additional functionality needs to be provided. > However, changing the way that these two policies behave breaks people who
depend upon their Show quoted text
> current behavior.
It's a lowest severity, unconfigurable policy. I don't think anyone depends on this undocumented, untested feature of MixedCase. Even if they do, perlcritic is a program used and interpreted by humans who can adapt, minute backwards compatibility is not a concern. Policies are routinely added and that causes much more change than this. The refined MixedCase + the new Capitalization policy will enforce the same set of features, and more, than what MixedCase currently does. There will be no net loss of enforcement. $Foo will still be prohibited, by default. ************************** Here's a test file: $ cat ~/tmp/test.plx use strict; my $Foo; my $fooBar; my $foo_bar; my $Foo_Bar; Here's the current perlcritic: $ perlcritic --include=NamingConventions ~/tmp/test.plx Mixed-case variable name(s) [NamingConventions::ProhibitMixedCaseVars] at /Users/schwern/tmp/test.plx line 3, near 'my $Foo;' Mixed-case variable name(s) [NamingConventions::ProhibitMixedCaseVars] at /Users/schwern/tmp/test.plx line 4, near 'my $fooBar;' Mixed-case variable name(s) [NamingConventions::ProhibitMixedCaseVars] at /Users/schwern/tmp/test.plx line 6, near 'my $Foo_Bar;' And with my patches: $ perl -Ilib bin/perlcritic --include=NamingConventions ~/tmp/test.plx Capitalization [NamingConventions::Capitalization] at /Users/schwern/tmp/test.plx line 3, near 'my $Foo;' Mixed-case variable name(s) [NamingConventions::ProhibitMixedCaseVars] at /Users/schwern/tmp/test.plx line 4, near 'my $fooBar;' Capitalization [NamingConventions::Capitalization] at /Users/schwern/tmp/test.plx line 6, near 'my $Foo_Bar;' As you can see, the same set of names are prohibited. Just now they use the right reasoning and PBP chapters. Show quoted text
> I believe that these policies should be left as-is and a new, more capable policy > with an appropriate name should be created, as in the one you wrote.
I don't like to make decisions based on belief. Let's lay out the arguments. I'm obviously biased, so I invite you to flesh out the arguments against. Arguments for splitting Capitalization from ProhibitMixedCase: * PBP, perlstyle and most of CPAN agree on a camelCase prohibition. PBP and perlstyle disagree on how to capitalize. CPAN is split. * camelCase can be increased in severity, since it's widely reviled in Perl. * camelCase is very clear cut (you allow it or you don't) while capitalization policies are complex and will require configuration. * "Mixed case" widely refers not to any mixing of upper and lowercase letters, but just camelCase (interword separation). All examples use multi-word names. It would bring the results of ProhibitMixedCase in line with user expectations. * PBP addresses camelCase and capitalization in separate chapters. perlstyle uses separate bullet points. If it's good enough for Damian and Larry... * The reasoning against camelCase is different from the reasoning for lower-case variables and subs. * Neither the PBP chapter on camelCase, nor the MixedCase documentation, nor their tests ever discuss single word variables. * The overall perlcritic "anti-camelCase, pro-lowercase" policy is unchanged. $Foo remains prohibited by default. * If ProhibitMixedCase were allowed to remain as is, you would have to configure two policies in order to take control of capitalization. * perlcritic can point the user to the correct reason in PBP, rather than pointing them at a spread of possible reasons. Arguments against: * Elliot defines "mixed case" to mean any mixing of upper and lower case letters. [1] * It changes an existing policy that somebody might depend on. [1] I do not mean this as an ad hominem attack, but this has been your argument with no counter to the evidence that the rest of the world uses the term differently. -- 87. If the thought of something makes me giggle for longer than 15 seconds, I am to assume that I am not allowed to do it. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Thu, 28 Aug 2008 22:17:36 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Jeffrey Thalhammer <jeff [...] imaginative-software.com>
Show quoted text
> Queue: Perl-Critic > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=38673 > > > Attached is a patch for a basic Capitalization policy following PBP > Chapter > 3.6 the best I could.
This is an excellent start. Although I do have some reservations about combining rules for subroutine, variable, and package into one Policy. With respect to variables, I envision that users could configure the policy to enforce one of three capitalization styles (lowercase, uppercase, uppercase-first) for each of the different types of variables (package, lexical, file-scoped lexical). I admit, it would be really strange to write lexicals in ALL CAPS. But once you have a way to enforce all those different styles, extending them to all the different types of variables seems pretty easy. Or do you think I'm being too zealous? Detecting constants will be hard, but not impossible. Basically, we'll have to look for "use constant" or "Readonly::*" and then parse the statement manually. Since those are entirely different from a PPI::Statement::Variable, it might make sense to handle constants in a separate policy with it's own applies_to() method. But I'm not certain of that. Also, detecting variable declarations *inside* certain types of other statements is tricky. Some examples: open my $foo, '<', $file; foreach my $foo (@list){} PPI lexes each variable declaration in there as a bareword "my" folowed by a symbol "$foo". In this case, I think we'd need to search for any "my" bareword that isn't a child of a PPI::Statement::Variable, and then grab the variable name from its sibling element. You could also argue that this is a bug in PPI. I hope to hack on this a bit more over the weekend. Thanks for cooking this up Schwern! -Jeff
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Thu, 28 Aug 2008 23:28:51 -0700
To: bug-Perl-Critic [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Jeffrey Thalhammer via RT wrote: Show quoted text
> This is an excellent start. Although I do have some reservations > about combining rules for subroutine, variable, and package into one > Policy.
I figure if you care about how you capitalize one type you're going to care about the rest, so why split it up? I think it will come down to how awkward it is to customize the behavior. Show quoted text
> With respect to variables, I envision that users could configure the > policy to enforce one of three capitalization styles (lowercase, > uppercase, uppercase-first) for each of the different types of > variables (package, lexical, file-scoped lexical).
Is it worth differentiating between package variables and file-scoped lexicals? Show quoted text
> I admit, it would be really strange to write lexicals in ALL CAPS. > But once you have a way to enforce all those different styles, > extending them to all the different types of variables seems pretty > easy. Or do you think I'm being too zealous?
There's no point in restricting the possible combinations. I've cooked some utility functions to detect whether an element is inside a subroutine which will allow detection of subroutine scoped lexicals. Patch attached. -- If at first you don't succeed--you fail. -- "Portal" demo
--- lib/Perl/Critic/Utils/PPI.pm (revision 60234) +++ lib/Perl/Critic/Utils/PPI.pm (local) @@ -21,6 +21,8 @@ is_ppi_expression_or_generic_statement is_ppi_generic_statement is_ppi_statement_subclass + is_ppi_in_subroutine + is_ppi_subroutine_declaration ); our %EXPORT_TAGS = ( @@ -68,6 +70,40 @@ return $element_class ne 'PPI::Statement'; } +#----------------------------------------------------------------------------- + +sub is_ppi_in_subroutine { + my $elem = shift; + + return unless $elem; + return unless $elem->parent; + + my $insub = 0; + while( $elem = $elem->parent ) { + if( is_ppi_subroutine_declaration($elem) ) { + $insub = 1; + last; + } + } + + return $insub; +} + +#----------------------------------------------------------------------------- + +sub is_ppi_subroutine_declaration { + my $elem = shift; + + return unless $elem; + + return 1 if $elem->isa("PPI::Statement::Sub"); + return 1 if $elem->isa("PPI::Statement") and + $elem->first_element and + $elem->first_element->content eq 'sub'; + return 0; +} + + 1; __END__ @@ -115,6 +151,16 @@ parameter is not L<PPI::Statement|PPI::Statement>. +=item C<is_ppi_subroutine_declaration( $element )> + +Is the $element a named or anonymous subroutine declaration? + + +=item C<is_ppi_in_subroutine( $element )> + +Is the $element inside a subroutine? + + =back --- t/05_utils_ppi.t (revision 60234) +++ t/05_utils_ppi.t (local) @@ -12,7 +12,7 @@ use warnings; use Readonly; -use Test::More tests => 67; +use Test::More tests => 82; #----------------------------------------------------------------------------- @@ -40,6 +40,8 @@ PPI::Statement::Unknown }; + use_ok('PPI::Document'); + use_ok('PPI::Token::Word'); foreach my $class (@PPI_STATEMENT_CLASSES) { use_ok($class); @@ -57,6 +59,8 @@ can_ok('main', 'is_ppi_expression_or_generic_statement'); can_ok('main', 'is_ppi_generic_statement'); can_ok('main', 'is_ppi_statement_subclass'); +can_ok('main', 'is_ppi_in_subroutine'); +can_ok('main', 'is_ppi_subroutine_declaration'); #----------------------------------------------------------------------------- # is_ppi_expression_or_generic_statement tests @@ -269,6 +273,90 @@ } #----------------------------------------------------------------------------- +# is_ppi_subroutine_declaration() tests + +{ + my $test = sub { + my($code, $result) = @_; + my $doc; + my $input; + + $doc = PPI::Document->new(\$code, readonly => 1) if defined $code; + $input = $doc->first_element if defined $doc; + + my $name = defined $code ? $code : "undef"; + + local $Test::Builder::Level = $Test::Builder::Level + 1; + is( + !!is_ppi_subroutine_declaration( $input ), + !!$result, + "is_ppi_subroutine_declaration(): $name" + ); + }; + + $test->('sub {};' => 1); + $test->('sub {}' => 1); + $test->('{}' => 0); + $test->(undef, 0); + $test->('{ sub foo {} }' => 0); + + # These may be controversial. It really depends on what's useful. + $test->('sub foo;' => 1); + $test->('BEGIN {}' => 1); +} + +#----------------------------------------------------------------------------- +# is_ppi_in_subroutine() tests + +{ + my $test = sub { + my($code, $transform, $result) = @_; + my $doc; + my $input; + + $doc = PPI::Document->new(\$code, readonly => 1) if defined $code; + $input = $transform->($doc) if defined $doc; + + my $name = defined $code ? $code : "undef"; + + local $Test::Builder::Level = $Test::Builder::Level + 1; + is( + !!is_ppi_in_subroutine( $input ), + !!$result, + "is_ppi_in_subroutine(): $name" + ); + }; + + $test->(undef, sub {}, 0); + + $test->('my $foo = 42', sub {}, 0); + + $test->('sub foo { my $foo = 42 }', + sub { + my $doc = shift; + $doc->find_first("PPI::Statement::Variable"); + }, + 1 + ); + + $test->('sub { my $foo = 42 };', + sub { + my $doc = shift; + $doc->find_first("PPI::Statement::Variable"); + }, + 1 + ); + + $test->('{ my $foo = 42 };', + sub { + my $doc = shift; + $doc->find_first("PPI::Statement::Variable"); + }, + 0 + ); +} + +#----------------------------------------------------------------------------- # ensure we run true if this test is loaded by # t/05_utils_ppi.t_without_optional_dependencies.t
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sun, 28 Sep 2008 20:05:58 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
I started with Schwern's Capitalization code, but it's basically been completely rewritten. Michael G Schwern via RT wrote: Show quoted text
> Jeffrey Thalhammer via RT wrote:
>> This is an excellent start. Although I do have some reservations >> about combining rules for subroutine, variable, and package into one >> Policy.
> > I figure if you care about how you capitalize one type you're going to care > about the rest, so why split it up? I think it will come down to how awkward > it is to customize the behavior.
I think it should all be in one place as well, and that's the way it is with the new policy. Show quoted text
>> With respect to variables, I envision that users could configure the >> policy to enforce one of three capitalization styles (lowercase, >> uppercase, uppercase-first) for each of the different types of >> variables (package, lexical, file-scoped lexical).
> > Is it worth differentiating between package variables and file-scoped lexicals?
I did. Name categories: * Packages * Subroutines * Globals * File scope lexicals * Scoped lexicals at the file level: { my $x; sub a {$x} sub b {$x} } * "Local" lexicals * Constants (constant pragma or Readonly, probably need to include constant subs) Show quoted text
>> I admit, it would be really strange to write lexicals in ALL CAPS. >> But once you have a way to enforce all those different styles, >> extending them to all the different types of variables seems pretty >> easy. Or do you think I'm being too zealous?
> > There's no point in restricting the possible combinations.
Cooked in possibilities: all upper, all lower, initial upper, initial lower (a la variables/methods in Java), and no restriction. I thought about adding something about allowing or disallowing underscores (if you wanted CamelCase), but decided it was better to allow specifying a regex. Also, you can specify multiple regexes for names to exempt from whatever your rule for a particular type is. The only defaults for these are for global variables: \$VERSION @ISA @EXPORT(?:_OK)? %EXPORT_TAGS. The POD needs to be updated, I need to change the tests for this from being static to being generated, etc., but have a look at http://perlcritic.tigris.org/source/browse/*checkout*/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Policy/NamingConventions/Capitalization.pm
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sat, 13 Dec 2008 20:14:59 -0600
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Elliot Shank via RT wrote: Show quoted text
> I started with Schwern's Capitalization code, but it's basically been > completely rewritten.
[chop] Show quoted text
> Cooked in possibilities: all upper, all lower, initial upper, initial > lower (a la variables/methods in Java), and no restriction. I > thought about adding something about allowing or disallowing > underscores (if you wanted CamelCase), but decided it was better to > allow specifying a regex. > > Also, you can specify multiple regexes for names to exempt from > whatever your rule for a particular type is. The only defaults for > these are for global variables: \$VERSION @ISA @EXPORT(?:_OK)? > %EXPORT_TAGS.
It doesn't handle "use vars", bareword file handles, or constant subroutines, but I think it's good enough to release. The question is whether it should really be called "Capitalization", given that it can do this (example from the POD): ----- For example, if you want all local variables to be in all lower-case and global variables to start with "G_" and otherwise not contain underscores, but exempt any variable with a name that contains "THINGY", you could put the following in your F<.perlcriticrc>: [NamingConventions::Capitalization] local_lexical_variables = :all_lower global_variables = G_(?:(?!_)\w)+ global_variable_exemptions = .*THINGY.* ----- However, I'm not sure of what to call it other than RequireNamesFollowStandards.
Subject: Re: [rt.cpan.org #38673] NamingConventions::ProhibitMixedCaseVars denies $Foo
Date: Sat, 13 Dec 2008 20:14:59 -0600
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
Elliot Shank via RT wrote: Show quoted text
> I started with Schwern's Capitalization code, but it's basically been > completely rewritten.
[chop] Show quoted text
> Cooked in possibilities: all upper, all lower, initial upper, initial > lower (a la variables/methods in Java), and no restriction. I > thought about adding something about allowing or disallowing > underscores (if you wanted CamelCase), but decided it was better to > allow specifying a regex. > > Also, you can specify multiple regexes for names to exempt from > whatever your rule for a particular type is. The only defaults for > these are for global variables: \$VERSION @ISA @EXPORT(?:_OK)? > %EXPORT_TAGS.
It doesn't handle "use vars", bareword file handles, or constant subroutines, but I think it's good enough to release. The question is whether it should really be called "Capitalization", given that it can do this (example from the POD): ----- For example, if you want all local variables to be in all lower-case and global variables to start with "G_" and otherwise not contain underscores, but exempt any variable with a name that contains "THINGY", you could put the following in your F<.perlcriticrc>: [NamingConventions::Capitalization] local_lexical_variables = :all_lower global_variables = G_(?:(?!_)\w)+ global_variable_exemptions = .*THINGY.* ----- However, I'm not sure of what to call it other than RequireNamesFollowStandards.
Elliot: So are we now done with all the capitalization-related policies? Can I make this as "resolved" ? Schwern: Have you tried the Capitalization policy in Perl-Critic-1.094001? Does it meet your needs? -Jeff
I haven't heard any complaints, so I'm marking this as "resolved".