I was examining some Microsoft PowerShell code in the ARI modules and came across an unusual pattern where a loop's result was assigned to a variable. I'm curious about this method and its benefits. For instance, I noticed something like this:
$tmp = foreach ($1 in $SQLDB) {
# ...
}
$tmp
What does this actually do? To clarify, I tried a simpler version:
$things = @(1, 2, 3, 4, 5)
$tmp = foreach ($thing in $things) {
$x = $thing + 1
}
$tmp -eq $null
This resulted in `$true`, which raised questions for me. Can anyone explain this variable storage in a foreach loop?
4 Answers
What you've referred to as 'foreach as an expression' is a PowerShell technique to efficiently build arrays without unnecessary overhead. Assigning the loop output directly to a variable captures all returned items seamlessly. It might be different if you come from a language that handles loops differently, but it's a neat approach for performance! Just remember, if you want the loop to output, you can’t use an intermediate variable for assignments like `$x =`. Simply let the loop express and capture the results directly!
That clears things up! So I was missing that key output step!
You're right about the line you're looking at. It might be a remnant from older code practices. When you don't output anything from a loop, like you're doing with `$x =`, it doesn’t actually add anything to `$tmp`. You need to output the desired result directly for it to be captured, which probably explains the `$null` you're seeing. You can simply return the final statement to populate `$tmp`. It's a handy technique if done correctly!
So if I output `$obj` instead, would that populate `$tmp` with the right data?
It seems like this pattern returns an array of objects from the database that match certain conditions. Instead of the approach with `$tmp`, you could just initialize an empty array beforehand and use `+=` to add each object during the loop. That’s probably the alternative you were looking for!
That's what I expected too! I skipped the output line in your example.
It's interesting that you're questioning Microsoft's code quality, especially over a syntax feature you might not fully understand. Assigning the results from a loop like that is actually quite common and often recommended. The typical way to do this is by using `foreach ($x in $y) {}` and capturing the output directly. Using `$Res += 'Something'` within a loop is inefficient since it rebuilds the array on each iteration, which is really slow. So, what you found is a solid practice of direct assignment during loops!
I agree! But be careful about assuming that all code in the Azure repository meets quality standards. It's not subject to the same audits as you'd think!
I still think the code could use some improvements, like clearer naming and better conventions.
Thanks for clarifying that! I appreciate the background info!