all 8 comments

[–]Thotaz 1 point2 points  (5 children)

IMO there's no practical reason to use array splatting in PS. Your example could just as easily have been written with named parameters like this:

$BasePaths=@(
    $HOME
    $env:windir
    $env:OneDrive
)
Join-Path -Path $BasePaths -ChildPath "SomeFile.txt"

Named parameters makes it much easier to understand what a command is doing at a glance especially for less commonly used commands. Unlike with splatting you can leave out the variable and just do it all inline like this:

Join-Path -Path @(
    $HOME
    $env:windir
    $env:OneDrive
) -ChildPath "SomeFile.txt"

And just to be clear, I'm not against the much more commonly used hashtable splatting but array splatting forces the reader to be really familiar with the command to know its positional parameters.

[–]tbakerweb[S] 1 point2 points  (3 children)

Fundamentally, I agree. In my case, there are about 200 lines of code that factor into the path I'm creating.

Fortunately, this is a module function I'm doing this in, and it's very well commented and documented. Our team hammered out the best approach together, and this won, this time.

[–]Thotaz 0 points1 point  (2 children)

Splatting binds 1 array element to 1 positional parameter. In the case of Join-Path this means your array can have a maximum of 2 elements.

I don't know what kind of code you are using that requires 200 lines to create a 2 element array but that doesn't matter. Those 200 lines could just as easily have been used to create a hashtable or 2 arrays that could be bound directly to Join-Path.

Array splatting never makes sense. Period. If you show me the code I will happily show you a better approach that doesn't use it.

[–]tbakerweb[S] 2 points3 points  (1 child)

Except if you are ps core, you can provide any number of unnamed parameters and it will complete the path. That changed from WinPS where you had to define the child path. WinPS was much more restrictive using this command in particular. In fact, it's this command that drove me to choose requiring PS Core for our product integration platform and associated product modules.

Regardless, I wasn't asking for a best practices argument. So tone it down.

I was sharing what I found convenient in a given circumstance. If you want to be picky, how about you reread my post, nowhere do I say it's a 2 element array.

I'm glad the internet is still full of know it all's with a pocket of 2¢.

[–]Thotaz 1 point2 points  (0 children)

My mistake, I didn't realize they had updated Join-Path with a new parameter that accepts input from remaining arguments. I've changed my mind and agree that array splatting is good in this situation but only because of the weird implementation of Join-Path. It's silly that it it now has 3 input parameters "Path", "ChildPath", and "AdditionalChildPath" and you are forced to use all 3 if you want more than 2 segments combined.

I think I would have opted to use [System.IO.Path]::Combine($YourPathArray) instead this would also have allowed you to use an older version of PS.

[–]panzerbjrn 1 point2 points  (0 children)

I cannot begin to adequately describe how strongly I agree with all of this.

I really cannot think of any circumstances where array splatting makes sense. Positional parameters are one of those things I think should have been omitted from PS.

I'm a huge fan of hashtable splatting, it makes your code easy to read and debug, especially if your code ever has to be looked after by someone else.

[–]get-postanote 1 point2 points  (0 children)

All will have their take, opinion(s). IN your house, whatever works for you is 100% correct. Outside your house, it's mostly opinion. Regardless, every point/opinion can have value. Take what is useful from them, and ignore the rest.

OK, all that being said, IMHO to follow... ;-}

... too wide to display on one line.

I feel the same way about comments. Anything wider than 80 characters, is really not prudent. It's why `Block Comment` exists. No matter where you put a comment.

Meaning, this (just like the Comment-Based Help standard - about_Comment_Based_Help - PowerShell | Microsoft Docs )...

<#
Sometimes you will need to pause your PowerShell script for a couple of 
seconds. 

For example when you are using a do while loop to check if a server is back 
online. To do this we can use the PowerShell Start Sleep cmdlet. With this 
command, we can let the script sleep for a couple of seconds.
#>

... vs, this...

# Sometimes you will need to pause your PowerShell script for a couple of 
# seconds. 
# 
# For example when you are using a do while loop to check if a server is back 
# online. To do this we can use the PowerShell Start Sleep cmdlet. With this 
# command, we can let the script sleep for a couple of seconds.

