5

I want to create an (immutable) tuple (or array) of elements in Powershell, so my attempt is the following:

$t = @("A","B")

Now, this creates an array that I can add to:

$t += "C"

I want $t to be immutable during the execution of the program. How can I do this?

2
  • @Snak3d0c if you can change it; it's not immutable. Commented Apr 19, 2018 at 10:18
  • Seems i misread the explanation i found. Thanks for clearing that up. I deleted my comment so that i don't confuse others. Commented Apr 19, 2018 at 10:24

3 Answers 3

6

You could actually use tuples

PS[1] (203) > $t = [tuple]::create(1,2,3)
PS[1] (204) > $t.item1
1
PS[1] (205) > $t.item1 = 4
'item1' is a ReadOnly property.
At line:1 char:1
+ $t.item1 = 4
+ ~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException
Sign up to request clarification or add additional context in comments.

1 Comment

This is great. I'm sorry to see that tuples are kind of a second class citizen and don't get all the properties and methods that come built in for something like an array but still nice to know.
4

You can create Read-Only or Constant variables: (Read-Only variables can be modified using -Force switch with Set-Variable method)

New-Variable -Name foo -Option Constant -Value @("A", "B")
$foo += "C"
Cannot overwrite variable foo because it is read-only or constant.

3 Comments

That's not immutable. This gives no error: $foo[0] = "C"
You'd need to make each value in it a constant as well, but this could work. Using actual tuples as bruce's answer shows is probably better.
This is akin to applying the readonly modifier to a field in C#: the variable itself is read-only but not necessarily the object it references.
2

Powershell simply doesn't have the concept of immutability as I understand it. You can fake it with custom objects sort of. Here is some code that can be used to fake an immutable hash table:

function New-ImmutableObject($object) {
    $immutable = New-Object PSObject

    $object.Keys | %{ 
        $value = $object[$_]
        $closure = { $value }.GetNewClosure()
        $immutable | Add-Member -name $_ -memberType ScriptProperty -value $closure
    }

    return $immutable
}
$immutable = New-ImmutableObject @{ Name = "test"}
$immutable.Name = "test1" # Throws error

Not my code. It comes from this quite nice article Functional Programming in PowerShell

You should be able to extend this to whatever type of object you want.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.