![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
|
Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
br> br> |
| |||||||
![]() |
| | Thread Tools | Display Modes |
| | #1 (permalink) |
| Guest | Common PowerShell programming traps Can we summarise some of common PowerShell programming traps from our experience? Just few of them from my own are here: *) Using function/script/.. parameters Do not pass parameters to PowerShell functions/scripts/... using syntax: MyFunction(param1, param2, ...) Instead do: MyFunction param1 param2 ... *) function/script/.. do not always 'return' array of objects Do not expect that a function/script/... returns an array of objects. The result is: $null in case of 0 objects; an object (not an array of 1 object) in case of 1 object; array of objects in case of 2+ objects. Example: $a = MyFunction # $a may be: $null; an object; an array of objects Processing a function results via pipeline helps to avoid ambiguity: MyFunction | <processing results> When an array is required use @(): $a = @(MyFunction) # $a is an array of 0, 1 or more objects *) trap block creates a new scope This probably does not work as expected: $ok = $true trap {$ok = $false; continue} 1/$null # error $ok # $ok is still $true This works fine (suppose the code is in script scope): $ok = $true trap {$script k = $false; continue} # note explicit 'script:'1/$null # error $ok # $ok is $false -- Thanks, Roman |
| | #2 (permalink) |
| Guest | Re: Common PowerShell programming traps Roman Kuzmin wrote: > Can we summarise some of common PowerShell programming traps from our > experience? Just few of them from my own are here: > > This works fine (suppose the code is in script scope): > $ok = $true > trap {$script k = $false; continue} # note explicit 'script:'> 1/$null # error > $ok # $ok is $false As you asked -- what if it's inside a function? function foo { $ok = $true trap {$ok = $false; continue} 1/$null # error return $ok # $ok is still $true } |
| | #3 (permalink) |
| Guest | Re: Common PowerShell programming traps Adam Milazzo wrote: > As you asked -- what if it's inside a function? > function foo > { > $ok = $true > trap {$ok = $false; continue} > 1/$null # error > return $ok # $ok is still $true > } I have just answered in the other thread but I think it is better to duplicate: to change a variable in parent scope we may use Set-Variable with -Scope 1 function foo { $ok = $true trap {Set-Variable ok $false -Scope 1; Continue} 1/$null # error $ok # $ok is $false } Thanks, Roman |
| | #4 (permalink) |
| Guest | Re: Common PowerShell programming traps "Roman Kuzmin" <RomanKuzmin@discussions.microsoft.com> wrote in message news:3A0EE800-DC11-4F05-8123-B13EBBCC8AE3@microsoft.com... > Can we summarise some of common PowerShell programming traps from our > experience? Just few of them from my own are here: Unexpected Function Output. Each statements output becomes part of the function's output. This can surprise you when you use a .NET method and you didn't realize it returned a value i.e. you assumed that the return was void. Or you might have known there was a return value but since you didn't use it, you think it just goes away. For instance, if you use StringBuilder you might not realize that the StringBuilder.Append* methods return the current StringBuilder contents (a string). Typically when you use these APIs in a function you would cast the method call to [void] or redirect to $null to eliminate the "intermediate" state of the StringBuilder from the output. -- Keith |
| | #5 (permalink) |
| Guest | Re: Common PowerShell programming traps Keith Hill [MVP] wrote: > "Roman Kuzmin" <RomanKuzmin@discussions.microsoft.com> wrote in message > news:3A0EE800-DC11-4F05-8123-B13EBBCC8AE3@microsoft.com... >> Can we summarise some of common PowerShell programming traps from our >> experience? Just few of them from my own are here: > > Unexpected Function Output. > > Each statements output becomes part of the function's output. This can > surprise you when you use a .NET method and you didn't realize it > returned a value i.e. you assumed that the return was void. Or you > might have known there was a return value but since you didn't use it, > you think it just goes away. For instance, if you use StringBuilder you > might not realize that the StringBuilder.Append* methods return the > current StringBuilder contents (a string). Typically when you use these > APIs in a function you would cast the method call to [void] or redirect > to $null to eliminate the "intermediate" state of the StringBuilder from > the output. I agree, regarding .NET functions. To quote James Truher: ----- We did consider that we should make [.NET] method calls more like cmdlet invocation to improve consistency, but at the end of the day, we reckoned that the developer types that would actually be using the object/method features would understand the differences between the two (method invocation and command arguments). ----- If method invocation already has a different syntax, it could have different behavior regarding automatically pushing return values into the pipeline, too. I'd like it better that way... |
| | #6 (permalink) |
| Guest | Re: Common PowerShell programming traps > Keith Hill [MVP] wrote: > Unexpected Function Output. "Adam Milazzo" wrote: > I'd like it better that way... I definitely agree that it is a trap and a very easy and annoying one. But this behaviour seems quite useful and natural for commands executed interactively. Finally I do come to a conclusion that what is good in command line should have higher priority than possible programming issues in scripts. And, at least for the moment, interactive and script commands should have the same effect. Thanks, Roman |
| | #7 (permalink) |
| Guest | Re: Common PowerShell programming traps Roman Kuzmin wrote: >> Keith Hill [MVP] wrote: >> Unexpected Function Output. > > "Adam Milazzo" wrote: >> I'd like it better that way... > > I definitely agree that it is a trap and a very easy and annoying one. But > this behaviour seems quite useful and natural for commands executed > interactively. Finally I do come to a conclusion that what is good in > command line should have higher priority than possible programming issues in > scripts. And, at least for the moment, interactive and script commands > should have the same effect. Would having trap { } operate more like if(x) { } in its scoping (so it can alter local variables) have some detrimental effect on commands executed interactively? I can't think of one, and if there isn't one, I'd like to know why trap has this weird scoping, then. |
| | #8 (permalink) |
| Guest | Re: Common PowerShell programming traps These are the same as the primary 'traps' I've encountered. Here's how I currently tend to think about/explain both of these to get people around the trappish side of them. ![]() (1) PowerShell functions/filters/scripts are COMMANDS not METHODS. (To explain the calling syntax to programmers). (2) functions/filters/scripts/commands you use are always pipeline segments. This is to communicate the fact that things you get from these sources have no guarantee of type or even numeracy - they may yield nothing, one item, or multiple items, and they may be of any type. It's not a great explanation, but it may make people think about the comparison to a physical pipeline - no guarantees of what you have dripping through to you, if anything. "Roman Kuzmin" <RomanKuzmin@discussions.microsoft.com> wrote in message news:3A0EE800-DC11-4F05-8123-B13EBBCC8AE3@microsoft.com... > Can we summarise some of common PowerShell programming traps from our > experience? Just few of them from my own are here: > > > *) Using function/script/.. parameters > > Do not pass parameters to PowerShell functions/scripts/... using syntax: > MyFunction(param1, param2, ...) > > Instead do: > MyFunction param1 param2 ... > > > *) function/script/.. do not always 'return' array of objects > > Do not expect that a function/script/... returns an array of objects. The > result is: $null in case of 0 objects; an object (not an array of 1 > object) > in case of 1 object; array of objects in case of 2+ objects. > > Example: > $a = MyFunction # $a may be: $null; an object; an array of objects > > Processing a function results via pipeline helps to avoid ambiguity: > MyFunction | <processing results> > > When an array is required use @(): > $a = @(MyFunction) # $a is an array of 0, 1 or more objects > > > *) trap block creates a new scope > > This probably does not work as expected: > $ok = $true > trap {$ok = $false; continue} > 1/$null # error > $ok # $ok is still $true > > This works fine (suppose the code is in script scope): > $ok = $true > trap {$script k = $false; continue} # note explicit 'script:'> 1/$null # error > $ok # $ok is $false > > -- > Thanks, > Roman |
| | #9 (permalink) |
| Guest | Re: Common PowerShell programming traps we definitely discussed both ways of having trap work. In the end, we wanted to avoid the general pollution that we thought would occur if we had the trap execute in the same scope of the function body, we also felt that the unintended side-effects would also be harder to debug. Lastly, remember that you can have any number of traps within a function. So far, the examples have been pretty simple, but it can be much more complicated: function badbad { trap [exception1] { ... } trap [exception2] { ... } trap [exception3] { ... } trap [exception4] { ... } trap [exception5] { ... } .... } The pollution caused by all these traps was felt to be more a hindrance than a help. Especially since it's so easy to adjust variables in the parent scope. jim -- -- James Truher [MSFT] Windows PowerShell Development Microsoft Corporation This posting is provided "AS IS" with no warranties, and confers no rights. "Adam Milazzo" <adamm@san.rr.com> wrote in message news:%234s$Tbx6GHA.4608@TK2MSFTNGP03.phx.gbl... > Roman Kuzmin wrote: >>> Keith Hill [MVP] wrote: >>> Unexpected Function Output. >> >> "Adam Milazzo" wrote: >>> I'd like it better that way... >> >> I definitely agree that it is a trap and a very easy and annoying one. >> But this behaviour seems quite useful and natural for commands executed >> interactively. Finally I do come to a conclusion that what is good in >> command line should have higher priority than possible programming issues >> in scripts. And, at least for the moment, interactive and script commands >> should have the same effect. > > Would having trap { } operate more like if(x) { } in its scoping (so it > can alter local variables) have some detrimental effect on commands > executed interactively? > > I can't think of one, and if there isn't one, I'd like to know why trap > has this weird scoping, then. |
| |
| |
![]() |
| Thread Tools | |
| Display Modes | |
| |
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Windows programming and image manipulation in Powershell question | hasten | PowerShell | 0 | 02-16-2008 03:22 PM |
| Moving Personal Folders: Not Intuitive and With Serious Traps | René G-L | Vista file management | 2 | 11-19-2007 02:14 AM |
| Book: Professional Windows PowerShell Programming: Snapins, Cmdlets,Hosts and Providers (Paperback) by Wrox | Marco Shaw | PowerShell | 1 | 05-28-2007 02:32 PM |
| [ANN] New PowerShell programming book due in September | Marco Shaw | PowerShell | 0 | 02-28-2007 07:40 AM |
| Traps and Foreach loops | lawndart@gmail.com | PowerShell | 4 | 02-14-2007 01:24 PM |