Welcome Forums General PowerShell Q&A shorthand loops behavior vs. traditional

Viewing 4 reply threads
  • Author
    Posts
    • #170782
      Participant
      Topics: 28
      Replies: 28
      Points: 163
      Rank: Participant

      I was playing around with a for loop I have in one of my functions, and noticed an oddity. If I do something like this:
       

          foreach ($a in 1..40) {
             try {
                Add-Content -Path $Path -Value $Content -ErrorAction Stop
                break
             } catch {
                Start-Sleep -Milliseconds 250
             }
          }
      

      It works as expected, breaking out of the foreach loop and continuing the function. I can even be specific and assign the loop a label, and the break specifically from that label. But if I shorthand it:

          (1..40) | % {
             try {
                Add-Content -Path $Path -Value $Content -ErrorAction Stop
                break
             } catch {
                Start-Sleep -Milliseconds 250
             }
          }
      

      The break not only takes me out of the loop, but out of the function and the whole script. I cannot assign a label to the shorthand version of the loop statement, and have yet to find a way to break only out of the foreach loop in this case. Yes, I know I should write things out rather than shorthand, I am just curious if this is intended behavior or not.

    • #170872
      Senior Moderator
      Topics: 8
      Replies: 1163
      Points: 4,070
      Helping Hand
      Rank: Community Hero

      Actually, that is not a short hand. Those two are two different items. ForEach-Object is a cmdlet and foreach is a looping construct, hence they behaves differently.

      While foreach is a loop (similar to foreach in c#), ForEach-Object is a cmdlet and when used in pipeline it takes objects coming throught the pipeline one at a time and its not same as looping, but similar.

    • #170878
      js
      Participant
      Topics: 28
      Replies: 752
      Points: 2,102
      Helping Hand
      Rank: Community Hero

      Yep, even if you call a second script, break outside of a loop will end everything. Use return or exit instead in that case.

      Also using a big range like 1..1000000 will usually use a lot of memory, but somehow inside a foreach () it’s optimized.

    • #170884
      Participant
      Topics: 28
      Replies: 28
      Points: 163
      Rank: Participant

      Thanks for the responses, I guess I didn’t realize the difference between just the foreach loop and the foreach-object cmdlet. I did try both return (which doesn’t break out of the loop) and exit (tries to exit the entire session) but neither seem to do the trick. As I said, I will stick with the long version, was just curious at the apparent difference in behavior.

    • #170887
      js
      Participant
      Topics: 28
      Replies: 752
      Points: 2,102
      Helping Hand
      Rank: Community Hero

      Also you can’t pipe from foreach () unless it’s inside a function and you pipe from the function, and you can from foreach-object.

Viewing 4 reply threads
  • The topic ‘shorthand loops behavior vs. traditional’ is closed to new replies.