Skip to content

Commit 6cfa7df

Browse files
committed
Updated examples and added more context
1 parent 4227c86 commit 6cfa7df

File tree

3 files changed

+285
-159
lines changed

3 files changed

+285
-159
lines changed

reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md

Lines changed: 95 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: Describes how to create and use a reference type variable. You can use reference type variables to permit a function to change the value of a variable that is passed to it.
33
Locale: en-US
4-
ms.date: 08/24/2018
4+
ms.date: 12/12/2024
55
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-5.1&WT.mc_id=ps-gethelp
66
schema: 2.0.0
77
title: about_Ref
@@ -10,18 +10,25 @@ title: about_Ref
1010

1111
## Short description
1212

13-
Describes how to create and use a reference type variable. You can use
14-
reference type variables to permit a function to change the value
15-
of a variable that is passed to it.
13+
Describes how to create and use a reference type variable.
1614

1715
## Long description
1816

19-
You can pass variables to functions _by reference_ or _by value_.
17+
You can pass variables to functions _by reference_ or _by value_. When you pass
18+
a variable _by value_, you are passing a copy of the data. When you pass a
19+
variable _by reference_, you are passing a reference to the original value.
20+
This allows the function to change the value of the variable that is passed to
21+
it.Reference types are created using `[ref]`, which is the type accelerator for
22+
the `[System.Management.Automation.PSReference]` type.
2023

21-
When you pass a variable _by value_, you are passing a copy of the data.
24+
The primary purpose of `[ref]` is to enable passing PowerShell variables by
25+
reference to .NET method parameters marked as `ref`, `out`, or `in`. You can
26+
also define your own PowerShell function that take `[ref]` type parameters. In
27+
this usage, `[ref]` is applied to a _variable_, and the resulting `[ref]`
28+
instance can be used to indirectly modify that variable's value.
2229

2330
In the following example, the function changes the value of the variable passed
24-
to it. In PowerShell, integers are value types so they are passed by value.
31+
to it. In PowerShell, integers are value types so they're passed by value.
2532
Therefore, the value of `$var` is unchanged outside the scope of the function.
2633

2734
```powershell
@@ -40,7 +47,7 @@ $var
4047
```
4148

4249
In the following example, a variable containing a `Hashtable` is passed to a
43-
function. `Hashtable` is an object type so by default it is passed to the
50+
function. `Hashtable` is an object type so by default it's passed to the
4451
function _by reference_.
4552

4653
When passing a variable _by reference_, the function can change the data and
@@ -66,7 +73,7 @@ Test New Text
6673
The function adds a new key-value pair that persists outside of the function's
6774
scope.
6875

69-
### Writing functions to accept reference parameters
76+
## Writing functions to accept reference parameters
7077

7178
You can code your functions to take a parameter as a reference, regardless of
7279
the type of data passed. This requires that you specify the parameters type
@@ -98,7 +105,7 @@ $var
98105
3
99106
```
100107

101-
### Passing references to .NET methods
108+
## Passing references to .NET methods
102109

103110
Some .NET methods may require you to pass a variable as a reference. When
104111
the method's definition uses the keywords `in`, `out`, or `ref` on a
@@ -126,7 +133,7 @@ PS> $number
126133
15
127134
```
128135

129-
### References and scopes
136+
## References and scopes
130137

131138
References allow the value of a variable in the parent scope to be changed
132139
within a child scope.
@@ -148,59 +155,96 @@ $i = 0;$iRef = 1
148155

149156
Only the reference type's variable was changed.
150157

151-
### Relationship between [ref] and System.Management.Automation.PSReference
158+
## Using `[ref]` as a general-purpose object holder
152159

153-
`Ref` is both a type accelerator for `System.Management.Automation.PSReference`
154-
(see [about_Type_Accelerators] for details) and a reserved keyword that
155-
PowerShell treats especially. Hence, `ref` and `PSReference` are not
156-
equivalents. The following script demonstrates their difference:
160+
You can also use `[ref]` as a general-purpose object holder. In this usage,
161+
`[ref]` is applied to a _value_ instead of a variable. Typically, the value is
162+
an instance of a _value type_, like a number. In most scenarios you can use a
163+
regular variable or parameter instead. However, this technique is useful in
164+
scenarios where passing an explicit value holder is undesired (for brevity) or
165+
not possible, such as in script-block parameter values.
166+
167+
For example, you can use script-block parameter values to calculate the value
168+
of **NewName** parameter of the `Rename-Item` cmdlet. The `Rename-Item` cmdlet
169+
allows you to pipe items to it. The command run the script block passed to the
170+
**NewName** for each item in the pipeline. The script block run in a child
171+
scope. Modifying a variable in the caller's scope directly won't help and you
172+
can't pass arguments to the script block in this context.
173+
174+
In this example, the script block passed to the **NewName** parameter
175+
increments the value of `$iRef` for each item in the pipeline. The script block
176+
creates a new name by adding a number to the beginning of the filename.
157177

