"$foo; return" and "return $foo" have subtly different semantics - by Blake Coverett

Status : 

 


6
0
Sign in
to vote
ID 508100 Comments
Status Active Workarounds
Type Bug Repros 3
Opened 11/4/2009 1:16:10 AM
Access Restriction Public

Description

If $foo is a bare object, "$foo; return" writes the bare object down the pipeline, "return $foo" adapts $foo into a PSObject and writes that down the pipeline.
Sign in to post a comment.
Posted by Blake Coverett on 11/4/2009 at 3:29 PM
To make reproducing this bug self-contained, here is a C# cmdlet that demonstrates the problem:

using System.Management.Automation;
[Cmdlet(VerbsCommon.Get, "Object")]
public class GetObject: PSCmdlet {
[Parameter(Mandatory=true, Position=0)]
[ValidateNotNull]
public object InputObject { get; set; }
protected override void EndProcessing() {
    WriteObject(InputObject.GetType().FullName);
}
}

Compile and import the above, then you can see the following results:

PS› Get-Object (&{ @{} })
System.Collections.Hashtable

PS› Get-Object (&{ return @{} })
System.Management.Automation.PSObject

Note, you can otherwise perform various operations on the native object without triggering it to be wrapped, i.e.

PS› Get-Object (&{ $h = @{}; $h.Add('foo', 'bar'); $h })
System.Collections.Hashtable

PS› Get-Object (&{ $h = @{}; $h.Add('foo', 'bar'); return $h })
System.Management.Automation.PSObject
Posted by Blake Coverett on 11/4/2009 at 1:14 PM
Those two pipelines in the repro steps prove the problem clearly to my mind. Is there a reason they are insufficient for you?

Bug# 508091 shows how Format-Table is sensitive to whether the hashtable passed in is wrapped in a PSObject or not. Since I'm not aware of an easy way to test whether an object is wrapped or not, I've used that behavior as a test. The second pipeline fails because the hashtable is wrapped by the return statement. The alternative is writing a C# cmdlet to show the behavior.
Posted by Dave Lerner on 11/4/2009 at 10:55 AM
Please post code proof.