powershell – 为什么在.ps1与.psm1文件中$_的行为有所不同?

前端之家收集整理的这篇文章主要介绍了powershell – 为什么在.ps1与.psm1文件中$_的行为有所不同?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设您在map.ps1中定义了map_ps:

function map_ps{
    [CmdletBinding()]
    param([parameter(ValueFromPipeline=$true)]$InputObject,$sb,$ArgumentList)
    process{&$sb $ArgumentList}
}

假设您还在名为map.psm1的well-formed模块中定义了另一个具有相同实现的函数map_psm:

function map_psm{
    [CmdletBinding()]
    param([parameter(ValueFromPipeline=$true)]$InputObject,$ArgumentList)
    process{&$sb $ArgumentList}
}

使用相同的参数调用每个函数不会产生相同的结果:

PS C:\> 1 | map_ps  -sb {"DollarBar:$_,Arg:$($args[0])"} -ArgumentList 2
DollarBar:1,Arg:2
PS C:\> 1 | map_psm -sb {"DollarBar:$_,Arg:$($args[0])"} -ArgumentList 2
DollarBar:,Arg:2

函数在.psm1中实现时为什么$_为空,但是当函数在.ps1中实现时却不是?

解决方法

除非在全局范围内声明变量,否则functions / ScriptBlocks无法看到模块中声明的变量与其自己的模块不同.作为解决方法,您可以通过[scriptblock] :: Create创建ScriptBlocks,它创建的ScriptBlocks不受任何特定模块的限制:

function FunctionWithoutModule{
    [CmdletBinding()]
    param([parameter(ValueFromPipeline=$true)]$InputObject,$ArgumentList)
    process{
        $SomeVariable='SomeValue'
        &$sb $ArgumentList
    }
}
$Module=New-Module -ScriptBlock {
    function FunctionWithModule{
        [CmdletBinding()]
        param([parameter(ValueFromPipeline=$true)]$InputObject,$ArgumentList)
        process{
            $SomeVariable='SomeValue'
            &$sb $ArgumentList
        }
    }
}
$ScriptBlockWithoutModule={"DollarBar:$_,Arg:$($args[0]),SomeVariable:$SomeVariable"}
$ScriptBlockWithModule=$Module.NewBoundScriptBlock($ScriptBlockWithoutModule)
$ScriptBlockNotBoundToModule=[scriptblock]::Create($ScriptBlockWithoutModule)

1|FunctionWithoutModule -sb $ScriptBlockWithoutModule -ArgumentList 2
#DollarBar:1,Arg:2,SomeVariable:SomeValue
1|FunctionWithoutModule -sb $ScriptBlockWithModule -ArgumentList 2
#DollarBar:,SomeVariable:
1|FunctionWithoutModule -sb $ScriptBlockNotBoundToModule -ArgumentList 2
#DollarBar:1,SomeVariable:SomeValue
1|FunctionWithModule -sb $ScriptBlockWithoutModule -ArgumentList 2
#DollarBar:,SomeVariable:
1|FunctionWithModule -sb $ScriptBlockWithModule -ArgumentList 2
#DollarBar:1,SomeVariable:SomeValue
1|FunctionWithModule -sb $ScriptBlockNotBoundToModule -ArgumentList 2
#DollarBar:1,SomeVariable:SomeValue

猜你在找的设计模式相关文章