158178
```powershell
159-
$x = 1
179+
$iRef = [ref] 0
180+
Get-ChildItem -File $setPath |
181+
Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name }
182+
```
160183

161-
$a = [ref] $x
162-
$b = [System.Management.Automation.PSReference] $x
163-
$c = [ref] $x
184+
## Difference between `[ref]` and `[System.Management.Automation.PSReference]`
164185

165-
$x +=4
166-
$a.Value +=3
167-
$b.Value +=2
168-
$c.Value +=1
186+
A reference type variable is created using
169187

170-
$x, $a.Value, $b.Value, $c.Value | ForEach-Object {
171-
Write-Output $PSItem
172-
}
173-
```
188+
Even though `[ref]` is a type accelerator for
189+
`[System.Management.Automation.PSReference]`, they behave differently.
190+
191+
- When you use `[ref]` to cast a variable, PowerShell creates reference object
192+
that contains reference to the original instance of the variable.
193+
- When you use `[System.Management.Automation.PSReference]` to cast a variable,
194+
PowerShell creates reference object that contains a copy of the variable,
195+
rather than a reference to the original instance.
174196

175-
The output of this script is:
197+
For example, the following script creates a variable `$x` and two reference
198+
objects.
176199

177200
```powershell
178-
9
179-
9
180-
3
181-
9
201+
PS> $int = 1
202+
PS> $aRef = [ref] $int
203+
PS> $bRef = [System.Management.Automation.PSReference] $int
204+
PS> $int
205+
1
206+
PS> $aRef, $bRef
207+
208+
Value
209+
-----
210+
1
211+
1
182212
```
183213

184-
The above script:
214+
At this point, both reference object have the same value as `$int`. By adding
215+
different values to the reference objects, we can see that `$aRef`, which was
216+
created using `[ref]`, is a reference to the original instance of `$int`.
217+
`$bRef` was created using `[System.Management.Automation.PSReference]` is a
218+
copy of the variable.
185219

186-
- Creates an integer `$x` variable and assigns `1` to it.
187-
- Creates pointers `$a` and `$c` of `[ref]` types and points them at `$x`.
188-
- Creates pointer `$b` of `[PSReference]` type and points it, not at `$x`, but
189-
a copy thereof, because PowerShell treats `[ref]` and `[PSReference]`
190-
differently.
191-
- Adds 4 to `$x`, 3 to `$a`'s value, 2 to `$b`'s value, and 1 to `$a`'s value.
220+
```powershell
221+
PS> $aRef.Value+=2
222+
PS> $bRef.Value+=5
223+
PS> $int
224+
3
225+
PS> $aRef, $bRef
192226
193-
In the script above, `$x`, `$a.Value`, and `$c.Value` point to the same memory
194-
location. They are the same, i.e., 1 + 4 + 3 + 1 = 9. But `$b.Value` refers to
195-
a copy of `$x` at the time of its creation. Hence, it contains 1 + 2 = 3.
227+
Value
228+
-----
229+
3
230+
6
231+
```
196232

197233
## See also
198234

199-
- [about_Variables](about_Variables.md)
200-
- [about_Environment_Variables](about_Environment_Variables.md)
201-
- [about_Functions](about_Functions.md)
202-
- [about_Script_Blocks](about_Script_Blocks.md)
203-
- [about_Scopes](about_scopes.md)
204-
- [about_Type_accelerators]
205-
206-
[about_Type_accelerators]: about_Type_Accelerators.md
235+
- [about_Variables][06]
236+
- [about_Environment_Variables][01]
237+
- [about_Functions][02]
238+
- [about_Script_Blocks][04]
239+
- [about_Scopes][03]
240+
- [about_Type_Accelerators][05]
241+
- [System.Management.Automation.PSReference][07]
242+
243+
<!-- link references -->
244+
[01]: about_Environment_Variables.md
245+
[02]: about_Functions.md
246+
[03]: about_scopes.md
247+
[04]: about_Script_Blocks.md
248+
[05]: about_Type_Accelerators.md
249+
[06]: about_Variables.md
250+
[07]: xref:System.Management.Automation.PSReference

0 commit comments

Comments
 (0)