Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista - Common PowerShell programming traps

Reply
 
Old 10-07-2006   #1 (permalink)
=?Utf-8?B?Um9tYW4gS3V6bWlu?=


 
 

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 {$scriptk = $false; continue} # note explicit 'script:'
1/$null # error
$ok # $ok is $false

--
Thanks,
Roman

My System SpecsSystem Spec
Old 10-07-2006   #2 (permalink)
Adam Milazzo


 
 

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 {$scriptk = $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
}
My System SpecsSystem Spec
Old 10-07-2006   #3 (permalink)
Roman Kuzmin


 
 

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


My System SpecsSystem Spec
Old 10-07-2006   #4 (permalink)
Keith Hill [MVP]


 
 

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

My System SpecsSystem Spec
Old 10-07-2006   #5 (permalink)
Adam Milazzo


 
 

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...
My System SpecsSystem Spec
Old 10-08-2006   #6 (permalink)
Roman Kuzmin


 
 

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


My System SpecsSystem Spec
Old 10-08-2006   #7 (permalink)
Adam Milazzo


 
 

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.
My System SpecsSystem Spec
Old 10-09-2006   #8 (permalink)
Alex K. Angelopoulos [MVP]


 
 

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 {$scriptk = $false; continue} # note explicit 'script:'
> 1/$null # error
> $ok # $ok is $false
>
> --
> Thanks,
> Roman



My System SpecsSystem Spec
Old 10-09-2006   #9 (permalink)
James Truher


 
 

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.



My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Windows programming and image manipulation in Powershell question PowerShell
Moving Personal Folders: Not Intuitive and With Serious Traps Vista file management
Book: Professional Windows PowerShell Programming: Snapins, Cmdlets,Hosts and Providers (Paperback) by Wrox PowerShell
[ANN] New PowerShell programming book due in September PowerShell
Traps and Foreach loops PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46