PowerShell
PowerShell copied to clipboard
Allow use of attributes before the function definition
Summary of the new feature / enhancement
PowerShell allows you to define functions like this:
function MyFunction ($param1, $param2)
{}
and that syntax is great for small internal functions you use inside a module. Unfortunately there's no way to add attributes to such functions. You need to move the parameters inside the function, add the param keyword and add the attributes to that param block instead.
This is also a little strange for functions that take no parameters or functions that exclusively use dynamic parameters because you need to add that empty param block if you want to assign any attributes.
Proposed technical implementation details (optional)
This is the syntax I expect to work:
[OutputType([string])]
function MyFunction ($param1, $param2)
{
}
Generally we advise people to write a param() block , and if you do
type function:\myFunction you'll see that the syntax of a script block contains Param(), and the function statement prepends something in () to the statement block with param
Introducing new alternative syntax for something which already works allows someone to write code which should work with older versions in a way that doesn't
Syntax-wise this
[OutputType([string])]
function MyFunction ($param1, $param2)
is something we do see in c# , and we do use it for PowerShell variable / parameter declarations. To my eye it jars to have something which affects a statement before the statement keyword. That could be fixed, but the previous objection remains - time spent working on something which guides to style would tell people not to use would probably be seen as wasted.
In my opinion, such a simplified syntax as function ($arg1, $arg2) {} is used for embedding in scripts when the type of output data is precisely known. This is not even a function, as a purpose, but a subroutine for organizing the structure of the script.
I believe OutputType is only for cmdlets.
I believe OutputType is only for cmdlets.
Actually when I was testing it I found you can attach it a variable. Why anyone would is another question And [outputType([String])] Param()
as the first two lines in a PS1 file works.
@jhoneill I didn't realize there were such recommendations. The default "function" snippet that ISE has uses that syntax, it's only the advanced function snippets that use the param block.
Even though it's just 1 more line, it feels like unnecessary bloat to define the param block inside the function like that.
@237dmitry Yes, that's exactly how I use it but I also want tab completion to work and I need the OutputType attribute to give the completion code enough info to give meaningful completions.
@MartinGC94
I've been steering people to this for years, https://github.com/PoshCode/PowerShellPracticeAndStyle it's the defacto style guide and https://github.com/PoshCode/PowerShellPracticeAndStyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md says use [cmdletbinding()] everywhere, which requires a param () inside the statement block, although in one place this guide does show non-advanced functions the parameters outside. I'm sure I didn't just morph "be advanced cmdlet-ready" into "only use the param() syntax" myself - I've been saying it for so long I've forgotten the origin.
On snippets - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_language_keywords?view=powershell-7.2 says begin / process / end and param are - as language keywords - written with an lower-case letter (like function , for , if , while etc). But the the ISE snipets capitalize them (and don't follow the layout rules which are built into the VS code extension - "don't put { on it's own line, in a statement, any more than you would in a foreach-object or where object cmdlet")
So I wouldn't take the snippets as gospel on style, (code in help is gloriously inconsistent).
In a .ps1 you write param ()
In a scriptblock passed to invoke-command or & you write param()
A function statement can build a script block to be saved to function: by adding parameters, as a param(), to the statement block (the bit between { and } in a statement is not a script block, but a function is a saved script block). I've always seen this ability as a crutch for people who don't write code as PowerShell, but are trying to write JavaScript, or VBS or C# in PowerShell. It's often a signpost that what follows will need re-writing.
But the block in the function statement should be the whole of the definition (and that means comment based help INSIDE which is also wrong in the snippets). That way we can remove the function line and the final } and make it a ps1 file or replace the starting part with { and use it as a script block or go in the other direction just as simply.
GitHub
The Unofficial PowerShell Best Practices and Style Guide - GitHub - PoshCode/PowerShellPracticeAndStyle: The Unofficial PowerShell Best Practices and Style Guide
GitHub
The Unofficial PowerShell Best Practices and Style Guide - PowerShellPracticeAndStyle/Code-Layout-and-Formatting.md at master · PoshCode/PowerShellPracticeAndStyle
Describes the keywords in the PowerShell scripting language.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.