Closed bryanwinstead closed 7 years ago
I would include such a guideline. PowerShell help is an example of using all kind of styles mixed. And it does not look neat, as a result. To me, at least. Also, as far as I follow my own rules, "imported code" often should be adjusted (boring).
For built-in names I simply follow the styles suggested by TabExpansion. For other names I use similar styles. It is mostly PascalCase except names of aliases (lower case) and local variables (camelCase).
Perhaps it makes sense to use PascalCase even for local variables if they are supposed to be used in child scopes without passing them as parameters.
I normally use PascalCase myself. Now that my personal style guide for my projects kind of became by popular demand a communist one I need to figure best way to handle all of this and re-structure some stuff for easier contributions.
Sent from my iPhone
On May 17, 2015, at 11:55 AM, bryanwinstead notifications@github.com wrote:
Since PEP-8 is specifically called out (and seems to be heavily influencing this document), do we want to develop brace/capitalization guidelines? PowerShell doesn't care, but it's often a big pet-peeve of developers, and I've seen a ton of different styles out there in the wild. Personally, I'm an OTB fan and, for PowerShell at least, I CamelCase everything since that's the Cmdlet naming convention.
— Reply to this email directly or view it on GitHub.
I definitely think we should have one... coming up with it is going to be challenging though. I almost 100% use PascalCase actually. Perhaps it makes sense to list out all the various items that might have different naming conventions, and go from there?
PEP 8 calls out these things, so it makes sense to start here I think:
Since nobody else is going first, here are my thoughts. Any disagreement?
lowercase (rationale: no language other than VB uses mixed case keywords?)
lowercase (same reason as above)
PascalCase (rationale: readability)
PascalCase
PascalCase
PascalCase
$PascalCase
$camelCase (see for example: $args
and $this
)
PascalCase (Verb-NounName)
PascalCase
PascalCase (VerbNounName, just without the dash)
$PascalCase
I have doubts about Comment Help Keywords, and about is Constants.
Comment help keywords have frequently been written in ALLCAPS to make them stand out more (the same is true for the process block keywords) one need only search poshcode to see examples of this. Personally, I think that if the indentation rules are followed, all of these keywords would be indented one level less than everything else around them, so there is no reason to capitalize them to make them stand out.
Constants are basically global variables which should not be changed. Hypothetically we can enforce non-changing on them. Note that Microsoft has several such constants and follows NO CONVENTION AT ALL: $Error, $ExecutionContext, $PID, $PSVersionTable, $ShellId, $Host, $PSHOME, $true, $false
I would argue that true and false are special, and that other than that, these are all PascalCase except $PSHOME
which obviously should be $PSHome
:wink: -- Hypothetically I'd be willing to use some other naming convention (like $ALL_CAPS or $Under_Score) but they would forever clash with the constants Microsoft has created ;-)
Private Function Names (in modules) PascalCase (but without the dash)
I do not think dash should be excluded. There is a reason to use Verb-Noun even for internal functions. See this case Conflict-with-aliases. Verb-Noun function names will unlikely clash with aliases.
Keywords are forgotten. Try/try
, Begin/begin
, and etc. What about dynamicparam
?
We've been excluding the dash from internal functions because it guarantees you won't accidentally export them (since you would see a warning).
I disagree with your contention that VerbNoun aliases are more likely than Verb-Noun aliases -- why do you say that? I can't find any non-contrived example of aliases that aren't initializations (i.e.: gci for Get-ChildItem) except when users are deliberately aliasing verb-noun commands to other verb-noun commands, and the built-in PowerShell verb aliases (e.g.: foreach, compare, where).
Keywords are a very interesting debate -- and comment help keywords. I'll add my opinions to the post above.
@Jaykul
I disagree with your contention that VerbNoun aliases are more likely than Verb-Noun aliases
I did not say that. Where is it? I will rephrase then because I disagree with this statement as well.
@nightroman you said:
There is a reason to use Verb-Noun even for internal functions. ... Verb-Noun function names will unlikely clash with aliases.
By the way, thanks for sticking around and debating this -- I keep worrying that I'm going to chase people off by defending my opinions :frowning:
I still do not see how you converted this into "VerbNoun aliases are more likely than Verb-Noun aliases". It's a different statement. If you disagree with my original statement then it's fine.
Can you give some examples of internal function names that you recommend/use?
I can see both arguments for private functions, but tend to go @nightroman's way in practice:
Cheers!
There are very few exceptions where I create a function that does not follow the Verb-Noun syntax. My arguments for always using Verb-Noun, even for internal commands are:
I think that's about it. I don't agree at all that it is a good decision to promote functions without Verb-Noun syntax just because they are internal. The advantages of having one style for all functions that is consistent and promotes best practices outweighs any other benefit that you might get from having a different name syntax for internal functions. Besides, there are better ways to organize internal vs. external so that there is no ambiguity: a "functions" folder and a "helpers" folder.
Kirk Munro Poshoholic, Microsoft MVP Blog http://poshoholic.com/ | Twitter http://twitter.com/poshoholic | LinkedIn http://ca.linkedin.com/in/kirkmunro | GitHub http://github.com/KirkMunro | Facebook http://www.facebook.com/#%21/kirk.munro
Need a PowerShell SME for a project at work? Contact me http://poshoholic.com/contact-me/!
On Thu, May 28, 2015 at 8:15 PM, Warren F. notifications@github.com wrote:
I can see both arguments for private functions, but tend to go @nightroman https://github.com/nightroman's way in practice:
- Verb-Noun is more consistent with other functions and cmdlets
- Verb-Noun is less likely to be mistaken for an executable
- There are other ways to assure private functions are not emitted
Cheers!
— Reply to this email directly or view it on GitHub https://github.com/PoshCode/PSStyleGuide/issues/17#issuecomment-106638975 .
All of the capitalization rules you mentioned here pretty much matches what I do anyway.
As for internal functions, I'm kind of all over the place. Sometimes they're Verb-Noun, sometimes not. I often have functions to give names to Boolean expressions, such as if (ShouldDoSomething @params) { ... }
, which seem more clear to me than using some sort of Test-Noun
name just to follow that pattern.
Exported functions are cmdlets, and should be treated as such. Internal functions may be cmdlet style, but don't have to be.
For what it's worth, I'm pretty sure that Kirk and I are going to vigorously disagree about how to organize code in modules too, because this whole idea of "a functions folder" scares me :wink:
I don't really need to argue the point, if we can agree not to have a separate rule for them. My projects can just add that rule, and you can just frown when you see them ;-)
In practice, on PoshCode projects we have been using VerbNoun rather than Verb-Noun for internal functions. We still use valid verbs and logical singular nouns, but simply ommit the -
If you care about my reasoning, let me just say there are a lot of good reasons to have internal private functions. There are a lot of good reasons to want it to be very obvious which functions those are (without having to go look for the definition of the function).
All of the same reasons that in C we prefixed internals with an _underscore, and in VB people used "my" or in c# we use camelCase. You can google any of those, or look at the fxCop explanations, but to put it simply: having the name be slightly different provides a clue to other developers (and future developers) that this is internal and should not be called by outsiders nor exported.
For one thing, we definitely test internal code differently (less rigorously) than external code, because we assume it's being tested as part of the code that's calling it, and because we are not worried about users passing it the "wrong" values and getting unexpected results.
For that reason, we want there to be a barrier to exporting them that is slightly steeper than just changing our minds and adding the function name to the list (although obviously search-and-replace for VerbNoun is a really trivial speed bump, it at least makes sure you don't do it accidentally, by omission).
@nightroman as an example, @jrich523 just wrote a function in the PSGit module called WriteMessage. It's an internal function that wraps a little functionality around "extra" output via Write-Host. We would never export it, because it's not generally useful outside our module. We could call it Write-Message, but then you wouldn't know that when you saw it.
@Jaykul I see, you promote VerbNoun style. Probably it is approximately as safe as Verb-Noun in order to avoid clashes with aliases. But the original guideline (that made me to make a comment) is
PascalCase (but without the dash)
It does not say anything about VerbNoun style. To me it sounds like "Pascal style without dash". It includes Test
, Assert
, Task
, and etc. Such names are likely to clash with aliases. I have seen such issues and decided to use Verb-Noun even for internal functions. Since then I do not see clashes yet. Hence my statement
Verb-Noun function names will unlikely clash with aliases.
The approach with Verb-Noun is not 100% safe of course. But it excludes too simple names like Test
, Assert
, Task
, and etc.
I hope this explains my statement. Once again, it was not "VerbNoun aliases are more likely than Verb-Noun aliases".
@nightroman gotcha. Yeah, even though I like leaving out the dash on internals (I love doing Export-ModuleMember -Function *-*
), I definitely think they should still follow the VerbNoun convention, and I thought I had written that above. I'll edit that while I wait to see if we can all agree to just remove that rule completely ;-)
I would remove the rule about internal functions at this point.
As for
Export-ModuleMember -Function *-*
, actually we did not (did we?) mention yet another rule which is even sort of official. Ideally, exported module functions should be Verb-PrefixNoun, not just Verb-Noun. In this case
Export-ModuleMember -Function *-Prefix*
solves the problem of accidental export of internal functions. If we use Verb-Noun for internal functions without a prefix then they will not be exported by mistake by the above command.
Here is the example of a module which follows these rule - FarGit. In the end you can see a bunch of internal Verb-Noun functions. Exported functions are called Verb-FarGitNoun. And the last command is
Export-ModuleMember -Function *-FarGit*
Wow I step away for a few days and conversation blows up. Couple of thoughts:
Export-ModuleMember -Function *-*
is just a benefit.if($true) {
}
if($true){
}
if($true)
{
}
I like if($true) {
myself.
@Jaykul, on the "functions" folder vs "helpers" folder, I'm not exactly sure how I ended up with those names, I have recently considered changing that to public/private, respectively. Regardless I'm not such a vigorous disagree-er on all topics, just some.
For module layout and internal function names, reading all of these comments is actually really helpful, and I adjust my perspective when it seems like a good idea to do so. And while I lean torwards Verb-Noun names, I do create some functions that don't contain dashes. But I'm trying to build more framework-like modules, so for something like WriteMessage (haven't looked at what it does), I'd be looking at that and wondering if I should have a separate module for that which PSGit takes a dependency on, and which also exports that function so that PSGit and others can leverage the additional value it adds. Or I would consider making it a snippet for SnippetPx if it's simply something that doesn't really warrant an external function but helps keep code dry and adds value.
I personally find discussions like this highly valuable because I never have time to look at other module designs and figure out what parts of those designs I want to borrow/steal.
Kirk Munro Poshoholic, Microsoft MVP Blog http://poshoholic.com/ | Twitter http://twitter.com/poshoholic | LinkedIn http://ca.linkedin.com/in/kirkmunro | GitHub http://github.com/KirkMunro | Facebook http://www.facebook.com/#%21/kirk.munro
Need a PowerShell SME for a project at work? Contact me http://poshoholic.com/contact-me/!
On Fri, May 29, 2015 at 3:45 AM, bryanwinstead notifications@github.com wrote:
Wow I step away for a few days and conversation blows up. Couple of thoughts:
- Module organization - should this be part of a separate discussion (best practices rather than style guidelines?)
- I think we should have a rule for private/helper module functions. If only to, as mentioned, provide some easy delineation for other people. The ability to Export-ModuleMember -Function - is just a benefit.
- I personally really like the idea of module Cmdlet prefixes. Should maybe be part of the module organization/best practices discussion?
- I think @Jaykul https://github.com/Jaykul's list is what I see most common. I don't personally like the distinction between local variable names and "global" (what is global in this context? $global:? module level?) variable names, but I know it can be useful.
- I also don't like lowercase keywords although I'm 100% in the minority there and have no hope of gaining traction.
- I like all caps "constants" a lot, but the style clash with Microsoft is probably going to cause some friction. Their lack of consistency doesn't mean we should as well though.
- One other thing I just thought of... what's everyone's thoughts on quoting parameters? Only when necessary seems to be what I see most often, but that causes an inconsistency. I like quoting parameters all the time.
— Reply to this email directly or view it on GitHub https://github.com/PoshCode/PSStyleGuide/issues/17#issuecomment-106730369 .
Regarding Prefixes -- let's have a separate thread. #23
Module Organization is #22
@bryanwinstead I blame you for combining two issues in one discussion. :stuck_out_tongue_closed_eyes: I'm moving Braces to #24
Hypothetically, we can use $ALL_CAPS
for constants even though Microsoft doesn't -- especially since the language isn't case sensitive, and we can even refer to their variables that way. However, as a general rule "Microsoft does it that way" is an influential argument, but "Bryan does it that way" isn't -- so we need to agree there's a worthwhile reason :smile:
The same thing goes for "global" variables (I'll admit I was thinking of "Module scope" not actually global, so perhaps we should have two categories there -- but I suspect that either way "Microsoft uses PascalCase" is going to trump my feeling that (like internal function names) they ought to have names which show what they are.
In particular, I think the case-insensitive nature of the language means that distinct capitalization schemes for different types of variables aren't helpful enough. Since capitalizing it two different ways in your script won't be obvious without a LINTer, having written it one way in one place doesn't help you remember to write it that way everywhere, so it's easier to just always use PascalCase.
Hmm, wish you could reply to a specific post on GitHub. Anyway, I agree 100% with the @Jaykul proposal from two days ago.
Yeah @rkeithhill! Maybe we need to set up a discourse server for this. They keep a single thread, but track replies so you can see them inline too.
Or maybe ... I was talking to @jrich523 about writing a tiny webservice that could edit the top issue (basically edit the first post in the issue) to create a graph to build/measure consensus - not sure how to measure it, maybe if you typed like: +1 [@Jaykul](#issuecomment-106124942)
+1 @Jaykul
And it could track any +1 or -1 and the id and figure out which post has the most agreement ...
Considering most of this has been broken out into separate issues, (plus the fact that we have reactions for tracking votes now, but this thread pre-dates them), I find this confusing. I don't think there's anything left in this thread other than the long fruitless discussion about whether it's ok for people to name private things however they like. I'm going to assert that remains without consensus, and close this.
If anyone feels there's anything remaining not in another issue, feel free to open a new issue.
Since PEP-8 is specifically called out (and seems to be heavily influencing this document), do we want to develop brace/capitalization guidelines? PowerShell doesn't care, but it's often a big pet-peeve of developers, and I've seen a ton of different styles out there in the wild. Personally, I'm an OTB fan and, for PowerShell at least, I CamelCase everything since that's the Cmdlet naming convention.