Hasonlóan a változókhoz, a függvényeknek is van láthatóságuk, „scope”-juk. Nézzünk erre is egy példát:
[12] PS I:\>function külső ($p)
>> {
>> function belső ($b)
>> {
>> Write-Host "Belső paramétere: $b"
>> }
>> write-host "Külső paramétere: $p"
>> belső 2
>> $k = "külső változója"
>> }
>>
[13] PS I:\>külső 1
Külső paramétere: 1
Belső paramétere: 2
[14] PS I:\>belső 3
The term
'belső' is not recognized as a cmdlet, function, operable program,
or script file. Verify the term and try again.
At line:1
char:6
+ belső <<<< 3
[15] PS I:\>. külső 4
Külső paramétere: 4
Belső paramétere: 2
[16] PS I:\>belső 5
Belső paramétere: 5
A [12]-es sorban definiált külső függvényemben definiálok egy belső függvényt. Amúgy a külső csak annyit csinál, hogy kiírja a paraméterét, meghívja a belsőt és még definiál magának egy $k változót. A belső csak annyit csinál, hogy kiírja a paraméterét.
Amikor a külsőt meghívom a [13]-as sorban, az szépen le is fut: a külső és a belső paramétere is kiíródik. Amikor a [14]-es sorban közvetlenül a belsőt hívom meg, akkor a PowerShell csodálkozik, hiszen a global scope számára a belső függvény nem látható.
Viszont van lehetőség arra, hogy a külső függvényemet „felemelem” globális szintre és így hívom meg, ezt tettem meg a [15]-ös sorban. Ennek formátuma nagyon egyszerű: egy darab pont, egy szóköz (fontos!) és a függvény neve. Ezt hívjuk dotsourcing -nak, azaz a meghívás szintjére emelem a függvény (vagy szkript, ld. később) futtatását.
Ez természetesen nem csak a belső függvénydefiníciót emelte fel a globális scope-ba, hanem a külső saját változóját is:
[17] PS I:\>$k
külső változója
Ha nem akarunk dotsourcing-gal bíbelődni, akkor mi magunk is definiálhatjuk eleve globálisnak a függvényben definiált függvényünket:
[23] PS I:\>function függvénytár
>> {
>> function global:első
>> { "első" }
>> function global:második
>> { "második" }
>> }
>>
[24] PS I:\>függvénytár
[25] PS I:\>első
első
[26] PS I:\>második
második
Ha ezek után meghívom a „függvénytár” függvényemet, definiálódik benne az „első” és a „második” függvény is, de a globális scope-ban, így közvetlenül meghívhatók.
Megjegyzés:
Ez a „dotsourcing” nagyon erős, azaz ha így hívok meg egy függvényt, akkor a benne tárolt minden „titok” meghívható lesz közvetlenül. Még akkor is, ha private-nak definiálom a belső függvényemet:
[28] PS I:\>function titkos
>> {
>> function private:egymegegy
>> { "1+1=2" }
>> }
>>
[29] PS I:\>. titkos
[30] PS I:\>egymegegy
1+1=2
Ámde ha egy változónál a –Visibility lehetőségnél állítjuk be a Private-ot, akkor már más a helyzet:
[114] PS C:\> function priv {New-Variable -Name pv -Visibility private -Value 5
; $pv}
[115] PS C:\> . priv
5
[116] PS C:\> $pv
Cannot
access the variable '$pv' because it is a private variable
At line:1
char:4
+ $pv
<<<<
+ CategoryInfo : PermissionDenied: (pv:String) [],
SessionStateE
xception
+ FullyQualifiedErrorId : VariableIsPrivate
Itt nyer értelmez igazából ez a lehetőség, azaz hiába hívom dotsource-szal a függvényt, a privát láthatóságú változó még akkor sem látható kívülről.
Összefoglalóul: a privát opció a gyerek-scope-ok elől rejti el a változókat, a privát láthatóság a szülő-scope elől rejti el.