7

I'm trying to automate creation of a bunch of tabs in PowerShell ISE

I've started with a function such as

function Start-NewTab($name, [ScriptBlock]$scriptBlock)
{
    $tab = $psISE.PowerShellTabs.Add()
    $tab.DisplayName = $name
    sleep 2
    $tab.Invoke($scriptBlock)
}

however when I run it like so

$v = "hello world"
Start-NewTab "Test" { $v }

hello world isn't shown, unlike the following fragement

function Test-ScriptBlock([ScriptBlock]$sb) { & $sb }
Test-ScriptBlock { $v }

What's going on here and how do I fix it?

4

3 に答える 3

1

「Tab」コンテナーは、ISEのランタイム(またはPowerShell実行環境)と同等です。新しいタブ(つまり、PowerShell実行環境)を作成しているため、変数vはその実行環境では未定義です。スクリプトブロックは新しい実行環境で評価され、v(なし)の値を出力します。

Test-Scriptblockの場合とStart-NewTabの場合で、変数を見つける必要のあるスコープを明示的に指定してスクリプトブロック内の変数を取得しようとすると、変数の解像度がどのように異なるかを簡単に確認できます。

PS>Test-ScriptBlock { get-variable v -scope 0}
Get-Variable : Cannot find a variable with name 'v'.
PS>Test-ScriptBlock { get-variable v -scope 1}
Get-Variable : Cannot find a variable with name 'v'.
PS>Test-ScriptBlock { get-variable v -scope 2} # Variable found in grandparent scope (global in the same execution environment)
Name                           Value                                                                                                                           
----                           -----                                                                                                                           
v                              hello world

PS>Start-NewTab "Test" { get-variable v -scope 0 } # global scope of new execution environment
Get-Variable : Cannot find a variable with name 'v'.
PS>Start-NewTab "Test" { get-variable v -scope 1 } # proof that scope 0 = global scope
Get-Variable : The scope number '1' exceeds the number of active scopes.

問題の回避策の1つは、スクリプトブロックで変数を定義することです。

Start-NewTab "Test" { $v = "hello world";$v }

編集:もう1つ、タイトルに「閉鎖」と記載されています。Powershellのスクリプトブロックはクロージャーではありませんが、スクリプトブロックからクロージャーを作成できます。ただし、これはあなたが説明する問題には役立ちません。

Edit2:別の回避策:

$v = "hello world"
Invoke-Expression "`$script = { '$v' }"
Start-NewTab "test" $script
于 2012-02-06T16:08:32.483 に答える
0

または、最初にスクリプトブロックを作成します。

$v={"Hello world"}                                                                                                    
start-newtab "test" $v 

ただし、範囲を覚えておく必要があります。

于 2012-02-06T16:13:55.370 に答える