Windows_PowerShell_iconpoprzedni konqrs okazał się zbyt łatwy. no to kto będzie prawdziwym cwaniakiem i rozkmini na tym poziomie? tym razem trochę wiedzy o:

  • rekurencji
  • zakresach zmiennych
  • praktyka
  • i kolejna zagadka (;

poprzedni wpis zainspirowany został podczas poprawiania skryptu.. czy też pisania go od nowa, który gdzieś tam wewnątrz miał funkcję budującą listę użytkowników grupy distribution:

function Get-GroupMember
{
    param($name)
    $members = @()
    foreach($member in (Get-DistributionGroupMember $name))
    {
        if($member.RecipientType -eq "UserMailbox")
        {
            $member
        }
        elseif($member.RecipientType -eq "MailUniversalSecurityGroup")
        {
            Get-GroupMember $member.Name
        }
    }

}

jak widać jest to rekursywne zapytanie, w wersji 'czyste zło’. zło, które zostało wskazane w odpowiedzi przez bula – tak na prawdę funkcja nie zwraca jednej zmiennej, tylko całą serię zagnieżdżonych zmiennych. zwróćcie uwagę, że wewnątrz funkcji jest deklaracja '$members=@()’ – czyli przy każdym kolejnym zagnieżdżeniu tworzy się nowy '$members’. w efekcie, nie dość, że technicznie nie ma jednego wyniq a seria wyniqw, to jeśli osoba należy do wielu grup, pojawi się wiele razy. jeśli okaże się, że grupy są gdzieś zapętlone, co przy skomplikowanej strukturze może się wydarzyć, to skrypt będzie leciał w nieskończoność [grupa A należy do grupy B, B do C, C do A – pętelka. AD pozwala nawet na A do B i B do A – nie ma tutaj weryfikacji].

rekursja jest również zła ze względu na obsługę pamięci i możliwość przepełnienia stosu. to trochę zabawne [i frustrujące] ale na pierwszym roq, na programowaniu uczono mnie rekurencji. potrzebowałem duuużo czasu i dobrego przykładu aż w końcu zrozumiałem. bo jak mówi stare przysłowie – ’rekurencję zrozumiał ten, kto zrozumiał rekurencję’. a jak już zrozumiałem, to ten sam wykładowca [Ś.P. prof. Bielecki] poświęcił następny semestr na wyjaśnianiu czemu rekurencja jest zła, czemu należy jej unikać i jak z niej wychodzić… w skrócie – nad wywołaniem rekurencyjnym na prawdę trudno zapanować, chyba że ktoś umie myśleć jak implementacja zagnieżdżonego stosu.

anyway… najprostszą metodą, jest po prostu wyrzucenie zmiennej do wspólnego zakresu [scope]. zmienne mają swoje 'skołpy’, co najlepiej widać właśnie przy rekursji. ale w prostym przykładzie:

function test {
  $a=2
  $a
}
$a=1
test
$a

output to: 2,1 . wewnątrz funkcji 'test’ są dwie zmienne $a – ta wewnątrz funkcji i ta zadeklarowana na poziomie skryptu. słowa 'globalnie’ unikam świadomie, ponieważ są trzy podstawowe poziomy: global, script, local. więcej tutaj.

fajnym testem rekursji+zakresu jest taki przykład:

function recursion {
    param($r)
    $var+=[string]$r
    if($r -lt 10) {
        recursion ($r+1)
    }
}

$var= recursion 1
$var

co wyświetli się na ekranie? spróbuj wymyślić, odpal kod, sprawdź… jeśli nie jesteś zaskoczony – to jesteś unikatem, który na prawdę zajebiście rozumie działanie stosu. ale to nie była końcowa zagadka. do tego jeszcze dojdę.

…. a nie będę pisał na razie dalszej części. zostawię w tym miejscu bo tłumacząc zepsuję zabawę, a dzięki temu ilość zagadek się zwiększy q:

czyli kolejna zagadka i kontynuacja przeróbki skryptu – jakoś na dniach ^^

hef fan

eN.

 

-o((:: sprEad the l0ve ::))o-

Comments (1)

  1. bula

    Odpowiedz

    man about_Scopes :)
    DLa ludzi od vbs to jest problem, bo tutaj to calkiem inaczej sie zachowuje domyslnie :)

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Time limit is exhausted. Please reload CAPTCHA.