Małe kruczki

2010-11-22 8:31

Przeskakując między wieloma językami programowania, bibliotekami czy frameworkami po pewnym czasie można wyrobić sobie zdolności “uogólniające”, dzięki którym takie zmiany nie są specjalnie kłopotliwe. Jednak nawet jeśli potrafimy płynnie przechodzić od jednego języka do drugiego, to zawsze istnieje szansa, że zapomnimy przy okazji o jakimś szczególe, drobnej rzeczy specyficznej dla konkretnego narzędzia – tytułowym małym kruczku.
A przynajmniej mi się tak nierzadko zdarza. Dlatego tę notkę dedykuję pojedynczym, drobnym a “dziwnym” cechom poszczególnych języków programowania, o których często zdarza mi się zapominać. A są one następujące:

  • W C++ nie dodaje się stałych tekstowych. W dziesiątkach języków programowania (i nie tylko programowania) zapis w stylu "ala" + " ma " + "kota" jest najzupełniej oczywistą konkatenacją trzech napisów. Ale w C++ nie. Ponieważ stałe dosłowne, takie jak teksty w cudzysłowach, są – w przybliżeniu – typu const char*, ich łączenie operatorem + jest interpretowane jako dodawanie dwóch wskaźników. Serio.
    Wniosek: W C++ w takich sytuacjach plus jest zbędny i należy go pominąć "ala" " ma " "kota", o ile oczywiście nie łączymy obiektów klasy string.
  • W Javie łańcuchy znaków porównujemy… inaczej. Otóż Java jest bardzo obiektowa i w związku z tym nawet dla typu java.lang.String nie robi wyjątku i obsługuje go tak, jak każdą inną klasę. A to oznacza, że zwykły operator == działa dla napisów tak samo, jak dla innych obiektów (inaczej niż choćby w C#), tj. porównuje ich referencje w celu sprawdzenia, czy mamy do czynienia z tym samym obiektem. Tym samym, nie zaś takim samym, czyli równym co do wartości – a o to nam zwykle chodzi, gdy pracujemy z napisami.
    Wniosek: W Javie do porównywania napisów korzystamy z metody equals. To pewnie dlatego wciąż nie ma w niej switcha dla napisów ;-)
  • Słowniki w Pythonie domyślnie “iterują się” po kluczach. Żeby oszczędzić nadmiernie rozbudowanych wyjaśnień, rzucę poniższym kawałkiem kodu:
    1. for k, v in dictionary: print k, " => ", v

    który na pierwszy rzut oka wygląda na zupełnie poprawną iterację po zawartości słownika dictionary, w której zmienna k dostaje klucz, a v wartość. Jest on dowodem, że oczami należy rzucać zawsze przynajmniej dwa razy. W istocie bowiem k i v będą kolejno otrzymywały, uwaga, po dwa elementy klucza (potraktowanego jako para). Po prostu konwersja słownik → coś_po_czym_można_iterować daje w Pythonie kolekcję kluczy, a nie par klucz-wartość. Nie pytajcie, dlaczego.
    Wniosek: Albo iterujemy po kluczach i wartość uzyskujemy zwykłym indeksowaniem, albo korzystamy z metody items w celu uzyskania kolekcji par klucz-wartość.

  • W Javascripcie zmienne – nawet te użyte po raz pierwszy w funkcjach – są domyślnie globalne. Nawet nie śmiem dociekać, co jest uzasadnieniem dla tego faktu…
    Wniosek: Pierwsze przypisanie do nowej zmiennej wewnątrz funkcji należy opatrywać słowem kluczowym var.
Tags: , , , ,
Author: Xion, posted under Programming »


7 comments for post “Małe kruczki”.
  1. brodny:
    November 22nd, 2010 o 13:27

    Podobny kruczek występuje przy korzystaniu z polimorfizmu (konkretniej metod wirtualnych). C++, C#, Delphi wymagają jawnego podania modyfikatora virtual, natomiast Java traktuje wszystko jako metody wirtualne (co imho w C# też powinno być domyślnym zachowaniem, ale co ja tam wiem :) )

  2. kombain:
    November 23rd, 2010 o 21:11

    Ja często łapię się na porównywaniu operatorem == napisów w Javie;) Ot, takie przyzwyczajenie z C#

  3. dynax:
    November 24th, 2010 o 15:31

    Ta pierwsza właściwość C++ od zawsze strasznie mnie denerwowała. Co gorsze, nie wiedziałem, że łączenie stałych stringów w zaprezentowany sposób (“ala” “ma” “kota”) jest w ogóle dopuszczalne, co zmuszało mnie do tworzenia potworków w tylu:

    DoSomething((std::string("ala") + "ma" + "kota").c_str());

  4. Kamil Szatkowski:
    December 10th, 2010 o 1:07

    Akurat jakkolwiek w C++ może się to wydawać niewygodne, to jednak jest to bardzo fajna cecha języka, że siedzisz blisko reprezentacji danych w pamięci.
    Jeśli potrzebujesz większej abstrakcji to lepiej rozważyć inny język, np. C#.

  5. Kos:
    December 20th, 2010 o 17:51

    Xion, co to jest to ostatnie? Ostatnio, jak sprawdzałem, to każdą nową zmienną deklarowało się w ecmascriptach słówkiem “var” :)

  6. Kos:
    December 20th, 2010 o 17:57

    Notka o Pythonie też zła: jeżeli będziesz iterował w sposób, jaki pokazałeś, to będzie to *zwykła iteracja po kluczach* – a każdy klucz będzie następnie traktowany jako `iterable` i rozpakowywany do zmiennych (k,v).

  7. Xion:
    December 21st, 2010 o 9:07

    @Kos: Fakt, masz rację, takie właśnie będzie zachowanie przy iterowaniu. Tak czy siak jest ono niezgodne z oczekiwanym :) (A tekst w notce oczywiście poprawiłem)

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.