Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indexing doesn't work for a Hashtable with an array key #9580

Closed
daxian-dbw opened this issue May 12, 2019 · 16 comments
Closed

Indexing doesn't work for a Hashtable with an array key #9580

daxian-dbw opened this issue May 12, 2019 · 16 comments
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-No Activity Issue has had no activity for 6 months or more WG-Engine core PowerShell engine, interpreter, and runtime

Comments

@daxian-dbw
Copy link
Member

Steps to reproduce

$s = @("hello")
$hash = @{ $s = 'Yay' }
$hash.Contains($s)
> True
$hash[$s]

Expected behavior

$hash[$s]
> Yay

Actual behavior

$hash[$s] returns nothing

Environment data

Name                           Value
----                           -----
PSVersion                      6.2.0
PSEdition                      Core
GitCommitId                    6.2.0
OS                             Microsoft Windows 10.0.17763
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
@daxian-dbw daxian-dbw added the Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a label May 12, 2019
@msftrncs
Copy link
Contributor

Do I understand right though, that $hash. $s works?

@daxian-dbw
Copy link
Member Author

daxian-dbw commented May 12, 2019

Yes. Within the context of the repro steps, $hash. $s works as expected.
$hash[$s] doesn't work here because powershell incorrectly treating the array $s as slicing indexes.

A slicing index example:

> $a = 1,2,3
> $a[@(1,2)]
2
3

@bpayette
Copy link
Contributor

@daxian-dbw It isn't "incorrectly" treating the array as a slice. This is by design. We wanted symmetric behavior between indexables wrt slicing. It does mean that you can't index using a collection reference but that was viewed as being a fairly obscure secondary scenario. The workaround is to simply use the item property:

PS[1] (20) > $a = @{($index1 = (1,2,3)) = "one"; ($index2 = (4,5,6)) = "two"}
PS[1] (21) > $a.item($index1)
one
PS[1] (22) > $a.item($index2)
two
PS[1] (23) >

Note that changing the current behaviour would be a significant breaking change so I'm not sure what you are proposing here.

@msftrncs
Copy link
Contributor

@bpayette, so, this is expected to be usable:

$a = @{a=1;b=2;c=3}
$b='a','b','c'
$a[$b]
1
2
3

And this is why an array should not be the key of a hashtable. Item() obviously solves the problem, but ONLY if you know that the key is an array. If you were passed both the key and the hash, you may not be fully away of what methods you can use.

@vexx32
Copy link
Collaborator

vexx32 commented May 16, 2019

Tbh, I generally tend to expect that the hashtable literal syntax wouldn't accept anything other than a string as a key name, and am then generally surprised when it does strange things like this.

I almost want to say it's worth breaking some of the more esoteric scripts and restricting the literal syntax to only use value types as keys; after all, using a reference type as a key is... gonna be weird at the best of times. You need a reference to that item to get the item back from the table, at which point it almost becomes pointless to keep the data in a hashtable anyway.

@bpayette
Copy link
Contributor

@msftrncs Yes - this is supposed to be usable.

, but ONLY if you know that the key is an array

Right. And if it's your code, then you should know that. If it's a 3rd party library, then you need to know how that library works in order to use it properly. I would recommend against doing this in a public interface because it is confusing.

@vexx32 Restricting the keys to non-mutable types (not just value types since strings are references) would have make sense but we didn't think about that way back in V1.

@vexx32
Copy link
Collaborator

vexx32 commented May 16, 2019

Right, but considering it's still for most intents and purposes utterly arcane and unusable I think that would be a change worth making, no?

@bpayette
Copy link
Contributor

@vexx32 Yes it's arcane but clearly @daxian-dbw had a reason from opening this bug.

@chuanjiao10 Anxiety is a good word :-)

@vexx32
Copy link
Collaborator

vexx32 commented May 16, 2019

Indeed, @bpayette; it arose from this arguably even more arcane situation that one can find themselves in: #9564

@msftrncs
Copy link
Contributor

Just to clarify, that hashtable comes from .NET right? So the same class can be used in the same way from other .NET languages (though their syntax might be more conventional (key=object, value=object))? So while PowerShell could have syntactically prevented a non-mutable key, that would not have prevented someone in a C# cmdlet from producing one?

@vexx32, I think you mentioned the wrong person above. :)

@vexx32
Copy link
Collaborator

vexx32 commented May 17, 2019

Oops, fixed.

Yes, I'm talking only about the PowerShell literal syntax. Even in PS, you could still opt to add weird keys to your hashtable via the $ht.Add() method if you choose.

I'm just thinking it probably makes the most sense for PS not to support that in its literal hashtable declarations due to the esoteric and confusing nature of how it works with objects that can only be compared by reference.

@SeeminglyScience
Copy link
Collaborator

Right, but considering it's still for most intents and purposes utterly arcane and unusable I think that would be a change worth making, no?

While I agree that it's difficult to find a use case for an array as a key, I don't agree as a general rule for all reference types. For example a reference type:

  1. Whose instances are created only once and then cached (e.g. System.RuntimeType)
  2. That overrides GetHashCode and the equality operators/methods (though, hopefully it would also be immutable in design)
  3. That is stored as a value in another dictionary

@iSazonov iSazonov added the WG-Engine core PowerShell engine, interpreter, and runtime label Sep 29, 2019
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

2 similar comments
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

@microsoft-github-policy-service microsoft-github-policy-service bot added the Resolution-No Activity Issue has had no activity for 6 months or more label Nov 16, 2023
Copy link
Contributor

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-No Activity Issue has had no activity for 6 months or more WG-Engine core PowerShell engine, interpreter, and runtime
Projects
None yet
Development

No branches or pull requests

7 participants
@daxian-dbw @iSazonov @SeeminglyScience @msftrncs @vexx32 @bpayette and others