2013-03-03 19 views
6

Dosyadan harici bir işlev almak istiyorum, onu bir modüle dönüştürmüyoruz (yüzlerce dosya başına işlevimiz var, bu nedenle bunların tümünü modüller olarak ele aldık) .Fonksiyondan dosyaya genel kapsamdan noktaya işlev fonksiyonları

İşte kod açıklaması. İçe Aktarma İşlevinde komut dosyası kök klasörü eklemek, dosya mevcudiyetini kontrol etmek ve özel bir hata atmak gibi bazı ek mantığa sahip olduğumu lütfen unutmayın.

C: \ Repository \ Foo.ps1:

Function Foo { 
    Write-Host 'Hello world!' 
} 

C: \ InvocationTest.ps1:

# Wrapper func 
Function Import-Function ($Name) { 
    # Checks and exception throwing are omitted 
    . "C:\Repository\$name.ps1" 

    # Foo function can be invoked in this scope 
} 

# Wrapped import 
Import-Function -Name 'Foo' 
Foo   # Exception: The term 'Foo' is not recognized 

# Direct import 
. "C:\Repository\Foo.ps1" 
Foo   # 'Hello world!' 

küresel kapsama kaynağını nokta için herhangi bir hile var mı?

cevap

4

Komut dosyasını bir üst kapsamda çalıştıramazsınız, ancak genel kapsamda açık bir şekilde belirleyerek bir işlev oluşturabilirsiniz.

Bunun gibi bir şey sizin için çalışır mı?

# Wrapper func 
Function Import-Function ($Path) { 
    # Checks and exception throwing are omitted 
    $script = Get-Content $Path 
    $Script -replace '^function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)', 'function Global:$1' 
    .([scriptblock]::Create($script)) 

} 

The above regex yalnızca kök fonksiyonlarını hedefler (sola dayalı fonksiyonları; kelimenin function sol için hiçbir boşluk). Onlar tanımlanan böylece nokta kaynaklı dosyalarında tanımlanan işlevleri değiştirebilirsiniz

$Script -replace '^\s*function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)','function Global:$1' 
+0

Çok teşekkürler, bu güzel hach ​​çalışıyor. Eğer işe yaramazsa, çalışmasını sağlamak için birkaç küçük düzeltme ekledim. –

+0

Hiç boşver. Tam bir bitmiş çözüm değil, sadece bir fikir iletmeye çalışıyordum. – mjolinor

+0

@AntonPurin, cevabınızı 'küçük düzeltmeleri' içerecek şekilde güncelleyebilir misiniz? –

0

Şu anda global kapsamda bir işlevi çalıştırmanın bir yolunu hatırlayamıyorum. Eğer bir dizeye .ToString() için scriptblock dönüştürdüğünüzde, değişken genişleyecektir

$name = "myscript" 

$myimportcode= { 
    # Checks and exception throwing are omitted 
    . .\$name.ps1 
    # Foo function can be invoked in this scope 
} 

Invoke-Expression -Command $myimportcode.ToString() 

: Böyle bir şey yapabilirdi.

0

: bakılmaksızın boşluk (alt fonksiyonları dahil), tüm fonksiyonları hedeflemek için, hiç $Script -replace hattını değiştirmek küresel kapsam: Eğer bir işlev içinde o kaynak dot zaman

function Global:Get-SomeThing { 
    # ... 
} 

, nokta kaynaklı dosyasında tanımlanan işlev genel olacaktır. Bunun en iyi fikir olduğunu söylemiyorum, sadece başka bir olasılık.

İlgili konular