Nowości i zmiany w Ruby 1.9 #2 - nowa składnia Hasha
5 komentarzy | Kategorie: Ruby, Techblog | trackbackTagi: 1.9 ruby ruby1.9
Wpis ten jest jedną z części cyklu pt "Nowości i zmiany w Ruby 1.9". Pełną listę wpisów znajdziesz pod adresem http://radarek.jogger.pl/2008/11/30/nowosci-i-zmiany-w-ruby-1-9/.
Tym razem chciałbym pokazać Wam nową zmianę w składni języka, która dotyczy także Hasha. Zmiana ta dotyczy nowej składni dla literału hasha, którego kluczami są symbole. Do tej pory taki hash definiowaliśmy w następujący sposób:
h = {:foo => 1, :bar => 2}
p h
# => {:foo=>1, :bar=>2}
Od wersji 1.9 można to zrobić trochę inaczej
h = {foo: 1, bar: 2}
p h
# => {:foo=>1, :bar=>2}
Jeszcze raz podkreślam, że nową składnię można zastosować tylko jeśli kluczami są symbole. Dla innych kluczy musisz użyć dotychczasowej składni. Wykonując mały eksperyment możesz przekonać się, że można równocześnie stosować nowy i stary sposób...
h = {foo: 1, bar: 2, "baz" => 3}
p h
# => {:foo=>1, :bar=>2, "baz" => 3}
...jednak z oczywistych powodów odradzam takie praktyki.
Przekazując hash jako jedyny lub ostatni parametr metody można ominąć nawiasy {}. Dzięki temu zyskujemy na czytelności bo zamiast
User.find(:all, {:order => "login", :limit => 5})
możemy napisać
User.find(:all, :order => "login", :limit => 5)
a stosując nową składnie
User.find(:all, order: "login", limit: 5)
Prawda, że przejrzyście to wygląda? A dwukropek dużo łatwiej się stawia niż znak "spacja, znak równości, znak większości".
Parametry nazwane - czy to już to?
Niektóre języki (np. Python) posiadają obsługę tzw. nazwanych parametrów. Dzięki temu wywołując możemy takie parametry podać w dowolnej kolejności. Od strony wywołania wygląda to podobnie jak ostatni przykład. Wbudowana obsługa takich parametrów pozwala na weryfikację przekazanych parametrów przez sam język. Dzięki nowej składni hashy możemy w pewien sposób symulować takie parametry, ale musimy wykonać dodatkową pracę by zweryfikować przekazane klucze.
Na pełną obsługę parametrów nazwanych musimy niestety poczekać przynajmniej do wersji 2.0.
Mała zmiana a cieszy oko :)
Fajnee, podoba mi się :) tylko trochę szkoda że w środku funkcji dalej trzeba tego hasha options ręcznie wyciągać, a nie jak w Pythonie…
Ostatnio przeglądałem zmiany wprowadzone w Pythonie 3.0. Wszystko zostało przedyskutowane i przemyślane. Język stał się jeszcze bardziej spójny. Super!
Jak wygląda to w Ruby? Weźmy nowego Hasha. Można po staremu i nowemu. Czym się różni stare od nowego? Tym że dwukropek damy po, a „strzałkę” opuścimy. Niezwykle przydatna zmiana. Ale hola, hola! Należy pamiętać dodatkowo że nową składnie można stosować tylko dla kluczy będących symbolami. Żeby było jeszcze ciekawiej oba sposoby można mieszać!
N sposobów na pętlę while, M na pętlę for. Różne nazwy na metody dające taki sam wynik. Różne sposoby na wykonanie jednej czynności. Zaczyna się robić niezły śmietnik. Nie ułatwia to w żaden sposób czytania kodu. Skąd mam pewność że metoda size i length zwracają to samo. Może pierwsza zlicza elementy nilowe a druga nie? Nie mam wyjścia muszę zobaczyć do dokumentacji! Okazuje się że obie metody służą dokładnie do tego samego. Do zliczania elementów nienilowych służy metoda o jakże intuicyjnej nazwie nitems.
Jestem zdania że język Ruby nie jest przygotowany na sukces jaki odniósł. Czekam na wydanie 2.0. Całą sytuację ratuje community, dostępne narzędzia i wiele ciekawych projektów :) Sam język jest ciekawy pod względem teoretycznym ale do The Zen of Python się nie umywa IMHO.
Z „Zen of Python” nie podoba mi się jedna rzecz: explicit is better than implicit… Bo według mnie explicit „self” nie jest better than implicit :) Najbardziej explicit to jest Java, ale wydawało mi się że właśnie od tego uciekaliśmy…
hm, nie da się ukryć, że nie wszystkie zmiany są dobre, a część z nich sprawia wrażenie jakby nieprzemyślanych. Niestety nigdy tak nie będzie, że wszyscy będą zadowoleni. Przykładowo o nowej składni dla Hashy większość komentarzy jest pozytywnych. Oczywiście, można się zastanowić czy ta zmiana była warta, ale jednoznacznej odpowiedzi nie uzyskamy. Pewne jest to, że twórcy języka nie przeszkadza „powielanie” rzeczy. Cóż, osobiście mogę z tym żyć :).
Python sprawia wrażenie lepiej prowadzonego języka, ale też nie jest bez wad. To o czym wspomniał choćby Psi też mnie irytuje.
Wracając jednak do Rubiego. Jakby popatrzeć na suche fakty, to można nawet pomyśleć, że język gorszy niż php ;-). Mogę zmienić praktycznie wszystko (nadpisać istniejące metody w każdej klasie), dodać metodę tylko do konkretnego obiektu (przez co tylko jeden konkretny obiekt będzie zachowywać się inaczej), mogę robić aliasy do tej samej metody (przy czym nadpisanie metody powoduje zasłonięcie tylko jednej z nich), usuwać wybrane metody (undef_method :foo), nadpisywać, usuwać stałe (Object.send(:remove_const, „Array”)). Można tak długo wymieniać.
Kiedyś na prezentacji Rubiego (SFI 2008) Chad Fowler powiedział „Sometimes it’s ok to be weird” (http://www.flickr.com/photos/leobard/2333834948/in/set-72157604067113071/) i podpisuję się dwoma rękoma. Piękno Rubiego polega na tym, że odpowiednio wyciągając i układając te różne dziwactwa tworzymy piękne rzeczy. Przykład?
Nawiasy Rubiego. Można je opuszczać, ale nie trzeba. Zatem puts(„Hello”) jest równoważne puts „Hello”. Wkurzające, prawda? Szkopuł tkwi w szczegółach. Chodzi o to by konsekwentnie, w zależności od sytuacji użyć takiej a nie innej formy. Railsy nam pokazały piękny przykład:
Myślę, że nie trzeba tłumaczyć, która forma jest preferowana, a wręcz „jedyna słuszna”.
Piękno Rubiego polega na tym, że język nie narzuca takich rzeczy. To już robi społeczność kreując pewien styl Rubiego.