I ran into a weird problem today. I was banging my head against the wall for a little while before I kind of figured out what is going wrong and how to fix it. If you are like me, you would expect the following code to create an array with two strings:
$foo = "Test" [string[]] @($foo + "_Suffix1", $foo + "_Suffix2")
It even looks like it does. The output is:
Test_Suffix1 Test_Suffix2
But look again. Let’s index into the array:
$foo = "Test" [string[]] @($foo + "_Suffix1", $foo + "_Suffix2")[0]
As you can see it is both elements concatenated together, not two elements:
Test_Suffix1 Test_Suffix2
I fixed it by change the code to the following:
$foo = "Test" [string[]] @("$foo`_Suffix1", "$foo`_Suffix2")
Here the output is different, and correct:
Test_Suffix1
Test_Suffix2
Again, if we index into the array:
$foo = "Test" [string[]] @("$foo`_Suffix1", "$foo`_Suffix2")[0]
Output:
Test_Suffix1
Here is the part that really threw me off:
$foo = "Test" ([string[]] @($foo + "_Suffix1", $foo + "_Suffix2")).GetType() ([string[]] @("$foo`_Suffix1", "$foo`_Suffix2")).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String[] System.Array
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String[] System.Array
You are getting your array.
That made it hard to figure out because the code was actually buried deep in a sequence of calls. In the former, you get an array with everything stuffed into the first element. In the latter, you actually get two elements.
What is really interesting is that given the above, you would think the following would be the same as the code that worked, but in fact it acts like the failing code:
$foo = "Test" [string[]] @($foo + "`_Suffix1", $foo + "`_Suffix2")[0]
Output:
Test_Suffix1 Test_Suffix2
Clearly what I think is going on, is not. Let’s dig in a little further…
See, I was assuming that the _
was throwing the concatenation off somehow. Which stands to reason when you try something like this:
$foo = "Test" [string[]] @("$foo_Suffix1", "$foo_Suffix2")
In which case, the string parser sees those as all one variable.
Let’s try the original with some extra braces:
$foo = "Test" [string[]] @(($foo + "_Suffix1"), ($foo + "_Suffix2"))
Output:
Test_Suffix1
Test_Suffix2
A little more experimentation:
PS C:\> [string[]] @("asfsadf", "asfdsdf") asfsadf asfdsdf PS C:\> [string[]] @("asdf" + "asfsadf", "asfdsdf") asdfasfsadf asfdsdf
So, PowerShell concatenation changes the meaning of the comma. This is going to require further investigation. My hunch is that the +
takes precedence over the ,
and what you are actually doing is passing an array to the concatenation operator.
In other words, what I think is going on is:
[string[]] @(("asdf" + "asfsadf"), "asfdsdf")
But what is actually going on:
[string[]] @("asdf" + ("asfsadf", "asfdsdf"))
Definitely something to be aware of.
Right away despite the fact, there are several various things which will note pad addicts normally look at well before splashing your money. https://imgur.com/a/oqP65KN https://imgur.com/a/iR4tbbA https://imgur.com/a/MKaJSnl https://imgur.com/a/peCr6PJ https://imgur.com/a/aO9jaIK https://imgur.com/a/Nta4wQi https://imgur.com/a/WEtTRvP
ReplyDelete