diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md index 8116e6d81857..e6fbdf737f3a 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md @@ -1,28 +1,34 @@ --- 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. Locale: en-US -ms.date: 08/24/2018 +ms.date: 12/12/2024 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Ref --- - # about_Ref ## Short 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. +Describes how to create and use a reference type variable. ## Long description -You can pass variables to functions *by reference* or *by value*. +You can pass variables to functions _by reference_ or _by value_. When you pass +a variable _by value_, you are passing a copy of the data. When you pass a +variable _by reference_, you are passing a reference to the original value. +This allows the function to change the value of the variable that is passed to +it.Reference types are created using `[ref]`, which is the type accelerator for +the `[System.Management.Automation.PSReference]` type. -When you pass a variable *by value*, you are passing a copy of the data. +The primary purpose of `[ref]` is to enable passing PowerShell variables by +reference to .NET method parameters marked as `ref`, `out`, or `in`. You can +also define your own PowerShell function that take `[ref]` type parameters. In +this usage, `[ref]` is applied to a _variable_, and the resulting `[ref]` +instance can be used to indirectly modify that variable's value. In the following example, the function changes the value of the variable passed -to it. In PowerShell, integers are value types so they are passed by value. +to it. In PowerShell, integers are value types so they're passed by value. Therefore, the value of `$var` is unchanged outside the scope of the function. ```powershell @@ -41,10 +47,10 @@ $var ``` In the following example, a variable containing a `Hashtable` is passed to a -function. `Hashtable` is an object type so by default it is passed to the -function *by reference*. +function. `Hashtable` is an object type so by default it's passed to the +function _by reference_. -When passing a variable *by reference*, the function can change the data and +When passing a variable _by reference_, the function can change the data and that change persists after the function executes. ```powershell @@ -67,14 +73,14 @@ Test New Text The function adds a new key-value pair that persists outside of the function's scope. -### Writing functions to accept reference parameters +## Writing functions to accept reference parameters You can code your functions to take a parameter as a reference, regardless of the type of data passed. This requires that you specify the parameters type -as `System.Management.Automation.PSReference`, or `[ref]`. +as `[ref]`. -When using references, you must use the `Value` property of the -`System.Management.Automation.PSReference` type to access your data. +When using references, you must use the `Value` property of the `[ref]` type to +access your data. ```powershell Function Test([ref]$data) @@ -86,7 +92,7 @@ Function Test([ref]$data) To pass a variable to a parameter that expects a reference, you must type cast your variable as a reference. -> [!NOTE] +> [!IMPORTANT] > The brackets and parenthesis are BOTH required. ```powershell @@ -99,7 +105,7 @@ $var 3 ``` -### Passing references to .NET methods +## Passing references to .NET methods Some .NET methods may require you to pass a variable as a reference. When the method's definition uses the keywords `in`, `out`, or `ref` on a @@ -127,7 +133,7 @@ PS> $number 15 ``` -### References and scopes +## References and scopes References allow the value of a variable in the parent scope to be changed within a child scope. @@ -149,10 +155,96 @@ $i = 0;$iRef = 1 Only the reference type's variable was changed. +## Using `[ref]` as a general-purpose object holder + +You can also use `[ref]` as a general-purpose object holder. In this usage, +`[ref]` is applied to a _value_ instead of a variable. Typically, the value is +an instance of a _value type_, like a number. In most scenarios you can use a +regular variable or parameter instead. However, this technique is useful in +scenarios where passing an explicit value holder is undesired (for brevity) or +not possible, such as in script-block parameter values. + +For example, you can use script-block parameter values to calculate the value +of **NewName** parameter of the `Rename-Item` cmdlet. The `Rename-Item` cmdlet +allows you to pipe items to it. The command run the script block passed to the +**NewName** for each item in the pipeline. The script block run in a child +scope. Modifying a variable in the caller's scope directly won't help and you +can't pass arguments to the script block in this context. + +In this example, the script block passed to the **NewName** parameter +increments the value of `$iRef` for each item in the pipeline. The script block +creates a new name by adding a number to the beginning of the filename. + +```powershell +$iRef = [ref] 0 +Get-ChildItem -File $setPath | + Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name } +``` + +## Difference between `[ref]` and `[System.Management.Automation.PSReference]` + +A reference type variable is created using + +Even though `[ref]` is a type accelerator for +`[System.Management.Automation.PSReference]`, they behave differently. + +- When you use `[ref]` to cast a variable, PowerShell creates reference object + that contains reference to the original instance of the variable. +- When you use `[System.Management.Automation.PSReference]` to cast a variable, + PowerShell creates reference object that contains a copy of the variable, + rather than a reference to the original instance. + +For example, the following script creates a variable `$x` and two reference +objects. + +```powershell +PS> $int = 1 +PS> $aRef = [ref] $int +PS> $bRef = [System.Management.Automation.PSReference] $int +PS> $int +1 +PS> $aRef, $bRef + +Value +----- + 1 + 1 +``` + +At this point, both reference objects have the same value as `$int`. By adding +different values to the reference objects, we can see that `$aRef`, which was +created using `[ref]`, is a reference to the original instance of `$int`. +`$bRef`, which was created using `[System.Management.Automation.PSReference]`, +is a copy of the variable. + +```powershell +PS> $aRef.Value+=2 +PS> $bRef.Value+=5 +PS> $int +3 +PS> $aRef, $bRef + +Value +----- + 3 + 6 +``` + ## See also -- [about_Variables](about_Variables.md) -- [about_Environment_Variables](about_Environment_Variables.md) -- [about_Functions](about_Functions.md) -- [about_Script_Blocks](about_Script_Blocks.md) -- [about_Scopes](about_scopes.md) +- [about_Variables][06] +- [about_Environment_Variables][01] +- [about_Functions][02] +- [about_Script_Blocks][04] +- [about_Scopes][03] +- [about_Type_Accelerators][05] +- [System.Management.Automation.PSReference][07] + + +[01]: about_Environment_Variables.md +[02]: about_Functions.md +[03]: about_scopes.md +[04]: about_Script_Blocks.md +[05]: about_Type_Accelerators.md +[06]: about_Variables.md +[07]: xref:System.Management.Automation.PSReference diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md index acbfbb151fc4..24522019c862 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md @@ -1,7 +1,7 @@ --- 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. Locale: en-US -ms.date: 08/24/2018 +ms.date: 12/12/2024 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Ref @@ -9,18 +9,26 @@ title: about_Ref # about_Ref ## Short 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. + +Describes how to create and use a reference type variable. ## Long description -You can pass variables to functions *by reference* or *by value*. +You can pass variables to functions _by reference_ or _by value_. When you pass +a variable _by value_, you are passing a copy of the data. When you pass a +variable _by reference_, you are passing a reference to the original value. +This allows the function to change the value of the variable that is passed to +it.Reference types are created using `[ref]`, which is the type accelerator for +the `[System.Management.Automation.PSReference]` type. -When you pass a variable *by value*, you are passing a copy of the data. +The primary purpose of `[ref]` is to enable passing PowerShell variables by +reference to .NET method parameters marked as `ref`, `out`, or `in`. You can +also define your own PowerShell function that take `[ref]` type parameters. In +this usage, `[ref]` is applied to a _variable_, and the resulting `[ref]` +instance can be used to indirectly modify that variable's value. In the following example, the function changes the value of the variable passed -to it. In PowerShell, integers are value types so they are passed by value. +to it. In PowerShell, integers are value types so they're passed by value. Therefore, the value of `$var` is unchanged outside the scope of the function. ```powershell @@ -39,10 +47,10 @@ $var ``` In the following example, a variable containing a `Hashtable` is passed to a -function. `Hashtable` is an object type so by default it is passed to the -function *by reference*. +function. `Hashtable` is an object type so by default it's passed to the +function _by reference_. -When passing a variable *by reference*, the function can change the data and +When passing a variable _by reference_, the function can change the data and that change persists after the function executes. ```powershell @@ -65,14 +73,14 @@ Test New Text The function adds a new key-value pair that persists outside of the function's scope. -### Writing functions to accept reference parameters +## Writing functions to accept reference parameters You can code your functions to take a parameter as a reference, regardless of the type of data passed. This requires that you specify the parameters type -as `System.Management.Automation.PSReference`, or `[ref]`. +as `[ref]`. -When using references, you must use the `Value` property of the -`System.Management.Automation.PSReference` type to access your data. +When using references, you must use the `Value` property of the `[ref]` type to +access your data. ```powershell Function Test([ref]$data) @@ -84,7 +92,7 @@ Function Test([ref]$data) To pass a variable to a parameter that expects a reference, you must type cast your variable as a reference. -> [!NOTE] +> [!IMPORTANT] > The brackets and parenthesis are BOTH required. ```powershell @@ -97,7 +105,7 @@ $var 3 ``` -### Passing references to .NET methods +## Passing references to .NET methods Some .NET methods may require you to pass a variable as a reference. When the method's definition uses the keywords `in`, `out`, or `ref` on a @@ -125,7 +133,7 @@ PS> $number 15 ``` -### References and scopes +## References and scopes References allow the value of a variable in the parent scope to be changed within a child scope. @@ -147,10 +155,96 @@ $i = 0;$iRef = 1 Only the reference type's variable was changed. +## Using `[ref]` as a general-purpose object holder + +You can also use `[ref]` as a general-purpose object holder. In this usage, +`[ref]` is applied to a _value_ instead of a variable. Typically, the value is +an instance of a _value type_, like a number. In most scenarios you can use a +regular variable or parameter instead. However, this technique is useful in +scenarios where passing an explicit value holder is undesired (for brevity) or +not possible, such as in script-block parameter values. + +For example, you can use script-block parameter values to calculate the value +of **NewName** parameter of the `Rename-Item` cmdlet. The `Rename-Item` cmdlet +allows you to pipe items to it. The command run the script block passed to the +**NewName** for each item in the pipeline. The script block run in a child +scope. Modifying a variable in the caller's scope directly won't help and you +can't pass arguments to the script block in this context. + +In this example, the script block passed to the **NewName** parameter +increments the value of `$iRef` for each item in the pipeline. The script block +creates a new name by adding a number to the beginning of the filename. + +```powershell +$iRef = [ref] 0 +Get-ChildItem -File $setPath | + Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name } +``` + +## Difference between `[ref]` and `[System.Management.Automation.PSReference]` + +A reference type variable is created using + +Even though `[ref]` is a type accelerator for +`[System.Management.Automation.PSReference]`, they behave differently. + +- When you use `[ref]` to cast a variable, PowerShell creates reference object + that contains reference to the original instance of the variable. +- When you use `[System.Management.Automation.PSReference]` to cast a variable, + PowerShell creates reference object that contains a copy of the variable, + rather than a reference to the original instance. + +For example, the following script creates a variable `$x` and two reference +objects. + +```powershell +PS> $int = 1 +PS> $aRef = [ref] $int +PS> $bRef = [System.Management.Automation.PSReference] $int +PS> $int +1 +PS> $aRef, $bRef + +Value +----- + 1 + 1 +``` + +At this point, both reference objects have the same value as `$int`. By adding +different values to the reference objects, we can see that `$aRef`, which was +created using `[ref]`, is a reference to the original instance of `$int`. +`$bRef`, which was created using `[System.Management.Automation.PSReference]`, +is a copy of the variable. + +```powershell +PS> $aRef.Value+=2 +PS> $bRef.Value+=5 +PS> $int +3 +PS> $aRef, $bRef + +Value +----- + 3 + 6 +``` + ## See also -- [about_Variables](about_Variables.md) -- [about_Environment_Variables](about_Environment_Variables.md) -- [about_Functions](about_Functions.md) -- [about_Script_Blocks](about_Script_Blocks.md) -- [about_Scopes](about_scopes.md) +- [about_Variables][06] +- [about_Environment_Variables][01] +- [about_Functions][02] +- [about_Script_Blocks][04] +- [about_Scopes][03] +- [about_Type_Accelerators][05] +- [System.Management.Automation.PSReference][07] + + +[01]: about_Environment_Variables.md +[02]: about_Functions.md +[03]: about_scopes.md +[04]: about_Script_Blocks.md +[05]: about_Type_Accelerators.md +[06]: about_Variables.md +[07]: xref:System.Management.Automation.PSReference diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md index 8fcfc9f73b2c..741cfd80de35 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md @@ -1,7 +1,7 @@ --- 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. Locale: en-US -ms.date: 08/24/2018 +ms.date: 12/12/2024 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Ref @@ -10,18 +10,25 @@ title: about_Ref ## Short 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. +Describes how to create and use a reference type variable. ## Long description -You can pass variables to functions _by reference_ or _by value_. +You can pass variables to functions _by reference_ or _by value_. When you pass +a variable _by value_, you are passing a copy of the data. When you pass a +variable _by reference_, you are passing a reference to the original value. +This allows the function to change the value of the variable that is passed to +it.Reference types are created using `[ref]`, which is the type accelerator for +the `[System.Management.Automation.PSReference]` type. -When you pass a variable _by value_, you are passing a copy of the data. +The primary purpose of `[ref]` is to enable passing PowerShell variables by +reference to .NET method parameters marked as `ref`, `out`, or `in`. You can +also define your own PowerShell function that take `[ref]` type parameters. In +this usage, `[ref]` is applied to a _variable_, and the resulting `[ref]` +instance can be used to indirectly modify that variable's value. In the following example, the function changes the value of the variable passed -to it. In PowerShell, integers are value types so they are passed by value. +to it. In PowerShell, integers are value types so they're passed by value. Therefore, the value of `$var` is unchanged outside the scope of the function. ```powershell @@ -40,7 +47,7 @@ $var ``` In the following example, a variable containing a `Hashtable` is passed to a -function. `Hashtable` is an object type so by default it is passed to the +function. `Hashtable` is an object type so by default it's passed to the function _by reference_. When passing a variable _by reference_, the function can change the data and @@ -66,14 +73,14 @@ Test New Text The function adds a new key-value pair that persists outside of the function's scope. -### Writing functions to accept reference parameters +## Writing functions to accept reference parameters You can code your functions to take a parameter as a reference, regardless of the type of data passed. This requires that you specify the parameters type -as `System.Management.Automation.PSReference`, or `[ref]`. +as `[ref]`. -When using references, you must use the `Value` property of the -`System.Management.Automation.PSReference` type to access your data. +When using references, you must use the `Value` property of the `[ref]` type to +access your data. ```powershell Function Test([ref]$data) @@ -85,7 +92,7 @@ Function Test([ref]$data) To pass a variable to a parameter that expects a reference, you must type cast your variable as a reference. -> [!NOTE] +> [!IMPORTANT] > The brackets and parenthesis are BOTH required. ```powershell @@ -98,7 +105,7 @@ $var 3 ``` -### Passing references to .NET methods +## Passing references to .NET methods Some .NET methods may require you to pass a variable as a reference. When the method's definition uses the keywords `in`, `out`, or `ref` on a @@ -126,7 +133,7 @@ PS> $number 15 ``` -### References and scopes +## References and scopes References allow the value of a variable in the parent scope to be changed within a child scope. @@ -148,10 +155,96 @@ $i = 0;$iRef = 1 Only the reference type's variable was changed. +## Using `[ref]` as a general-purpose object holder + +You can also use `[ref]` as a general-purpose object holder. In this usage, +`[ref]` is applied to a _value_ instead of a variable. Typically, the value is +an instance of a _value type_, like a number. In most scenarios you can use a +regular variable or parameter instead. However, this technique is useful in +scenarios where passing an explicit value holder is undesired (for brevity) or +not possible, such as in script-block parameter values. + +For example, you can use script-block parameter values to calculate the value +of **NewName** parameter of the `Rename-Item` cmdlet. The `Rename-Item` cmdlet +allows you to pipe items to it. The command run the script block passed to the +**NewName** for each item in the pipeline. The script block run in a child +scope. Modifying a variable in the caller's scope directly won't help and you +can't pass arguments to the script block in this context. + +In this example, the script block passed to the **NewName** parameter +increments the value of `$iRef` for each item in the pipeline. The script block +creates a new name by adding a number to the beginning of the filename. + +```powershell +$iRef = [ref] 0 +Get-ChildItem -File $setPath | + Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name } +``` + +## Difference between `[ref]` and `[System.Management.Automation.PSReference]` + +A reference type variable is created using + +Even though `[ref]` is a type accelerator for +`[System.Management.Automation.PSReference]`, they behave differently. + +- When you use `[ref]` to cast a variable, PowerShell creates reference object + that contains reference to the original instance of the variable. +- When you use `[System.Management.Automation.PSReference]` to cast a variable, + PowerShell creates reference object that contains a copy of the variable, + rather than a reference to the original instance. + +For example, the following script creates a variable `$x` and two reference +objects. + +```powershell +PS> $int = 1 +PS> $aRef = [ref] $int +PS> $bRef = [System.Management.Automation.PSReference] $int +PS> $int +1 +PS> $aRef, $bRef + +Value +----- + 1 + 1 +``` + +At this point, both reference objects have the same value as `$int`. By adding +different values to the reference objects, we can see that `$aRef`, which was +created using `[ref]`, is a reference to the original instance of `$int`. +`$bRef`, which was created using `[System.Management.Automation.PSReference]`, +is a copy of the variable. + +```powershell +PS> $aRef.Value+=2 +PS> $bRef.Value+=5 +PS> $int +3 +PS> $aRef, $bRef + +Value +----- + 3 + 6 +``` + ## See also -- [about_Variables](about_Variables.md) -- [about_Environment_Variables](about_Environment_Variables.md) -- [about_Functions](about_Functions.md) -- [about_Script_Blocks](about_Script_Blocks.md) -- [about_Scopes](about_scopes.md) +- [about_Variables][06] +- [about_Environment_Variables][01] +- [about_Functions][02] +- [about_Script_Blocks][04] +- [about_Scopes][03] +- [about_Type_Accelerators][05] +- [System.Management.Automation.PSReference][07] + + +[01]: about_Environment_Variables.md +[02]: about_Functions.md +[03]: about_scopes.md +[04]: about_Script_Blocks.md +[05]: about_Type_Accelerators.md +[06]: about_Variables.md +[07]: xref:System.Management.Automation.PSReference