A legtriviálisabb operátorok – a kifejezés eredeti jelentése alapján – valós számokon végezhető műveletekhez kötődik. A PowerShell ezen jóval túlmutat, a matematikai tanulmányainkban megszokott műveletek ki vannak terjesztve egyéb objektumokra: többek között a tömbökre, sztringekre, fájlokra.
Rögtön nézzünk is példákat az összeadásra:
[1] PS C:\> 5+4
9
[2] PS C:\> "ab" + "lak"
ablak
[3] PS C:\> "egy", "kettő", "három" + "négy", "öt"
egy
kettő
három
négy
öt
Látszik, hogy akár az egészekre, sztringekre vagy a tömbökre is értelmezett az összeadás. Ebben jelentős szerepe van a .NET Framework osztálydefinícióinak, hiszen valójában az ő érdemük, az ő megfelelő összeadást végző metódusuké, hogy mi is történik ténylegesen az összeadás hatására. A PowerShell „csak” abban ludas, hogy megtalálja az adott metódust és átalakítsa a kifejezést, esetlegesen típuskonverziót végezzen az operandusok között.
A Reflector programmal ezeket meg is tudjuk nézni, a számoknál az op_Addition metódust kell keresni:
44 . ábra Az összeadás metódusainak felderítése a Reflectorral
A sztringeknél talán az Append metódust, de ezzel nekünk nem kell törődni, ezt a PowerShell helyettünk elvégzi.
Ezen kívül még dátumokat és esetlegesen hashtáblákat szoktunk még összeadni:
[4] PS I:\>$hash1 = @{Első = 1; Második = 2}
[5] PS I:\>$hash2 = @{Harmadik = 3; Negyedik = 4}
[6] PS I:\>$hash1 + $hash2
Name Value
---- -----
Második 2
Harmadik 3
Negyedik 4
Első 1
Ha olyan hashtáblát próbálunk hozzáadni egy meglevőhöz, amiben újra szerepel egy korábbi elem, akkor hibát kapunk:
[8] PS C:\> $hash3 = @{Harmadik = 33; hatodik = 6}
[9] PS C:\> $hash2 + $hash3
Bad argument to operator '+': Item has already been
added. Key in dictionary:
'Harmadik' Key
being added: 'Harmadik'.
At line:1 char:9
+ $hash2 + <<<< $hash3
+
CategoryInfo : InvalidOperation:
(:) [], RuntimeException
+
FullyQualifiedErrorId : BadOperatorArgument
Dátumoknál kicsit zűrösebb a helyzet:
[12] PS I:\>get-date
2008. március 11. 9:53:26
[13] PS I:\>(get-date) + 5000000000000
2008. március 17. 4:47:00
Jó nagy számot kellett a dátumhoz adnom, hogy valami látható legyen az eredményen, mert valójában a dátum un. „tick”-ekben, „ketyegésekben” számolódik, ami 100 ns-os felbontású időtárolást tesz lehetővé.
Épp ezért a dátumoknál már eleve van mindenféle praktikusabb Add… metódus:
[18] PS I:\>get-date | Get-Member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add Method System.DateTime Add(TimeSpan value)
AddDays Method System.DateTime AddDays(Double value)
AddHours Method System.DateTime AddHours(Double value)
AddMilliseconds Method System.DateTime AddMilliseconds(Double v...
AddMinutes Method System.DateTime AddMinutes(Double value)
AddMonths Method System.DateTime AddMonths(Int32 months)
AddSeconds Method System.DateTime AddSeconds(Double value)
AddTicks Method System.DateTime AddTicks(Int64 value)
AddYears Method System.DateTime AddYears(Int32 value)
...
[19] PS I:\>get-date
2008. március 11. 9:57:55
[20] PS I:\>(get-date).AddDays(5)
2008. március 16. 9:58:10
A fenti példában először kilistáztam a get-date által visszaadott [DateTime] típus metódusait, majd a [20]-as sorban 5 napot adtam az aktuális dátumhoz.
Az összeadáshoz hasonlóan a szorzás is jelentős általánosításon esett át:
[10] PS C:\> 6*7
42
[11] PS C:\> "w"*4
wwww
[12] PS C:\> ("BO","CI")*3
BO
CI
BO
CI
BO
CI
[13] PS C:\> "BO","CI"*3
BO
CI
BO
CI
BO
CI
[14] PS I:\>("BO","CI"*3).length
6
Láthatjuk, hogy a szöveget is lehet szorozni, ez annyiszor teszi össze a szöveget, ahány a szorzásjel után áll.
Tömbnél is hasonlóan többszörözi a tagokat. A [13]-as promptnál látszik, hogy nem is kell zárójelet használni! Ez a PowerShell alkotóinak az érdeme.
Megjegyzés
Érdekes módon a [14]-es promptban látszik, hogy a kéttagú tömb háromszorozása után nem háromelemű lett (3 darab kételemű), hanem hatelemű!
Nézzük meg, hogy mi történik, ha felcseréljük a szorzás operandusit:
[15] PS C:\> 3*"BO","CI"
The '*' operator failed: Cannot convert the "System.Object[]"
value of type "S
ystem.Object[]" to type
"System.Int32"..
At line:1 char:3
+ 3* <<<< "BO","CI"
+
CategoryInfo : InvalidOperation:
(:) [], RuntimeException
+
FullyQualifiedErrorId : OperatorFailed
Azt láthatjuk, hogy nem mindegy, hol van a szorzó és a tényező. A szorzónak kell mindig jobb oldalon állnia, ha nem, akkor hibát kaphatunk, mint ahogy az a [15]-es és [16]-ös sor után is kaptunk, hiszen a PowerShell az automatikus típuskonverziót balról jobbra végzi, azaz az [int] típust veszi alapnak, és ehhez próbálja igazítani a szorzás következő tényezőit, ami itt – szövegek és kételemű tömb esetén - nem sikerült.
Természetesen osztás is van a PowerShellben:
[32] PS I:\>15/5
3
[33] PS I:\>(15/5).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Int32 System.ValueType
[34] PS I:\>15/6
2,5
[35] PS I:\>(15/6).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Double System.ValueType
[36] PS I:\>2,4/1,2
Method invocation failed because [System.Object[]]
doesn't contain a method na
med 'op_Division'.
At line:1 char:5
+ 2,4/ <<<< 1,2
+
CategoryInfo : InvalidOperation:
(op_Division:String) [], Runt
imeException
+
FullyQualifiedErrorId : MethodNotFound
[37] PS I:\>(15/6)/(125/100)
2
A [32]-es prompt egyértelmű, 15-öt elosztunk 5-tel, 3-at kapunk, nem is akármilyen 3-at: Int32 típusút! Szemben a 15/6-tal, aminek eredménye természetesen [35]-ben Double.
Egy kicsit időzzünk el itt! Hogyan is néz ki a [34] eredményeként kapott 2,5? A tizedes elválasztására vesszőt használt a PowerShell! Viszont a [36]-ban nem szerette ezt, mert a (,) általában tömb jelzésére szolgáló operátor. Akkor vajon fog tudni dolgozni ezzel az általa kiadott 2,5-gyel? A [37]-ben azt látjuk, hogy természetesen igen! És itt jön ki a PowerShell objektumalapúságának nagy előnye! Annak ellenére, hogy a megjelenítésnél használja az aktuális gép területi beállításait, és ennek megfelelően jeleníti meg a számokat, amikor ő számol tovább egy objektummal, akkor területi beállítás-mentesen kezeli ezt. Ha sztring alapú lenne a PowerShell, hasonlóan a Linuxos/Unixos shellekhez, akkor vagy a kimenet nem venné figyelembe a területi beállításokat, vagy egy csomó sztring-hókuszpókuszt kellene elvégezni ahhoz, hogy ilyen egyszerű műveletek működhessenek. Ha mi adunk be számokat a parancssor számára, akkor mindig ponttal jelezzük a tizedesjelet, nem a területi beállítás alapján kell beírni a számokat.
Ebbe a fejezetbe tartozik még a maradékos osztás művelete, a % :
[41] PS I:\>21%5
1
[42] PS I:\>1.4%1.1
0,3
Ezzel nincs sok trükk, hiszen ez az operátor csak számokra van értelmezve, viszont nem csak egészekre, ahogy ez a [42]-ben látszik.