I expect that inside a class method, I can have "local" variable scoped inside of the method, but it is not the case. The following is the test code:
class test_scope {
$var = "class var"
test_scope() {
}
[void] my_method() {
$var = "method var"
}
}
$obj = [test_scope]::new()
$obj.my_method()
I got an error message:
Line |
8 | $var = "method var"
| ~~~~
| Cannot assign property, use '$this.var'.
This is surprising. How can I have local variables?
As a comparison, function (outside of a class, that is) can have local variables with the same name as the script variable. The following is an example:
$var2="global var"
function my_function() {
$var2="function var"
write-host $var2
write-host $script:var2
}
my_function($null)
and I got the answer I expected:
function var
global var
As another comparison with Python:
class test_scope:
var = "class var"
def my_method(self):
var = "method var"
print(self.var)
print(var)
obj = test_scope()
obj.my_method()
It works as expected:
function var
global var
so PowerShell is out of norm?
PS: I tested under PowerShell 5.0 and 7.0.
The accepted answer avoids the problem but doesn't identify its root cause. This is that the scope of a variable must always be specified in class functions, with the exception of parameters that the function receives and class properties. So you can write without any problems:
class test_scope {
$var = "class var"
test_scope() {
}
[void] my_method() {
$local:var = "local method var" # or private
$script:var = "script var" # or global
# one can omit local or private scope when reading the variable:
Write-Host "'$var' vs '$( $this.var )'"
# one has to use global or script scope also when reading the variable:
Write-Host "'$( $script:var )' vs '$( $this.var )'" # or global
}
}
$obj = [test_scope]::new()
$obj.my_method()
Output:
'local method var' vs 'class var'
'script var' vs 'class var'