The question is why choosing such a different syntax?
I understand that PowerShell is shell based language, I can read the PowerShell Grammar.
But ultimately, I am going to end up writing a lot of code and the question is?
Is my code as clear as if I was writing in Python or JavaScript. I do not think so.
Not to mention the following samples:
if ( f1 1 2 -and f2 3 4 ) { }First, if you are new to PowerShell, you will have difficulties understanding this code. Then once you think you know PowerShell, this code will not fail and will not do what you thought it would do.
What about the classical calling a function and not passing the arguments the PowerShell way. Once again it does not fail, it just behave as expected, except that is not what you are used to and for a moment you forgot to PowerShell grammar.
function f1($p1, $p2) { } f1 1,2And now you have a bug or two in your code.
Unit tests: PowerShell is about automating and configuring Systems. There is not way you can write unit tests for that. Do I have to mock up the all Windows operating system.
Interesting remarks from John D. Cook from his blog post PowerShell gotchas, which summarize it well
PowerShell is both a shell and a scripting language, but first of all it is a shell.
This post is about some of the weirdest stuff, I faced while working with PowerShell, and
some workarounds.
some workarounds.
Function returning an array of one string
When a function returns an array containing only one string, PowerShell will convert the returned value into one string.function CreateArray() { $myArray = @() # Create an empty array of object $myArray += "Blue" # Add a string to the array return $myArray } cls $myArray = CreateArray Write-Host "myArray is $($myArray.GetType().Name)" Write-Host "myArray.len is $($myArray.Length)" Write-Host "myArray: $myArray"Output:
myArray is String myArray.len is 4 myArray: BlueTo force the value to be returned as an array, add a coma just after the return.
(Sound like a typo to me)
function CreateArray() { $myArray = @() $myArray += "Blue" return , $myArray # Force to return an array } cls $myArray = CreateArray Write-Host "myArray is $($myArray.GetType().Name)" Write-Host "myArray.len is $($myArray.Length)" Write-Host "myArray: $myArray"
Calling one or more functions with parameters from an if
That should sound like a no brainer, but because in PowerShell what follow an if is not an expression that must evaluate to a bool , but is defined in the grammar as pipeLineRule then this can be dangerous.Reminder: When calling a function in PowerShell
- There is no need for ( )
- Parameters are separated by a space
function f1($p1, $p2) { Write-Host "f1 `$p1: $p1, `$p2: $p2" return $true } function f2($p1, $p2) { Write-Host "f2 `$p1: $p1, `$p2: $p2" return $false } cls if ( f1 1 2 ) { " f1 returned true" } # THIS SYNTAX WILL RUN, BUT WILL NOT CALL f2 3 4 if ( f1 1 2 -and f2 3 4 ) { " f1 and f2 returned true" } else { " f1 and f2 returned false" } # You must wrap each function call into a () if ( (f1 1 2) -and (f2 1 2) ) { " f1 and f2 returned true" } else { " f1 and f2 returned false" } # Negating the result of a function. You must wrap each function call into a () # At least here if you forget the (), it will not compile if ( -not(f1 1 2) ) { " f1 returned false" } else { " f1 returned true" }Output:
f1 $p1: 1, $p2: 2 f1 returned true f1 $p1: 1, $p2: 2 f1 and f2 returned true f1 $p1: 1, $p2: 2 f2 $p1: 1, $p2: 2 f1 and f2 returned false f1 $p1: 1, $p2: 2 f1 returned true
Creating object on the fly
Sometime I missed the simplicity of JavaScript.var o = { Name : "Rene", Age : 48 };The PowerShell way
# Out of the box $o = New-Object -TypeName PSObject -Property @{ Name = "Rene"; Age = 48 } # With a helper function function CreateObject($properties) { return New-Object -TypeName PSObject -Property $properties } $o = CreateObject @{ Name = "Rene"; Age = 48 }
Object literal
Powershell does not support the notion of Object Literal like in JavaScript, but support Dictionary and Array literal. It is close. Here is a code that convert a dictionary into an object though it does not supported nested objectvar o = { Name : "Rene", Age : 32, Debug : true, Unknown: null, Country : { Name : "Guatemala", }, Numbers : [1, 2, 3, 4] };The PowerShell way
$o = @{ Name = "Rene" Age = 32 Debug = $true Unknown = $null Country = @{ Name = "Guatemala" } Numbers = @( 1, 2, 3, 4 ) }
No comments:
Post a Comment