shorthand loops behavior vs. traditional

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

This topic contains 4 replies, has 3 voices, and was last updated by

js
 
Participant
1 month, 1 week ago.

  • Author
    Posts
  • #170782

    Participant
    Topics: 23
    Replies: 24
    Points: 102
    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: 1041
    Points: 3,439
    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: 25
    Replies: 678
    Points: 1,629
    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: 23
    Replies: 24
    Points: 102
    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: 25
    Replies: 678
    Points: 1,629
    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.

You must be logged in to reply to this topic.