2012-06-14 25 views
3

用戶cashfoley在codeplex上發佈了一個看起來相當優雅的代碼集合,稱爲PSClass的「模塊」。名稱查找在Powershell腳本塊中如何工作?

當我點源psclass代碼到我自己的一些代碼,我能寫這樣的代碼:

$Animal = New-PSClass Animal { 

    constructor { 
     param($name, $legs) 

     # ... 
    } 

    method -override ToString { 
     "A $($this.Class.ClassName) named $($this.name) with $($this.Legs) Legs" 
    } 
} 

當我試圖然而,創建一個模塊出的PSClass代碼,我開始出現錯誤。 constructormethod名稱不再被識別。

看看實際的實現,我看到的是constructor,method等實際上是嵌套在New-PSClass函數中的函數。

因此,在我看來,當我點播PSClass.ps1文件時,我的腳本塊允許包含對嵌套在其他本地函數中的函數的引用。但是,當PSClass代碼成爲模塊時,導出New-PSClass函數(我嘗試使用清單並使用Export-ModuleMember),名稱不再可見。

有人可以向我解釋腳本塊,範圍規則和嵌套函數的可見性規則是如何協同工作的?

另外,有一種單獨的,是否有一個更好的類純定義協議純Powershell腳本? (具體來說,不涉及「只是寫在C#中,然後執行此操作......」)

+0

ps> get-help about_scopes |更多 – x0n

回答

0

腳本塊中的變量在執行前不會被評估。如果在執行塊時腳本塊中的變量不存在於當前範圍內,則變量將不具有任何值。腳本塊不是閉包:它們在實例化時不捕獲上下文。

Remove-variable FooBar 

function New-ScriptBlock 
{ 
    $FooBar = 1 

    $scriptBlock = { 
     Write-Host "FooBar: $FooBar" 
    } 

    $FooBar = 2 
    & $scriptBlock # Outputs FooBar: 2 because $FooBar was set to 2 before invocation 
    return $scriptBlock 
} 

function Invoke-ScriptBlock 
{ 
    param(
     $ScriptBlock 
    ) 

    & $ScriptBlock 
} 

$scriptBlock = New-ScriptBlock 

& $scriptBlock # Prints nothing since $FooBar doesn't exist in this scope 

$FooBar = 3 
Invoke-ScriptBlock $scriptBlock # Prints $FooBar: 3 since FooBar set to 3 
+0

如果這是真的,那麼爲什麼將外部函數放在模塊中不起作用? –