I will explain my question on an example. Let's have following code in C#:
void A(Action block)
{
B(() =>
{
Console.WriteLine(2);
block();
});
}
void B(Action block)
{
Console.WriteLine(1);
block();
}
void Main()
{
A(() =>
{
Console.WriteLine(3);
});
}
The output of this code is:
1
2
3
Now, I want to write this code in PowerShell:
function A($block) {
B {
2
. $block
}
}
function B($block) {
1
. $block
}
A {
3
}
However, this code causes a call depth overflow:
The script failed due to call depth overflow. The call depth reached 1001 and the maximum is 1000.
I found that if I change the name of the parameter of the function B, it will work.
Is it a feature or a bug (or both)? How can I make that work in PowerShell without having parameters unique across functions?
You can pass the parameters in the PowerShell function and to catch those parameters, you need to use the arguments. Generally, when you use variables outside the function, you really don't need to pass the argument because the variable is itself a Public and can be accessible inside the function.
Subexpression operator $( ) For a single result, returns a scalar. For multiple results, returns an array. Use this when you want to use an expression within another expression. For example, to embed the results of command in a string expression. PowerShell Copy.
The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.
The PowerShell parameter is a fundamental component of any script. A parameter is a way that developers enable script users to provide input at runtime. If a PowerShell script's behavior needs to change in some way, a parameter provides an opportunity to do so without changing the underlying code.
Yeah, you're going recursive because the $block
reference in the scriptblock passed into function B gets evaluated in the context of function B and as a result, evaluates to the value of B's $block
parameter.
If you don't want to change the parameter name (don't blame you) you can force PowerShell to create a new closure in A to capture the value of $block within function A e.g.:
function A($block)
{
B {Write-Host 2; &$block}.GetNewClosure()
}
function B($block)
{
Write-Host 1
&$block
}
A {Write-Host 3}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With