How can I pass strings by reference to the parent scope?
This doesn't work since strings are not acceptable "values".
function Submit([ref]$firstName){
$firstName.value = $txtFirstName.Text
}
$firstName = $null
Submit([ref]$firstName)
$firstName
Error: "Property 'value' cannot be found on this object; make sure it exists and is settable"
Doing this doesn't give an error but it doesn't change the variable either:
$firstName = "nothing"
function Submit([ref]$firstName){
$firstName = $txtFirstName.Text
}
Submit([ref]$firstName)
$firstName
Edit:
Doing the first code block by itself works. However when trying to do it in my script it returns the error again. I fixed it enough for it to assign the variable and do what I want but it still throws up an error and I was wondering how to fix that. I think it's because it doesn't like variable;es changing during a running session. Here is a link to my script
https://github.com/InconspicuousIntern/Form/blob/master/Form.ps1
Your first snippet is conceptually correct and works as intended - by itself it does not produce the "Property 'Value' cannot be found on this object" error.
You're seeing the error only as part of the full script you link to, because of the following line:
This line causes your
Submit
function to be called without arguments, which in turn causes the$firstName
parameter value to be$null
, which in turn causes the error quoted above when you assign to$firstName.Value
.By contrast, the following invocation of
Submit
, as in your first snippet, is correct:[ref] $firstName
creates a (transient) reference to the caller's$firstName
variable, which insideSubmit
binds to (local) parameter variable$firstName
(the two may, but needn't and perhaps better not have the same name), where$firstName.Value
can then be used to modify the caller's$firstName
variable.Syntax note: I've intentionally placed a space between
Submit
and([ref] $firstName)
to make one thing clearer:The
(...)
(parentheses) here do not enclose the entire argument list, as they would in a method call, they enclose the single argument[ref] $firstName
- of necessity, because that expression wouldn't be recognized as such otherwise.Function calls in PowerShell are parsed in so-called argument mode, whose syntax is more like that of invoking console applications: arguments are space-separated, and generally only need quoting if they contain special characters.
For instance, if you also wanted to pass string
'foo'
, as the 2nd positional parameter, toSubmit
:Note how the two arguments are space-separated and how
foo
needn't be quoted.As for an alternative approach:
[ref]
's primary purpose is to enable .NET method calls that haveref
/out
parameters, and, as shown above, using[ref]
is nontrivial.For calls to PowerShell functions there are generally simpler solutions.
For instance, you can pass a custom object to your function and let the function update its properties with the values you want to return, which naturally allows multiple values to be "returned"; e.g.:
Alternatively, you can just let
Submit
construct the custom object itself, and simply output it:Please try this out and see if you are getting the same results? It is working for me, and I really did not change much.