23:03
1/9/2012

Ruby + JavaScript = WAT?

Wesołe video na weekend. O językach programowania i ich …nieprzewidywalności:

Źródło: Destroyallsoftware.com

Przeczytaj także:


19 komentarzy

Dodaj komentarz
  1. Nawiasologia stosowana w opozycji do Strzałkologii. WHAT ?!

  2. http://www.youtube.com/watch?v=6ri1v9Xucxs ;)

  3. tymczasem C (opracowany w latach 70-tych) nadal jest najpopularniejszym językiem do pisania dużych projektów.

  4. Właściwości Javascript dają szerokie pole do popisu:
    http://sla.ckers.org/forum/read.php?24,33349,33405

  5. Staaareee ;]

  6. Absolutnie fascynujące!

  7. NaNaNaNaNaN Batman! :)))

  8. Zaskakujące dla ludzi nie znających języka. Jeśli ‘dziwne’ zachowanie jest udokumentowane to nie jest dziwne. Prawidłowa reakcja to nie ‘wat’ i kretyński śmiech, ale RTFM i ‘aha, więc tak to działa’.

  9. Powrót do przeszłości.

  10. W jednym miejscu trochę się pierdolnął, bo [] + {} to nie obiekt, tylko string “[object Object]”. Wtedy dwa pierwsze przykłady są logicznie spójne – jeżeli po lewej stronie jest tablica, to oba elementy są konwertowane do stringa,

  11. Wesołe były obrazki….
    ale jeśli chodzi o programowanie to, co to jest wat? o co chodzi z nan? itd…

    • NaN – Not a Numbera

  12. Pozwolę sobie wkleić kometarz z wykopu (autor: Sh1eldeR)

    Przy okazji []+{} autor mówi, że otrzymane [object Object] to jest obiekt. W 2:16 chyba nawet ktoś go pyta, czy to taki stringm, czy to obiekt, a autor mówi “no, that’s just an object” — czyli obiekt. To nieprawda. To jest string “[object Object]”. I jest logiczny. Wcześniej pokazał, że pusta tablica daje pusty string. Z kolei obiekty są domyślnie zamieniane na string “[object Object]” właśnie. WIęc jeśli dodamy tablicę i obiekt to mamy pusty string, a potem string “[object Object]”.

    To wszystko wydaje się bez sensu, ale mając w miarę dobrą znajomość języka można to zrozumieć i nawet uznać za “przeważnie logiczne”. Inna sprawa, że większość ludzi kodujących w JS niestety nie ma wielkiego pojęcia o języku, w którym pisze. A gdy próbujemy zintepretować bez zrozumienia, tylko stosując doświadczenie z innycj języków, to mamy WTF za WTF-em.

    Jeśli napiszemy a + b, to w JS-ie, gdy oba wyrażenia (a i b) są liczbami, będziemy mieli do czynienia z dodawaniem liczb. W przeciwnym wypadku — z zamianą wyrażeń na stringi i z łączeniem stringów (*). I o to się to wszystko rozbija. Dwie tablice to nie błąd, bo są zamieniane na puste stringi, a następnie łączone.

    Haczyk jest w przypadku gdy instrukcję rozpoczniemy od {} + cośtam. Wtedy nawet nie używamy dwuargumentowego operatora dodawania.

    Przy tablicach kolejny drobny błąd. Array(16) daje nie 16 przecinków, tylko… 15. Czemu? Bo żeby wyświetlić tablicę na ekranie, najpierw musimy zamienić ją na string. Domyślnie, tablice w JS zamieniane są na string w ten sposób(*), że łączony jest każdy element tablicy, zamieniony na string. Pusty (niezainicjalizowany) element daje pusty string. Elementy łączone są przecinkami.

    Dlatego pusta tablica to pusty string. W przypadku tablicy 16 elementów, pustych elementów, każdy element jest reprezentowany przez pusty string, a potem pomiędzy nimi są wstawiane przecinki. Stąd 15 przecinków.

    I drugi tego samego autora:

    [] + {} wyjaśniłem powyżej. Dwuargumentowy operator + działa albo jak matematyczne dodawanie, albo jak łączenie stringów. Tu mamy łączenie stringów. Pusta tablica zamieniana jest na pusty string, a obiekt na “[object Object]”.

    {} + [] wygląda podobnie, ale to coś zupełnie innego. Tu nie ma dwuargumentowego operatora +.

    Reguły parsowania JS mówią, że jeśli rozpoczynamy nową instrukcję i mamy tam {}, to jest to… nie literał obiektowy (inicjalizator obiektu, pusty obiekt), tylko… blok instrukcji. Pusty.

    Co to jest blok? Coś, czego używa się np. przy ifach:

    if (warunek) {
    zróbcoś();
    zróbjeszcze_coś();
    }

    Gdy warunek jest spełniony, chcemy wykonać dwie instrukcje i musimy ująć je w klamry — tworzymy tzw. blok.

    Blok może być pusty:

    if (warunek) {
    }

    Blok może też występować bez instrukcji if, for czy while — ot tak, po prostu:

    róbcoś();
    { // otwieramy blok
    wbloku1();
    wbloku2();
    } // zamykamy
    zablokiem();

    Taki blok nic nam nie daje, bo w JS-ie nie ma nawet blokowego zasięgu zmiennych, niemniej jednak można to zrobić.

    Taki blok również może być pusty:

    róbcoś();
    { // otwieramy blok
    } // zamykamy
    zablokiem();

    I gdy wywalimy komentarze i znak nowej linii, mamy:

    róbcoś();
    // pusty blok
    {}
    zablokiem();

    Widzisz dokąd to zmierza?

    Gdy napiszemy:

    {} + []

    Zaczynamy od pustego bloku. On nic nie robi — powiedzmy, że jest ignorowany i nie generuje żadnego stringa. Dlatego nie ma “[object Object]”.

    Dalej mamy +[]. Co to robi?

    Cóż…

    W JavaScripcie jest jednoargumentowy operator +. Łatwiej go zrozumieć, zaczynając od jednoargumentowego minusa:

    var a = -b;

    To chyba jasne: minus zamienia to, przy czym stoi, na liczbę, zmienia jej znak i zwraca. Czyli jeśli w b mielibyśmy 5, to w a będzie -5.

    Jednoargumentowy plus z kolei nie robi praktycznie nic. Poza tym, że zamienia to, przy czym stoi, na liczbę. Ściślej: próbuje zamienić. +5 daje 5. +”cośtam” da już jednak NaN, czyli Not a Number, bo nie da się stringu “cośtam” zamienić na liczbę. Z kolei +”” daje 0, bo pusty string zamieniany jest na zero (w miarę logiczne).

    Mamy więc +[]. Jednoargumentowy operator + próbuje zamienić tablicę na “wartość prymitywną”. W tym przypadku: na string. Jak opisałem w poprzednim poście, jest to pusty string. Następnie, pusty string zamieniany jest na liczbę. A to jest zero.

    I otrzymujemy w sumie zero.

    Całość rozbija się więc o to, że {} to nie jest tutaj pusty obiekt, tylko blok, a plusik to wersja jednoargumentowa.

    Zauważ proszę, że w praktyce to nam nigdy nie będzie przeszkadzalo. Bo nie zaczniemy instrukcji od {}. Zawsze będziemy tam mieli np. if ({} + []) czy wykonaj_funkcję({} + []). I tutaj już otrzymamy “[object Object]” — pusty obiekt i pusta tablica. Wystarczą do tego same nawiasy: ({} + []). Ale bez nawiasów itp. mamy blok.

    Swoją drogą, nie wiem ile % koderów JS interesuje się takimi rzeczami. Może z 5%? Cieszę się zawsze gdy widzę jedną z tych osób. Im więcej ludzi piszących JS chce się go tak naprawdę nauczyć, tym lepiej. Pozostali… cóż, dobrze, że architekci lub lekarze nie postępują tak jak oni.

    • Bardzo rzeczowy komentarz – myślę, że intencją autora prezentacji nie był flejm na js czy rubiego, tylko rozbawienie publiczności – nie warto tego traktować śmiertelnie poważnie – niekonsekwencja lub (pozorny) brak logiki zdarza się wszędzie i jeśli ktoś się chwali, że język XYZ jest od nich (niekonsekwencji, pozornego braku logiki gdzieniegdzie) wolny, to po prostu słabo go zna :) Z drugiej strony – szkoda, że autor chociaż pobieżnie nie wyjaśnił skąd takie a nie inne zachowanie wynika – na pewno łatwiej byłoby zapamiętać meandry js/rb w kontekście humorystycznego “NaNNaNNan Batman!”, niż suchego akademickiego tłumaczenia :)

  13. dziękuję @ayeo za wytłumaczenie troszeczkę jaśniej już to wygląda, zastanawiam się tylko dlaczego i w jakim celu tworzy się “puste obiekty” lub tablice… pewnie odnosiło się to do tej prezentacji.
    Mam pytanie jak włączyć taką konsole z JS? czy na windows można? a jeśli tak to jak? :)

    • @Aneta: W Firefoksie: Tools/Web Developer/Web Console (Ctrl:Shift+K). W Chromium: Tools/JavaScript Console. W innych przeglądarkach też pewnie można. Niezależnie od systemu. Po co tworzyć puste obiekty? Choćby po to, by później je czymś wypełniać.

  14. Ale się uśmiałem hehe :) Więcej takich proszę.

Twój komentarz

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.

RSS dla komentarzy: