Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Powershell's "return" keyword cause type errors?

Tags:

powershell

$xml = [xml] '<node>foo</node>'
function foo2 { return "foo2" }

# all of these fail with the message:
# **Cannot set "foo" because only strings can be used as values to set XmlNode properties.**
$xml.node = foo2
$xml.node = foo2 -as [string]  # because of this issue[1]
$xml.node = (foo2)  

# these work
$xml.node = (foo2).tostring()
$xml.node = (foo2) -as [string]
$xml.node = [string] (foo2)

# yet, these two statements return the same value
(foo2).gettype()
(foo2).tostring().gettype()

1: PowerShell functions return behavior

like image 968
Richard Berg Avatar asked Mar 01 '23 18:03

Richard Berg


2 Answers

Got some confirmation from the PowerShell team on this one. This appears to be a bug in the XML adapter. If you look at the object that is spit out by foo2 in a debugger it is a PSObject. If you don't use the return keyword and instead just output the string "foo2" then the function returns a string object.

The bug in the XML adapter is that it is not unwrapping the PSObject to get at the base object. As a result when it tries to assign the PSObject to $xml.node it fails. For now, as a workaround, you can manually unwrap the psobject like so (or just cast to [string]):

$xml = [xml] '<node>foo</node>'
function foo2 { return "foo2" }
$xml.node = (foo2).psobject.baseobject
$xml

node
----
foo2
like image 53
Keith Hill Avatar answered Mar 08 '23 05:03

Keith Hill


Depending on the context, functions may return an array (of length 1) where your expected result is at index 0 in the array. To ensure you always get a scalar if a single element is returned wrapped in an array, use the following syntax:

$xml.node = $( myfunc )

Hope this helps,

-Oisin

p.s. I know others cannot repro this, and nor can I, but I suspect your demo code is cut out from some other, larger script.

like image 30
x0n Avatar answered Mar 08 '23 04:03

x0n