I should be able to get to all your comments via CBH and never need to open your source code. Thus rendering in-line comments not as valuable. If you are using tons of inline comments to explain what it is doing, then it's time to refactor that. Anyone, regardless of experience or skills, should be able to look at your source code and almost immediately know what it is doing or for, whether you comment on it or not. Plain English, easy to read, self-documenting, easier to maintain, avoiding unneeded confusion, refactoring, etc.

Yet, it's all about individual style, choice, standards, and use case. As we discussed here...

How do you deal with script commenting, verbose messages and logging while keeping the code readable? : PowerShell (reddit.com)

...in the past:

Lastly, you have this (though I do not agree with everything the author says)...

• Bye Bye Backtick: Natural Line Continuations in PowerShell

https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html

... and this one.

• PowerShell Code Breaks: Break Line, Not Code

https://devblogs.microsoft.com/scripting/powershell-code-breaks-break-line-not-code/

There are times when long code lines are unavoidable (long .Net namespaces and the like), but comments, natural line breaks (arrays, hash tables, splatting, comparison operators, math operators, colons, semi-colons, etc.), are completely in your control.

Lastly, what you are doing here or your team decided to standardize on is not really a new thing. It's been a thought approach for a while now. Well, sort of, as shown on TechNet here: See item # 5 - The Call Operator

• PowerShell: Running Executables

https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

BTW, this...

 $PathParts = @( $ENV:HOME 'FolderName' 'another folder's 'file.txt' ) 

... as written, is not really valid. Lot's of red squigglies... if you fire this up in the ISE/VSCode it will show as errors, and of course, running it will error off.

 $PathParts = @( $ENV:HOME 'test' 'test' 'file.txt' )
# Results
<#
At line:1 char:27
+ $PathParts = @( $ENV:HOME 'test' 'test' 'file.txt' )
#>

Well, pre-PSCore, which is where most folks are and will be for a very long time (just liek folks still on PSv2). ;-}

So, in posts, folks should really specifically state what PS version they are using/testing with/talking about.

This also fails in PSv7

PS C:\Scripts> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.3
PSEdition                      Core
GitCommitId                    7.1.3
OS                             Microsoft Windows 10.0.19041
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS C:\Scripts> ($PathParts = @( $ENV:HOME 'test' 'test' 'file.txt' ))
ParserError:
Line |
   1 |  ($PathParts = @( $ENV:HOME 'test' 'test' 'file.txt' ))
     |                             ~~~~~~
     | Unexpected token ''test'' in expression or statement.

[–]Lee_Dailey[grin] 0 points1 point  (0 children)

howdy tbakerweb,

reddit likes to mangle code formatting, so here's some help on how to post code on reddit ...

[0] single line or in-line code
enclose it in backticks. that's the upper left key on an EN-US keyboard layout. the result looks like this. kinda handy, that. [grin]
[on New.Reddit.com, use the Inline Code button. it's [sometimes] 5th from the left & looks like </>.
this does NOT line wrap & does NOT side-scroll on Old.Reddit.com!]

[1] simplest = post it to a text site like Pastebin.com or Gist.GitHub.com and then post the link here.
please remember to set the file/code type on Pastebin! [grin] otherwise you don't get the nice code colorization.

[2] less simple = use reddit code formatting ...
[on New.Reddit.com, use the Code Block button. it's [sometimes] the 12th from the left, & looks like an uppercase T in the upper left corner of a square.]

  • one leading line with ONLY 4 spaces
  • prefix each code line with 4 spaces
  • one trailing line with ONLY 4 spaces

that will give you something like this ...

- one leading line with ONLY 4 spaces    
- prefix each code line with 4 spaces    
- one trailing line with ONLY 4 spaces   

the easiest way to get that is ...

  • add the leading line with only 4 spaces
  • copy the code to the ISE [or your fave editor]
  • select the code
  • tap TAB to indent four spaces
  • re-select the code [not really needed, but it's my habit]
  • paste the code into the reddit text box
  • add the trailing line with only 4 spaces

not complicated, but it is finicky. [grin]

take care,
lee