Język Scala dla programistów PHP cz.5 – implicit conversions

Jedną ze świetnych i unikalnych cech języka Scala, której PHP nie posiada są tzw implicit conversions zwane też przez oficjalną dokumentację „widokami” (views). Podobny mechanizm zaimplementowany jest w C#, chociaż szczegółów szczerze powiedziawszy nie znam ;).Przejdźmy jednak do rzeczy. Czym jest widok/implicit conversion ? Jest to technika niejawnego rzutowania za pomocą funkcji zdefiniowanej przez użytkownika. Przydaje się ona gdy chcemy np. rozszerzyć wbudowaną w język klasę o swoje metody. Funkcję konwertującą definiujemy poprzez dodanie słowa kluczowego „implicit” przed deklaracją funkcji.

Poniżej przykład implicit conversion na wbudowanej klasie „String”, dzięki któremu dodajemy do niej znaną z PHP metodę „stripslashes”:

Najpierw definiujemy nową klasę stringów nazwaną „MyString”:

class MyString(val value: String){

  def stripslashes():String = {
    return this.value.replace("\\\\","")
    }
  }

Następnie definiujemy funkcję konwertującą:

implicit def stringToMyString(string: String) = new MyString(string)

Czas na testy. Najpierw klasycznie, bez użycia widoku:

val test1 = new MyString(" aaa \\\\ ");
println(test1.stripslashes) //wyświetli aaa

Z użyciem widoku:

val test2 = " aaa \\\\ "
println(test2.stripslashes) //wyświetli aaa

Jak widać, dzięki technice widoków możemy łatwo wzbogacać wbudowane typy (i nie tylko) o nowe funkcjonalności, czyniąc kod bardziej przyjaznym. Zasięg implicit conversion jest zależny od kontekstu w jakim został zdefiniowany – jeżeli zdefiniujemy go klasie to ma zasięg do klasy, jeżeli w paczce to do paczki.

Technika implicit conversion jest w pewnym stopniu podobna do zgłoszonego kiedyś do PHP ficzeru zwanego autoboxingingiem, z tą różnicą, że mechanizm implicit conversions jest mniej „magiczny” oraz ma wyraźne granice zasięgu działania. Uważam, że jest również lepszy od otwierania klas znanego z języka Ruby, oraz Javascriptowego przyłączania metod do prototypu, z powodów takich samych jak wymienione wcześniej.

A wy co o tym sądzicie ?

  1. wookieb pisze:

    Dla mnie jak zawsze w przypadku Scali, Bomba :)
    Tylko zastanawia mnie jak bardzo ciężki jest mechanizm wykrywania w którym obiekcie jest nieodnaleziona metoda. Jak zapewne się domyślam lista takich metod jest mapowana w momencie utworzenia konkretnej funkcji implicit def.

  2. wookieb pisze:

    P.s. Pokaż ludziom potęgę „_” przy tworzenie literałów funkcji w różnych przypadkach to porzucą ruby w ten sam dzień :)

  3. @wookieb: o literałach na pewno będzie, ale trochę czasu upłynie zanim do nich dojdziemy, bo Scala to naprawdę bogaty język, co do wykrywania, z tego co wiem to się dzieje w czasie kompilacji, także nie ma żadnego wpływu na kod wynikowy.

  4. Theq pisze:

    Zgadza się, dzieje się to na etapie kompilacji. Czyli np. kod „2.years ago” jest tłumaczony na „intToPeriod(2).years.ago”, gdzie intToPeriod to nasza funkcja konwertująca.

  5. theq, wookieb a jak sądzicie, taki ficzer przydałby się w PHP ?

  6. Theq pisze:

    Można dodać, ale imho to będzie taka pierdółka bez większego znaczenia 😀 W końcu co za róźnica, czy zrobisz „hello there”.toupper(), czy strtoupper(„hello there”). Do tego to język dynamicznie typowany i już widzę te błędy w runtime. Jak na razie jedynym ciekawym zastosowaniem, jakie widziałem to DSLowy sposób zabawy datami, czyli „1.year and 2.months ago” zwraca mi odpowiednią datę.

  7. No może pierdółka, ale dla mnie to jest wygodniejsze osobiście :), zresztą było już RFC o „autoboxingu”

  1. There are no trackbacks for this post yet.

Leave a Reply

Informuj mnie o odpowiedziach poprzez e-mail. Możesz również subskrybować wpis bez zostawiania komentarza.