Pash-Project / Pash

An Open Source reimplementation of Windows PowerShell, for Mono.
https://groups.google.com/group/pash-project
BSD 3-Clause "New" or "Revised" License
517 stars 54 forks source link

Arrays of zero or one #357

Open mrward opened 9 years ago

mrward commented 9 years ago

Text below taken from microsoft.com

Beginning in Windows PowerShell 3.0, a collection of zero or one object has the Count and Length property. Also, you can index into an array of one object. This feature helps you to avoid scripting errors that occur when a command that expects a collection gets fewer than two items.

The following examples demonstrate this feature.

#Zero objects
    $a = $null
    $a.Count
    0
    $a.Length
    0

#One object
    $a = 4
    $a.Count
    1
    $a.Length
    1
    $a[0]
    4
    $a[-1]
    4
Jaykul commented 9 years ago

To be clear, in PS 3+ all objects have Count and Length ... and if they don't have an indexer, then indexing to item zero returns the object itself. ... which means you can do ridiculous things like

C:\PS> $A = 1
C:\PS> $A[0][0][0][0][0][0]
1
ForNeVeR commented 9 years ago

Maybe it's better to say that since PS3 there is implicit conversion from object to single-object array (or to zero-length array in case of $null)?

Jaykul commented 9 years ago

Well, that's obviously not actually what happens (it would break equality and more), but considering they've also added member unrolling (where you can access the properties of the items in a collection, all at once), it's not a bad way to think about it....

On Monday, March 23, 2015, Friedrich von Never notifications@github.com wrote:

Maybe it's better to say that since PS3 there is implicit conversion from object to single-object array (or to zero-length array in case of $null)?

— Reply to this email directly or view it on GitHub https://github.com/Pash-Project/Pash/issues/357#issuecomment-84813074.

Joel "Jaykul" Bennett http://HuddledMasses.org PowerShell MVP, Software Dev., Speaker 585-563-9632 <//1-585-563-9632> | Jaykul @ GitHub https://github.com/jaykul | Twitter https://twitter.com/Jaykul | Linked In http://www.linkedin.com/in/jaykul/ http://PowerShellGroup.org

sburnicki commented 9 years ago

This behavior is pretty easy to implement:

Access by indexed is implemented in SettableIndexExpression.cs. In line 82 an exception is thrown if that type is not "indexable". The targetValue and list of indices is available at that line, so we can simply check for index == 0 || index == -1 and return the targetValue. The behavior with other indices and setting a value at this index will be needed to be checked.

Similarly in SettableMemberExpression.cs at line 80 we can check for the special Count and Length attribute and return 0/1 if the psobj is not a list/array. This could also be implemented in PSObject itself when getting the properties, but it somehow feels better here, since the special idnexing behavior is also implemented on the expression level.