Függvények láthatósága, „dotsourcing”

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.



Word To HTML Converter