tags:

views:

137

answers:

3

Here is my code:

# hi.ps1

function fun
{
    Write-Host $args
}

Write-Host '---------------'
Write-Host $args
Write-Host '---------------'
fun
Write-Host '---------------'

This is the output:

PS C:\scratch> .\hi there jim
---------------
there jim
---------------

---------------

My question is, why isn't $args visible within fun?

+1  A: 

From my understanding of powershell, $args refers to the the arguments to the current function. The first time you call Write-Host, $args refers to the top-level arguments. Inside fun, you're referring to the arguments to fun, which are not given.

See PowerShell Variables for more information on variables.

lacqui
Nice guess, but that can't be right. If you modify fun to take an argument, the Write-Host still produces no output.
dangph
Oh, $args does in fact refer to function arguments, BUT it seems that if the function has a parameter list (e.g. function ($x) {...}) then $args won't be assigned, which I think is somewhat counter-intuitive.
dangph
I think you are misunderstanding the purpose of $args. $args stores any "uncaught" arguments. If you define parameters in a script or function, then PowerShell will try to bind arguments to those. Anything it can not bind will end up in $args.
JasonMArcher
Yes, it makes sense once you know, but it is not obvious at first how it works.
dangph
+1  A: 

It seems that $args has "script" scope. There are three scopes: local, global, and script.

If the function is changed like this:

function fun
{
    Write-Host $script:args
}

Then it will work. The "script:" is a scope resolution operator ("local:" is the default). I found that result somewhat experimentally, and I can't say I know what the point of script scope is exactly, but it appears that variables in script scope belong to the script itself in some way.

Edit: I'm accepting my own answer as the best one since it is what solved my problem, but also see the other answers and their comments for some useful information.

dangph
+4  A: 

Think of a script file like a function. The function body is the script content and the function name is the script file name. When you send arguments to the script they will be avaiable in the script content. When you send arguments to a function $args will be accessible inside the function.

Take the following for example:

# .\test-args.ps1

function foo{ write-host "printing function `$args $args"}

# print script args

write-host "printing script `$args $args"

# print function args

foo hello world ...

# end of script
Shay Levy
Yup. You can think of $args acting kind of like $_. It all matters what context you are using it in.
JasonMArcher
$args becomes available if a func has no named params or when args count is -gt named params count, that is, if you have a func with 2 params and you send 4 arguments then $args contains the last 2.
Shay Levy