Opublikowane przez Jarosław Zabiełło
Sat, 21 Nov 2009 03:43:00 GMT
Gdy ok 1.5 roku pisałem o szumie i nadziejach związanych z MagLev’em, trudno było przewidzieć ile czasu zajmie dostosowanie wirtualnej maszyny Smalltalka do pracy z kodem bajtowym Ruby’ego. Dziś (właściwie to jakieś 2 godziny temu) oficjalnie ogłoszono że jest dostępna publicznie pierwsza wersja alpha. Z tego, co podaje dokumentacja, to Maglev jeszcze nie działa tam gdzie są wymagane rozszerzenia w C, ale w przykładach widać, że działa Sinatra, Rack, RubyGems czy interaktywna konsola. Najciekawsza jest transakcyjna, przezroczysta pamięć stała MagLev’a, bo to zupełnie zmienia styl myślenia i pracy z danymi. Może będzie można w końcu zapomnieć o przestarzałych ORM’ach i RDBMS? (technologia baz relacyjnych pochodzi z lat 70-tych, jest wolna i przestarzała).
Ruby everywhere – czyli najważniejsze implementacje Ruby’ego:
- Ruby 1.8 MRI – implementacja w języku C (najstarsza)
- Ruby Enterprise Edition – implementacja w C, mniejsze zużycie pamięci, używana głównie z Passengerem
- Ruby 1.9 – implementacja w języku C, używa wirtualnej maszyny YARV
- JRuby – implementacja w języku Java, wirtualna maszyna Javy (JVM)
- IronRuby – implementacja w języku C# (środowisko .NET)
- Maglev – implementacja w języku Smalltalk, wirtualna maszyna Smalltalka (Gemstone)
- MacRuby – implementacja w języku Objective-C dla systemu Mac OS-X
- Rubinius – implementacja Ruby w… Ruby (z loaderem w C++)
- BlueRuby – Ruby działający w SAP Web Application Server (ABAP Virtual Machine)
Zobacz też State of Ruby VMs: Ruby Renaissance
Tagi gemstone, jruby, maglev, ruby, smalltalk | 8 comments
Opublikowane przez Jarosław Zabiełło
Sat, 14 Jun 2008 17:11:00 GMT
Gemstone to komercyjna, rozwijana od ponad 20 lat, bardzo szybka maszyna wirtualna dla języka Smalltalk. Jest używana od lat w zastosowaniach biznesowych, m.in. w instytucjach finansowych. W odróżnieniu od innych Gemstone to coś więcej niż tylko maszyna wirtualna. Gemstone posiada wbudowany mechanizm bardzo wydajnego, transakcyjnego zapisu obiektów, chodzi to obsługę obiektów rzędu setek i tysięcy miliardów (lub informacji o wielkości 17 petabajtów). MagLev to smalltalkowy GemStone S64 VM z dodanym bytecodem pozwalającym na uruchamianie Rubiego. W różnych benchmarkach MagLev jest szybszy od Rubiego MRI od 7 do ponad 100 razy i osiąga szybkość zbliżoną do czystego C. Dodatkowo daje przezroczysty, wydajny zapis obiektów Rubiego w sposób znacznie wygodniejszy od tego co oferują relacyjne bazy danych. Czyżby wkrótce można było pokusić się o napisanie odpowiednika Zope w Rubim pracującym pod wydajną, wirtualną maszyną Smalltalka?
Czytaj dalej...
Tagi gemstone, maglev, rails, ruby, smalltalk, vm | 6 comments
Opublikowane przez Jarosław Zabiełło
Wed, 22 Nov 2006 01:26:00 GMT
Każdy, kto zajmował się kiedykolwiek programowaniem stron internetowych wie, że protokół HTTP jest bezstanowy. Innymi słowy, każde przeładowanie strony internetowej generuje kompletnie niezależne wywołanie serwera i nie ma on możliwości aby powiązać wywołanie z konkretnym klientem. Aby temu zaradzić, wprowadzono prostą sztuczkę. Wprowadzono tzw. mechanizm cookies (dosł. ciasteczek), malutkich plików które serwer może wysyłać do klienta (tam i z powrotem). Ten unikalny identyfikator (sesji) można też trzymać w adresie URL, ale ta metoda jest zdecydowanie odradzana z powodu łatwości nadużyć (łatwo wykraść taki numer i podszyć się pod autora) Od strony klienta jedynym wymaganiem jest aby nie blokował sobie w przeglądarce mechanizmu cookies.
Serwer znając identyfikator sesji, może związać z nim szereg danych, np. aktualną listę zamawianych produktów włożonych do koszyka w sklepie internetowym. Dane te zwykle trzyma się w bazie lub w pamięci operacyjnej. Oczywiście czas życia danych jest ustalany przez serwet i w normalnym wypadku są one cyklicznie kasowane. (Z tym “normalnym” wypadkiem to różnie bywa, bo wiele frameworków tego nie zapewnia i trzeba samemu o to zadbać)
Mechanizm sesji jest dosyć wydajny, bo zapytania wysyłane do serwera mogą być obsługiwane asynchronicznie, czyli bez żadnych blokad w oczekiwaniu na ukończenie obsługi zapytania. Przez lata “stanowość” protokołu HTTP zapewniało się właśnie za pomocą sesji.
Ten mechanizm ma jednak swoje wady. Największą jest złożoność jaką wprowadza po stronie skryptów na serwerze. (I to nie jest wcale taka trywialna sprawa jak to można było zaobserwować u developerów frameworka CherryPy którzy miesiącami nie potrafili napisać stabilnie działającego mechanizmu obsługi sesji.)
Kontynuacje
Kompletnie innym podejściem jest skorzystanie z tzw. mechanizmu kontynuacji. Mechanizm ten podobny jest do gracza, który w dowolnym momencie może zapisać i wczytać stan gry. Kontynuacje zapewniają taki mechanizm zapisu stanu programu aby w dowolnym momencie później go przywrócić. Niektórzy porównują to do maszyny czasu, bo można w dowolnym momencie przywrócić wcześniejszy stan aplikacji.
Zalet z takiego podejścia jest wiele. Weźmy np. sprawę obsługi “nieśmiertelnego” przycisku Back w przeglądarce. Obsługa tego przycisku sprawia spore problemy. Programiści najchętniej w ogóle by go zablokowali. W wypadku kontynuacji ten problem w ogóle nie istnieje. Kliknął ktoś Back aby cofnąć się do poprzedniej strony? Żaden problem. Serwer przywróci cały wcześniejszy stan aplikacji bez żadnego problemu. I to w sposób przezroczysty dla programisty! Programowanie stron webowych staje się znacznie prostsze, niczym tworzenie aplikacji desktopowej włącznie z debugowaniem krok po kroku. Wg różnych prognoz, tak będziemy programować serwisy internetowe za kilka lat!
Sama idea nie jest najwyraźniej jeszcze powszechnie znana, skoro w rozmowie z developerami irlandzkiego Google, zaskoczyłem ich informacją na ten temat. Kto wie, czy Google mocniej nie zainwestuje w Rubiego (aktualnie mocno korzysta z Pythona, który jest podstawą większości ich skryptów).
Smalltalk i Seaside
Smalltalk jest bardzo starym językiem bo jego początki sięgają lat 70-tych. Od zawsze był językiem w pełni obiektowym i dynamicznym. To m.in. Smalltalk pierwszy wymyślił wirtualną maszynę której to ideę później skopiowali twórcy Javy. W Smalltalku napisano najlepszy (w chwili obecnej) na świecie serwer kontynuacyjny – Seaside.
Czy to spowoduje renesans na Smalltalka? Osobiście w to wątpię. Główną wadą Smalltalka jest jego monolityczność i hermentyczność. Uruchamiając środowisko Smalltalak uruchamia się cały, zamknięty świat Smalltalka. Np. nie ma tam dostępu do plików z zewnątrz tak, jak w innych językach. To spowodowało, że język ten, mimo pewnych sukcesów, nigdy nie zdobył sobie powszechnego uznania. I moim zdanie, nigdy już nie zdobędzie, bo w międzyczasie wyrosła mu młoda, obiecująca konkurencja.
Ruby
Ruby jest językiem relatywnie młodym. Tzn. został po raz pierwszy udostępniony publicznie w tym samym roku co Java – 1995. Ale przez większość lat był mało znany poza Japonią (skąd pochodzi jego twórca). Ruby jest także jednym z tych nielicznych języków, które (podobnie jak Smalltalk) posiadają wbudowaną obsługę kontynuacji. Istnieją co prawda różne próby implementacji tego mechanizmu w Javie1, ale tylko Ruby posiada ten mechanizm jako coś naturalnego i nie trzeba stosować żadnych specjalnych sztuczek aby go emulować. Z tego co pamiętam, Seaside pierwotnie był tworzony w Ruby, ale w tamtym okresie, kontynuacje w Ruby były jeszcze niedojrzałe, więc twórcy przerzucili się na Smalltalka. Ruby jednak szybko się rozwija, nabiera dojrzałości i moim zdaniem, ma bardzo duże szanse, aby wyprzedzić pozostałe języki przy tworzeniu serwisów internetowych nowej generacji, serwisów opartych na kontynuacjach.
Przykład kontynuacji.
Poniższy przykład2 pokazuje implementację generatora za pomocą kontynuacji.
class Generator
def initialize
do_generation
end
def next
callcc do |here|
@main_context = here;
@generator_context.call
end
end
private
def do_generation
callcc do |context|
@generator_context = context;
return
end
generating_loop
end
def generate(value)
callcc do |context|
@generator_context = context;
@main_context.call(value)
end
end
end
A oto oparty na nim generator ciągu liczb Fibbonacciego:
class FibGenerator < Generator
def generating_loop
generate(1)
a, b = 1, 1
loop do
generate(b)
a, b = b, a+b
end
end
end
fib = FibGenerator.new
15.times { print "#{fib.next} " }
1 Np. Riff lub Jetty 6.
2 Przykład z książki “The Ruby Way”, 1ed.
Posted in Ruby, Java, SmallTalk | Tagi continuations, java, ruby, smalltalk | 23 comments
Opublikowane przez Jarosław Zabiełło
Sun, 14 May 2006 04:22:00 GMT
Niektórym osobom stykającym się z po raz pierwszy z Railsami wydaje się, że jest to tylko jakieś kolejne, tradycyjne środowisko developerskie pracujące wg wzorca projektowego MVC (model-widok-kontroler). Przywiązani do swoich języków i frameworków czasami się dziwią, dlaczego temat Railsów wywołuje od jakiegoś czasu tyle emocji i komentarzy.
Na pewno po częsci jest tak pewnie dlatego, że RoR jest bardzo dobrze wypromowany. Dobra strona główna, dobra dokumentacja, książki, filmy, bardzo aktywna społeczność – nic tylko naśladować. Z drugiej strony, trzeba też przyznać, że jest to środowisko świetnie zaprojektowane – w Railsach sie pracuje po prostu komfortowo.
Nie dziwią więc ciągłe próby naśladowania Railsów w innych językach (PHP, Python, Java, C# itp) Jednakże między nimi a Railsami będzie ciągle pewna, trudna do osiągnięcia, jeśli nie w ogóle niemożliwa – bariera. Railsy posiadają nie tylko wszystko, co potrzeba do bardzo produktywnego tworzenia aplikacji internetowych, ale są przy tym równocześnie bardzo eleganckie i czytelne. Eleganckie i czytelne czyli łatwe do nauki. Tak, nauka Rubiego nie jest przeszkodą. Przekona się o tym każdy, kto trochę bliżej przyjrzy się jak działa RoR.
Miałem okazję porównywać ze sobą kilka różnych frameworków. Gdy chciałem przekonać się do któregoś z nich, zawsze ostatecznie wracałem z powrotem do RoR. Po prostu żaden z nich nie jest jak elegancki i prosty w użyciu1. Co jest główną przyczyną takiego wrażenia? Twórca Railsów, David Heinemeier Hansson powiedział kiedyś, że gdyby nie Ruby to nie powstałby Ruby on Rails. Powiedział także, że uważa iż w żadnym innym języku nie da się napisać tak eleganckiego i pięknego kodu. Zatem można powiedzieć, że prawdziwą siłą Railsów jest Ruby. Razem tworzą nierozłączną parę i ta łączność nie dotyczy bynajmniej tylko nazwy. ;) Ruby posiada bowiem pewne unikalne cechy, które pozwoliły stworzyć RoR w postaci, która jest raczej mało nieosiągalna dla innych języków. Już to wyjaśniam.
Panuje powszechnie mniemanie, że Ruby to połączenie cech Pythona i Perla. Ruby (podobnie jak Perl) posiada np. wbudowaną w składnię obsługe wyrażeń regularnych. Posiada także (podobnie jak Python) pełną obiektowość i bardzo elegancką, czytelną (choć nie taką samą) składnię. Pewnym odkryciem było dla mnie to, że językie, do którego Ruby ma najwięcej podobieństw to innego języka – Smalltalk. Lektura cech, filozofii (i nawet do pewnego stopnia składni) Smalltalka pokazuje zdumiewające podobieństwo do Rubiego. Można wręcz odnieść wrażenie, że Ruby to swego rodzaju przeróbka Smalltalka2. Podobieństw jest bardzo wiele. Od słów kluczowych po symbole, sposób tworzenia instancji klas, bloki kodu (ang. closures), kontynuacje3 itp. Jak ktoś jeszcze nie rozumie filozofii Rubiego, jego modelu obiektowego i powodu istnienia otwartych klas, powinien poczytać sobie trochę o Smalltalku.
Ruby jak i Smalltalk posiadają bardzo podobny model obiektowy. Wszystkie obiekty (na drodze dziedziczenia) wywodzą się z jednej, ostateczniej klasy Object. Oba języki mają zaimplementowaną pełną obiektowość. Nie ma (tak ja w Javie) podziału na prymitywy i typy referencyjne. Wszystko jest obiektem i wszystko posiada metody. Dotyczy to nie tylko liczb i napisów ale także obiektu nil, true czy false. Każdy obiekt można przeciążyć i/lub zmodyfikować wewnetrznie (dynamicznie dodając lub usuwając jego metody w trakcie pracy programu)
Z tego wynika, że właściwie to można modyfikować sam język. Daje to możliwości zupełnie nieosiągalne nawet dla tak dobrego i obiektowego języka jakim jest Python. Ruby pozwala na łatwe dodawanie nowych metod do liczb czy napisów. Pozwala na taką modyfikację samego siebie, aby optymalnie nadawał się do realizacji pewnych, specyficznych zadań. Ruby umożliwia zatem tworzenie tego, co się określa mianem języków domenowych (Domain-specific Programming Languages). Są to języki, które w przeciwieństwie do języków ogólnego zastostosowania, zostały zaprojektowane do wykonywania specyficznego zadania/zadań. Zarówno Smalltalk jak i Ruby pozwalają na tworzenie języków domenowych.
Ruby on Rails to nic innego jak framework napisany za pomocą Rubiego zmodyfikowanego w celu uzyskania wysoce produktywnego środowiska do tworzenia nowoczesnych aplikacji internetowych.
Przykładowe helpery dostępne w Rails, które korzystają z nowych metod nie będących standardową częścią Rubiego. Poniższe przykłady pochodzą z 1-g wydania książki Agile Web Development in Rails.
puts 20.bytes
puts 20.kilobytes
puts 20.megabytes
puts 20.gigabytes
puts 20.terabytes
puts 20.minutes.ago
puts 20.hours.from_now
puts 20.weeks.from_now
puts 20.months.ago
now = Time.now
puts now
puts now.ago(3600)
puts now.at_beginning_of_day
puts now.at_beginning_of_month
puts now.at_beginning_of_week
puts now.at_beginning_of_year
puts now.at_midnight
puts now.change(:hour => 13)
puts now.last_month
puts now.last_year
puts now.midnight
puts now.monday
puts now.months_ago(2)
puts now.months_since(2)
puts now.next_week
puts now.next_year
puts now.seconds_since_midnight
puts now.since(7200)
puts now.tomorrow
puts now.years_ago(2)
puts now.years_since(2)
puts now.yesterday
puts "cat".pluralize
puts "cats".pluralize
puts "erratum".pluralize
puts "cats".singularize
puts "errata".singularize
Z racji tego, że Railsy zmodyfikowały Rubiego do realizacji swoich zadań, uważam, że próba sklonowania tego środowiska w jakimś innym języku (poza Smalltalkiem), jest z góry skazana na niepowodzenie. Po prostu nigdy to nie będzie tak piękny kod jak Ruby dla Railsów. Na otarcie łez dla pythonistas, mogę powiedzieć, że przy wszystkich zaletach Rubiego, nadal uważam że Python (jako język) jest nie tylko łatwiejszy do opanowania ale także bardziej produktywny. Ale jeśli chodzi o frameworki, to Rails jest nie do pobicia jeśli chodzi o komfort, możliwości i DRY[4].
—
1 Zupełnie identyczne wrażenia prostoty jak z Railsami miałem w przypadku szukania dobrego systemu CMS’a. Taki np. pythonowy Plone w porównaniu do ezPublish i całej masy innych, pehapowych rozwiązań jest nie tylko poteżniejszy ale także niezrównanie prostszy i wygodny (po 5 minutach od instalacji, praktycznie bez czytania dokumentacji i bez znajomości Pythona, można stworzyć prosty serwis o całkiem przyzwoitej, podstawowej funkcjonalności)
2 Smalltalk posiada tylko 5 słów kluczowych i proste zasady: wszystko jest obiektem, wszystkie operacje polegają na przesyłaniu metod (nazywanych tu: wiadomościami) między obiektami. Moim zdaniem Smalltalk trochę przesadził z tą zasadą, bo nawet bo zamiast do sterowania kontrolą kodu używane są także wiadomości. Może jest jest spójne, ale trochę dziwnie wygląda. Osobiście bardziej podobają mi się możliwości Smalltalka ale wyrażone w składni …Rubiego. :) Zobacz też Ruby Instead of Smalltalk
3 Kontynuacje są jedną z wbudowanych cech Rubiego o której może być za jakiś czas głośno. Umożliwiają bowiem budowanie tzw. internetowych serwerów kontynuacyjnych, które w pełni zachowują stan pomiędzy requestami i ogromnie upraszczają prace programistów. W tej chwili najlepiej opracowanym frameworkiem tego typu jest smalltalkowy Seaside.
4 DRY to skrót od ang. Dont’t Repeat Yourself. Railsy zostały napisane z wręcz obsesyjną ;) cechą unikania powtarzania kodu. Mniej powtórzeń to nie tylko mniej niepotrzebnej, dodatkowej pracy ale także mniejsze ryzyko popełniania błędu.
Posted in Ruby, Ruby on Rails, SmallTalk | Tagi rails, ruby, smalltalk | 32 comments