Reputation: 59
The way I've been writing code is that I've been making separate ps1 files to do specific tasks. In doing so I noticed that a script in one file has access to the variables of the calling script.
For my limited purposes, I don't think I'll ever want to have globals as I want each ps1 file to act as a function which is passed the arguments it needs.
Should I be defining a scope for every variable I create? Is there a way to force all variables in a ps1 file to be local in scope? Or do I need to set the scope on each variable?
EDIT (Untested simplified code to demonstrate):
The second file will print $month from the first file. This means it's a global and not local just to file1.ps1. I don't want globals as I'd rather pass what I need the other scripts need. Should file2.ps have been defined as a function to prevent this?
file1.ps1:
$date = Get-Date
$month = $date.Month
./file2.ps1
---------------------
file2.ps1:
write-host $month
=================================
Upvotes: 2
Views: 285
Reputation: 36708
Actually, I think the most important aspect of your question has not been addressed: scope pollution. Scope pollution is a very legitimate concern and may be even more troublesome than your example suggests. Consider the following two scripts
=========== script1.ps1 ============
$month = "jan"
$year = "1999"
. .\script2.ps1
"Date in script1 is {0}, {1}" -f $month, $year
=========== END script1.ps1 ============
=========== script2.ps1 ============
$year = "2013"
"Date in script2 is {0}, {1}" -f $month, $year
$month = "feb"
=========== END script2.ps1 ============
The output is this:
Date in script2 is jan, 2013
Date in script1 is feb, 2013
That is, not only does script2--the supposed "child"--have access to script1's variables but script1--the supposed "parent"--also has access to script2's variables! The reason for this is that dot-sourcing a script is not a parent-child relationship; the dot-sourced entity is on par with the dot-sourcing entity. It is as if the script was written
$month = "jan"
$year = "1999"
$year = "2013"
"Date in script2 is {0}, {1}" -f $month, $year
$month = "feb"
"Date in script1 is {0}, {1}" -f $month, $year
The fact that you recognize there is a scoping issue means you should at least be considering functions and modules for proper encapsulation. For further reading, take a look at a couple of my articles on Simple-Talk.com:
Upvotes: 1
Reputation: 54881
Any variable will be created automatically in a local scope unless you declare it to a specific scope. Script
is the local scope for commands in the base of a script file, and function is a a local scope of commands inside a function. Global is the "local scope" for the sessions (ex. commands your write directly in the console). Ex:
MyScript.ps1
$myscriptvar = "This is in a local SCRIPT scope"
function test {
$myfuncvar = "This is in the local scope for the function"
#I can READ $myscriptvar in here, but if I define it (ex $myscriptvar = 2),
#the change will exist in a LOCAL variable ($function:myscriptvar) in the function only.
}
test
Console
$myglobalvar = @"
This is in the global scope and can be read by
the script and the function inside the script, but any changes will be saved in
their local scope if not specified like $global:mygloblvar
"@
.\MyScript.ps1
So all variables is by default created in the "local" scope, it just depends where you define it (in console, scriptfile, function).
EDIT example with scripts:
Untitled2.ps1
"In script2, `$myvar is: $:myvar"
"In script2, `$script:myvar is: $script:myvar"
$myvar = "lol"
Untitled1.ps1
$myvar = "Hey"
.\Untitled2.ps1
$myvar
Console
PS > .\Untitled1.ps1
In script2 , $myvar is: Hey
In script2 , $script:myvar is:
Hey
Upvotes: 2
Reputation: 180798
In general, the default scope (i.e. with no modifiers) should almost always suffice, unless you need to override it with some other scope:
An item you include in a scope is visible in the scope in which it was created and in any child scope, unless you explicitly make it private.
If you create a function, it will have its own scope. Any variables you declare within the function will be limited to that scope (the inside of the function).
Upvotes: 0