Klasy w PowerShell


PowerShell jest językiem skryptowym, którego świat bardzo mocno osadzono w .Net. Wraz z jego rozwojem pojawiało się coraz więcej możliwości znanych z tradycyjnych języków obiektowych. Mogliśmy pracować na obiektach, tworzyć funkcje czy workflowy. Do niedawna jednym z niedostępnych elementów w składni języka pozostawały klasy. Wersja PowerShella 5.0 otwiera i tę możliwość w sposób natywny.

Wcześniej w PowerShell klas nie można było tworzyć wprost, pozostawała jedynie droga „naokoło”. Jedna ze stosowanych tu metod to kompilowanie, podczas wykonywania skryptu, kodu napisanego w języku tradycyjnie do tego wykorzystywanym, czyli C# czy VisualBasic.

Drugą ze stosowanych dotąd metod było tworzenie nowego niestandardowego obiektu z własnymi właściwościami za pomocą cmdletu New-Object:

Oba sposoby mają swoje wady i zalety. Niestety za pomocą żadnego z nich nie możemy korzystać z klas w tak wygodny sposób, jak w językach natywnie je implementujących. Dodatkowo tworzenie generycznych obiektów przy pomocy drugiego sposobu nie daje nam możliwości korzystania z metod.

Klasy i obiekty

Klasa jest symboliczną reprezentacją obiektu. Opisuje jego strukturę tak samo, jak projekt budynku opisuje ideę wykonania obiektu budowlanego. I podobnie jak na podstawie jednego projektu może powstać wiele budynków o podobnych właściwościach, tak z definicji klasy może powstać wiele obiektów danego typu. Instancja obiektu zawiera określone i zdefiniowane wcześniej dane, do których dostęp można uzyskać poprzez właściwości. Posiada metody, które reprezentują możliwe do wykonania na niej akcje.

Świat PowerShella opiera się całkowicie na obiektach. Każdy wynik działania cmdletów – niezależnie od tego, czy są one proste czy złożone – jest obiektem .NET. Sprawdźmy to na przykładzie:

Wywołanie zmiennej z przypisanym wynikiem cmdletu Get-Date zwraca nam dokładną datę i godzinę, w której ten cmdlet wykonano. Zmienna $today zawiera nie tylko te dane, ale także wiele innych przydatnych cech, które można łatwo wykorzystać poprzez odpowiednie wywołanie. Powyższy przykład pokazuje, jak otrzymać wartości z konkretnych właściwości. Są to odpowiednio DayOfWeek, która zawiera nazwę dnia tygodnia oraz Hour, która zawiera godzinę. Dostęp do właściwości obywa się za pomocą znaku kropki, która w tym przypadku oddziela zmienną przechowującą instancję obiektu od nazwy konkretnej właściwości.

Analogicznie możemy uzyskać dostęp, czy też wykonać konkretną metodę, która zdefiniowana jest w klasie. W przykładzie wywołujemy metodę AddMonths, która dodaje nam określoną liczbę miesięcy do wyniku. Wartość przekazywana w parametrze jest ujemna, co w efekcie odejmie podaną liczbe miesięcy. Jednocześnie zwracany jest wynik tego działania.

Większość klas zawiera właściwości tylko do odczytu. Oznacza to, że można pobrać ich wartość, ale nie można ich ustawić. Poniższy przykład pokazuje, co się stanie w przypadku próby ustawienia godziny dla naszej instancji obiektu.

Wszystkie metody, właściwości i nazwę klasy, której instancją jest dany obiekt, można uzyskać za pomocą cmdleta Get-Member.

Wynik informuje nas o tym, że ten obiekt jest reprezentacją instancji klasy DateTime, jaka jest lista właściwości i metod wraz z ich nazwami oraz definicją, z której można się dowiedzieć o rodzaju i ilości przyjmowanych atrybutów.

Powyższe przybliża nas do idei klas, ale nie odpowiada nam jasno, dlaczego mielibyśmy je stosować w PowerShellu. Możemy przecież tworzyć funkcje, które bez trudu utworzą obiekt np. z klasy PSObject posiadający własne i zdefiniowane przez nas właściwości. Wynik działania takiej funkcji możemy przypisać do dowolnej zmiennej. Sprawdźmy to na poniższym przykładzie, wykorzystując wcześniejszy kod tworzenia nowego pracownika:

Wynik przechowywany w obu zmiennych zawiera podane przez nas dane:

Mogłoby się więc wydawać, że takie tworzenie obiektów będzie wystarczające. I faktycznie tak jest w przypadku znacznej części codziennej pracy administracyjnej. Nie zawsze przecież pojawia się potrzeba tworzenia dużej liczby obiektów, posiadających wiele właściwości o różnych typach, zawierających wiele metod pozwalających manipulować tymi danymi.

Łatwo sobie jednak wyobrazić sytuację, w której tworzony obiekt będzie zawierać wiele różnych metod. W przypadku korzystania z obiektów generycznych, tworzonych np. z klasy PSObject, musielibyśmy zaimplementować je wszystkie jako osobne funkcje. Funkcje te nie będą przypisane w żaden sposób do konkretnych typów obiektów, a dodatkowo obiekt, który będzie zmieniany, będzie musiał być przekazywany do funkcji jako jej parametr, a następnie wynik tej funkcji powinien być przypisany ponownie do zmiennej, w której był przechowywany:

Już korzystanie z jednej metody zaimplementowanej w ten sposób staje się mało czytelne. Używanie skryptów napisanych w ten sposób, ich pielęgnacja i ponowne wykorzystanie jest bardzo uciążliwe. W tym miejscu na pomoc przychodzą klasy w PowerShellu. Sprawdźmy więc, jak wyglądać będzie implementacja klasy pracownika zawierająca wszystkie powyższe właściwości. Zainicjujmy też jeden obiekt:

Tylko tyle potrzebujemy do utworzenia obiektu pracownika. Wynik zmiennej $Pracownik1 łatwo przewidzieć: będzie analogiczny do poprzedniego sposobu tworzenia obiektu za pomocą obiektu generycznego PSObject. Zrobiliśmy to jednak znacznie prościej i czytelniej:

Dodatkowo można zauważyć, że typ obiektu tożsamy jest z nazwą naszej klasy.

Istnieje także dodatkowy sposób inicjowania obiektu z klasy:

Warto także zauważyć, że w przypadku naszej klasy samo jej zainicjowanie powoduje utworzenie obiektu, którego właściwości są puste.

Do zapamiętania

Poniżej zestawiam najważniejsze informacje związane z klasami.

  1. Klasa jest symboliczną reprezentacją obiektu, czyli jego projektem, na podstawie którego będzie tworzony.
  2. Obiekt jest instancją danej klasy. Zawiera dane przechowywane we właściwościach oraz akcje do wykonania na nim, zwane metodami.
  3. Wiele obiektów zawierających różne dane można tworzyć z jednej klasy.
  4. Najprostsza definicja klasy składa się ze słowa kluczowego Class, nazwy klasy oraz nawiasów klamrowych. Właściwości klasy umieszczone są pomiędzy nawiasami klamrowymi.

Co dalej?

W następnym artykule omówimy metody, czyli akcje możliwe do wykonania na danym obiekcie, oraz konstruktory, czyli specjalne metody umożliwiające tworzenie obiektów z inicjalnie ustawionymi właściwościami.

Wszystkie części

  1. Klasy w PowerShell
  2. Klasy w PowerShell cz. 2

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Komentarz do “Klasy w PowerShell