Dolar-daszek, dolar-dolar

dolar-daszekDziś krótki wpis o dwóch zmiennych, którym nie poświęciłem zbyt wiele uwagi gdy usłyszałem o nich po raz pierwszy. Wówczas nie widziałem dla nich kompletnie żadnego zastosowania. Dziś nie mam już wątpliwości: ich przydatność jest tylko kwestią wyobraźni użytkownika i choć w zasadzie ogranicza się ona do interaktywnej konsoli, to będąc jej stałym użyszkodnikiem – nie wyobrażam sobie jak mogłem kiedyś sobie bez tych dwóch zmiennych radzić. Zmienne mają bardzo krótkie nazwy, dzięki czemu korzystanie z nich nie wymaga wielu znaków: wystarczy standardowy znak dolara (oznaczającego zmienną) i jednoznakowa nazwa: dolar lub "daszek".

Nazwy obu zmiennych są żywcem "zerżnięte" z wyrażeń regularnych: tam też właśnie początek ciągu znaków oznaczymy "daszkiem" a jego koniec – znakiem dolara. Nie dziwi więc fakt, że właśnie zmienna o nazwie "^" odpowiada pierwszemu a zmienna o nazwie "$" ostatniemu elementowi uprzednio uruchomionego polecenia. Postem tym chcę Wam przybliżyć kilka codziennych lub prawie codziennych scenariuszy, kiedy z obu zmiennych zdarza mi się skorzystać. Sam przekonałem się, jak szybko od "po kiego grzyba mi takie cuś?" przeszedłem do "o mamo, znów przyda mi się jedna z drugą…".

Do rzeczy

Pierwszy przykład to niemal codzienność w moim wypadku. Nigdy chyba nie pojmę czemu autorzy PowerShell ISE tak zmasakrowali w nim funkcję, przy pomocy której możemy dowolny plik otworzyć we wbudowanym edytorze. Ani to-to nie umie przyjąć danych z "rurki", ani pliku nieistniejącego uprzednio nie utworzy (niechby nawet spytało, czy taki był mój zamiar – a nie, od razu wyjątkami sypać…). Ale na ogół nie chce mi się zachowania tego zmieniać, by nie być uzależnionym w tym od tego, co ISE podpowie mój profil. Często więc moja historia wygląda następująco:

psedit MojNowyPlik.ps1
New-Item $$
psedit $$
view raw psedit.ps1 hosted with ❤ by GitHub

W tym wypadku zmienna "$" zwalnia mnie z konieczności wpisywania tej samej nazwy kilkakrotnie, czy operowania na historii poleceń.

Przykład z drugiej strony: ostatnio próbowałem zrozumieć, czemu plik testujący mój moduł zwraca ciągle błędy. Aby to zrobić chciałem skorzystać z wbudowanego w PowerShella debuggera. Debugger ten ma kilka ciekawych możliwości, ale ja na ogół korzystam z rozwiązania najprostszego – ustawiania "breakpointa" tuż nad linią, gdzie coś się zaczęło kitwasić. I znów: mógłbym się pewnie posłużyć historią, ale z pomocą przyjdzie mi "daszek":

.\PesterTests\MojaFunkcja.Tests.ps1
# Błąd w linii 131...
sbp $^ 130
# Z aliasowego na nasze...
Set-PSBreakpoint -Script .\PesterTests\MojaFunkcja.Tests.ps1 -Line 130
view raw sbp.ps1 hosted with ❤ by GitHub

Inny przykład: właśnie uruchomiłem skrypt, działa jak ta lala, więc pora dodać go w gicie, by później (już z czystym sumieniem) przesłać dalej. I znów: bez daszka nie podchodź, zwłaszcza jak skrypt ma kilka parametrów, których naturalnie przy tej operacji nie chcemy podawać…:

.\Get-FolderReport.ps1 -Path C:\temp -Depth 3 -Verbose
git add $^
view raw gitadd.ps1 hosted with ❤ by GitHub

Przykłady można mnożyć, ale najlepiej spróbować samemu… Czytając o tym dojdziecie pewnie do podobnych jak ja wniosków – toż to prościej można zrobić… Spróbujcie a przekonacie się szybko, że to jest jak narkotyk. Tylko jedno pytanie: jak to działa? I o co właściwie w tym wszystkich chodzi? Cóż, wolałem zacząć od przykładów, teraz pora na teorii ździebko.

Jak to tak…?

Zmienna "^" odnosi się do pierwszego elementu w uprzednio uruchomionym poleceniu. Analogicznie: "$" zawierać będzie ostatni element polecenia, które przed chwilką uruchomiliśmy. Sytuacja komplikuje się nieco, jeśli ten element zawierał jakieś rozbudowane wyrażenie, jak choćby ciąg znaków otoczony cudzysłowem ze zmiennymi. Dlaczego? Bo obie zmienne zawierać będą wersję bez rozwiniętych zmiennych, ciężko więc będzie uzyskać identyczny wynik. Dla przykładu:

echo "$($PSVersionTable.PSVersion.Major) testuję zmienną $ $"
# wynik: 5 testuję zmienną $ $
"$$"
# wynik: $($PSVersionTable.PSVersion.Major) testuję zmienną $ $
# Aby uzyskać identyczny wynik musielibyśmy zamiast tego użyć:
$ExecutionContext.InvokeCommand.ExpandString($$)
view raw DolarDolar.ps1 hosted with ❤ by GitHub

Mają więc obie zmienne swoje ograniczenia, o które zdarza mi się okazjonalnie "potknąć". Ale nie ukrywam, że nadal ilość sytuacji, w których ze zmiennych tych korzystam, jest znaczna. Małe, a cieszy… Smile

~ - autor: Bartek Bielawski w dniu 15 lutego, 2017.

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie na Google

Komentujesz korzystając z konta Google. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s

 
%d blogerów lubi to: