RoR 1.1 wersja finalna!

Opublikowane przez Jarosław Zabiełło Wed, 29 Mar 2006 03:18:00 GMT

Wyszła oficjalna wersja Ruby on Rails 1.1. To bardzo ważna aktualizacja. Zawiera ponad 500 zmian i dodatków.

M.in. wprowadzono nowy typ szablonów jeszcze bardziej ułatwiających korzystanie z AJAX’a. RoR posiada zatem 3 podstawowe rodzaje szablonów: główne RHTML, RXML (do XML i kanałów RSS) oraz RJS do AJAX’a. Poza tym można podpiąć inne, np. wzorowany na pythonowym DjangoLiquid.

Ulepszono także ActiveRecord (dodano m.in. powiązania polimorficzne, oraz “migracje”, czyli wersjonowanie struktury bazy, które są teraz zintegrowane z generatorami modeli.

Do kontrolerów dodano metodę respond_to ułatwiająca pisanie stron działających równocześnie zarówno z jak i bez AJAX’a. Wprowadzono dodatkowy rodzaj testów integracji i wiele, wiele innych cech, w sumie ponad 500 zmian i dodatków zebranych przez grupę ponad 100 kontrybutorów.

Posted in  | Tagi  | 2 comments

RadRails najlepsze narzędzie do RoR?

Opublikowane przez Jarosław Zabiełło Thu, 23 Mar 2006 05:53:00 GMT

RadRails to wysokiej klasy edytor klasy IDE dedykowany do pracy z Ruby on Rails. Jest on przeróbką kodu słynnego Eclipse. RadRails otrzymał nagrodę najlepszego narzędzia developerskiego pod Eclipse: “Eclipse Best Developer Tool”.

Najnowsza wersja RadRails (0.6.1) wprowadza kolejne udogodnienia w pracy, więcej generatorów, dodano obsługę unit testów, lepsze uzupełnianie kodu (hmm, przypomina coraz bardziej TextMate).

Dzięki RadRails, nie trzeba w ogóle wchodzić do konsoli aby uruchamiać skrypty Railsów. RadRails generuje (lub usuwa kontrolery), modele, restartuje webrick’a (wbudowany serwer www dedykowany do pracy developerskiej), ma wbudowany podgląd przeglądarki, . W sumie wszystko w jednym.

Posted in ,  | Tagi , ,  | 9 comments

Microsoft docenia Pythona

Opublikowane przez Jarosław Zabiełło Tue, 21 Mar 2006 09:46:00 GMT

Na stronie MicrosoftTechNet firma Microsoft umieściła sporą listę przydatnych skryptów Pythona dotyczących różnych aspektów systemu Windows.

Posted in  | Tagi  | 3 comments

Subway - padł

Opublikowane przez Jarosław Zabiełło Sat, 18 Mar 2006 13:05:00 GMT

Subway, jeden z pierwszych z frameworków napisanych w Pythonie (który chciał konkurować z RoR, za pomoca podobnego stylu pracy) został zamknięty z powodu braku zainteresowania i wsparcia ze strony społeczności pythonistas.

Osobiście, mnie to nie dziwi. Subway nigdy nie wysilił się aby udostępnić jakąś sensowną dokumentację. Trudno aby ktokolwiek chciał wspierać coś, co nie wiadomo jak używać.

Tak więc, na polu frameworków Pythona które są w jakiś sposób podobne do RoR zostały: Pylons, Django i TurboGears.

Posted in  | Tagi ,  | 3 comments

Ruby on Rails najlepszym frameworkiem roku

Opublikowane przez Jarosław Zabiełło Thu, 16 Mar 2006 11:55:00 GMT

Ruby on Rails dostał nagrodę jako najlepsze narzędzie do budowania aplikacji internetowych. Wzorcowa promocja RoR robi swoje. Tylko naśladować.

Posted in  | Tagi , ,  | brak comments

Mechanizmy bezpieczeństwa - Ruby vs Python

Opublikowane przez Jarosław Zabiełło Fri, 10 Mar 2006 21:37:00 GMT

W języku Ruby (mimo jego wielkiego dynamizmu) kwestia bezpieczeństwa została potraktowana poważnie. Ruby posiada różne mechanizmy umożliwiające kontrolę nad bezpieczeństwem kodu. Generalnie są to 3 różne mechanizmy.

  • Zakresy metod: private, protected i public.
  • Możliwość nieodwracalnego zamrożenia dowolnego obiektu.
  • Możliwość nieodwracalnego ustawiania poziomów bezpieczeństwa.

Zakresy private, protected, public

  • Metody publiczne moga być wywoływane przez kogokolwiek. Domyślnie wszystkie metody są publiczne (poza konstruktorem initialize który zawsze jest prywatny)
  • Metody chronione (protected) mogą być wywoływane tylko przez obiekty w tej samej klasie i klasach potomnych.
  • Metody prywatne mogą być wywoływane tylko w kontekście bieżącego obiektu. Nie można wywoływać metod prywatnych innego obiektu.

Np.:

class C
  public
  def publiczna
    p "Metoda publiczna"
  end  
  def get_chroniona
    chroniona
  end
  def get_prywatna
    prywatna
  end
  protected
  def chroniona
   p "Metoda chroniona"
  end 
  private
  def prywatna
    p "Metoda prywatna"
  end 
end

c = C.new
c.publiczna # => Metoda publiczna
c.get_chroniona  # => Metoda chroniona
c.get_prywatna  # => Metoda prywatna
c.chroniona # => protected method `chroniona' called for #<C:0x28e6300> (NoMethodError)
c.prywatna # => private method `prywatna' called for #<C:0x28e62e8> (NoMethodError)

Dla porównania, w Pythonie wszystkie metody są publiczne. Efekt metod prywatnych i chronionych uzyskuje się za pomocą konwencji. Metody prywatne mają prefiks dwóch underscorów, a chronionie – jeden underscore. Oczywiście nadal są one formalnie publicznie ale dostęp do nich (szczególnie do metod “prywatnych” jest utrudniony)

class C(object):
  def publiczna(self):
    print "Metoda publiczna"
  def get_chroniona(self):
    self._chroniona()
  def get_prywatna(self):
    self.__prywatna()
  def _chroniona(self):
   print "Metoda chroniona"
  def __prywatna(self):
    print "Metoda prywatna"

c = C()
c.publiczna()
c.get_chroniona() # => Metoda chroniona
c.get_prywatna() # => Metoda prywatna
c._chroniona() # => Metoda chroniona
c._C__prywatna() # => Metoda prywatna
c.__prywatna() # => AttributeError: 'C' object has no attribute '__prywatna'

Python wychodzi z innych przesłanek niż Ruby. Zakłada, że “jesteśmy dorośli i wiemy co chcemy robić”. Tzn. utrudnia popełnienie pomyłki przypadkowego dostępu do metody “prywatnej” za pomocą zmodyfikowania nazwy która da dostęp do takiej metody. Jednak jak ktoś, chce to Python nie będzie utrudniał. Można dostać się do każdej metody. Jak zobaczymy dalej (przy omawianiu poziomów bezpieczeństwa Rubiego), ta zasada spowodowała daleko idące konsekwencje dla kwestii bezpieczeństwa kodu Pythona.

Zamrażanie obiektów

Jeśli chodzi o kwestie zamrażania obiektów, to opisuję to w artykule o dynamice klas Python nie posiada jednak aż tak eleganckiego mechanizmu co Ruby. Da się co prawda przyblokować zmiany w obiekcie, ale trzeba sięgnąć po bardziej zaawansowane mechanizmy:

class ImmutableClass(type):
  def __setattr__(cls, name, value):
    raise AttributeError, "'%s' is immutable" % cls.__name__

class C(object):
  def hello(self):
    return 'Hello World!'
  __metaclass__ = ImmutableClass # blokada zmiany

def hello2(self): return 'Blah!'

c = C()
print c.hello() # => Hello World!
C.hello = hello2 #=> AttributeError: 'C' is immutable
print c.hello() # => Hello World!

Poziomy bezpieczeństwa

Jedną z ciekawych cech języka Ruby jest możliwość uruchamiania kodu na różnym poziomie bezpieczeństwa. Załóżmy np, że chcemy stworzyć (w najprostszy możliwy sposób) kalkulator który następnie udostępnimy na stronie internetowej. Przykładowy kod (na podst. PixAxe2) mógłby wyglądać np. tak:
require 'cgi'
cgi = CGI.new('html4')
# pobierz warto z pola formularza 'wyrazenie'
expr = cgi['wyrazenie'].to_s
begin
  result = eval(expr)
rescue Exception => detail
  # obsłuż złe wyrażenie
end
# wyświetl wynik dla użytkownika
Wszystko pięknie, ale co się stanie jak jakiś złośliwy użytkownik wpisze:
system("rm *")

Cały nasz kod zostanie skasowany! Na szczęście Ruby udostępnia mechanizm uruchamiania kodu w specjalnym trybie tak, aby kod nie był w stanie zbytnio rozrabiać. Poziom Rubinowej paranoi bezpieczeństwa określa zmienna globalna $SAFE. Może ona przyjmować następujące wartości:

  • 0 Brak mechanizmów zabezpieczeń. Wartość domyślna.
  • >= 1 Ruby zabrania uzywanie danych w potencjalnie niebezpiecznych operacjach
  • >= 2 Ruby zabrania ładowanie innych skryptów z dostępnych globalnie miejsc
  • >= 3 Wszystkie nowo stworzone obiekty są oznakowane jako niebezpieczne
  • >= 4 Ruby dzieli uruchamiany program tak, że obiekty nie oznaczone jako niebezpieczne również nie mogą być modyfikowane.

Domyślna, zerowa wartość $SAFE jest wystarczająca w większości przypadków. Jednak, gdy skrypt Rubiego jest uruchamiany z ustawionym atrybutem suid lub setgid (co pod uniksem umożliwia uruchomienie skryptu w kontekście innego użytkownika) lub, gdy ruby pracuje w trybie modułu apache’a (mod_ruby), to poziom bezpieczeństwa jest automatycznie podnoszony do 1. Poziom bezpieczeństwa można także ustawić za pomocą parametru -T z wiersza poleceń lub poprzez przypisanie zmiennej $SAFE innej wartości. Przy czym, nie jest możliwe zmniejszenie raz ustawionego poziomu bezpieczeństwa aż do końca działania skryptu.

Bieżąca wartość $SAFE jest dziedziczona przez wszystkie nowo tworzone wątki. Jednakże wewnątrz każdego wątka, wartość zmiennej globalnej $SAFE może być zmieniana bez wpływu na tą wartość w innym wątku. Ta cecha pozwala na budowanie bezpiecznych piaskownic (sandbox), obszarów w których można odpalać potencjalnie niebezpieczny kod bez ryzyka, że wpłynie on na resztę aplikacji czy systemu. Np.
File.new(filename, 'w').write('niebezpieczny kod')
Thread.start do
  $SAFE = 4
  load(filename, true)
end

Dla porównania, Python w ogóle nie posiada takich mechanizmów. Na domiar złego, okazało się, że (obecny we wcześniejszych wersjach Pythona) moduł Bastion okazał się dziurawy Został usunięty w biblioteki podstawowej i jak na razie Python nie posiada już nic w tym temacie do zaoferowania w zamian.

Posted in ,  | Tagi ,  | 3 comments

Dokumentacja dla leniwych - potęga Pythona

Opublikowane przez Jarosław Zabiełło Mon, 06 Mar 2006 15:18:00 GMT

Jedną z najbardziej nielubianych rzeczy przez programistów jest tworzenie dokumentacji do kodu. Wszyscy wiemy, że dobrze ją tworzyć, ale mało komu chce się na to poświęcać cenny czas zwłaszcza jak terminy ukończenia projektu gonią. W takich sytuacjach często dokumentację zostawia się zwykle “na później” jako zadanie do wykonania po ukończeniu projektu. Jednak czym innym jest dodanie komentarza do kodu na bierząco a czym innym napisanie go po paru tygodniach (zwłaszcza jak kod był tworzony zespołowo i musimy teraz zastanowić się co kolega Jasio miał na myśli tworząca jakąś tam kolejną funkcję)

Aby ten problem rozwiązać, praktycznie wszyscy developerzy różnych języków zaczęli wymyślać różne metody aby ten proces usprawnić.

Po pierwsze, stworzono parsery kodu źródłowego, który potrafią wyłuskać z wszystkich plików projektu definicje klas, metod, modułów. Taka pomoc, choć lepsza nic nic, generalnie niewiele jest warta, bo sprowadza się do wyświetlenia nazw klas i ich metod (No może dodatkowo z typami danych, jeśli językiem tym jest któryś z języków statycznie typowanych) Nie mówi jednak nic na temat funkcjonalności ani tego jak używać wyłuskany kod.

Aby temu zaradzić wymyślono inne podejście. Założono że programista przed każdą funkcją czy klasą będzie dodawał wielowierszowy komentarz wg ściśle określonej składni. I potworzono różnego rodzaju biblioteki javadoc, phpdoc czy rubydoc. Niby lepiej. Można teraz lepiej opisywać kod, ale nadal trzeba trzymać się specyficznej składni i znaczników. Poza tym, tak tworzona dokumentacja nie jest w żaden sposób związana z tworzonym kodem.

Doctringi

Jednym z założeń leżących u podstaw Pythona jest przyjęcie zasady, że proste jest lepsze niż złożone. Twórca Pythona, wychodząc naprzeciw zapotrzebowaniom programistów wpadł na genialnie prosty i wygodny zarazem sposób. Przyjął prostą zasadę: każdy fragment tekstu zaczynający się zaraz pod deklaracji klasy czy metody będzie automatycznie dołączany do tej klasy, metody jako jego osobista dokumentacja. Nazwano to docstringiem.

Jak wiemy, dobry programista do programista leniwy. Czyli taki, który stara się osiągać cel jak najmniejszym nakładem pracy. Docstring nie narzuca na programistę żadnych wymagań co do konieczności używania jakichś specjalnch znaczników. Po prostu, deklaruję funkcję. Zaraz pod nią wpisuję linijkę opisującą z grubsza do czego służy, i nie przerywając pracy, piszę dalej. W związku jednak z tym, że ten docstring staje się automatycznie częścią danej metody, mam natychmiastowy do niego dostęp z poziomu interpretera, ba, z poziomu konsoli:

Każdy docstring mogę także wyświetlić tak:

W Pythonie (od wersji 2.4 wzwyż) można dodawać docstringi także do

atrybutów.

Docstringi są bardzo wygodnym sposobem dodawania dokumentacji do kodu. Wymagają minimum wysiłku i wiedzy. To powoduje, że większość aplikacji Pythona tam, gdzie się ludzie śpieszą, powstaje własnie tą metodą.

Pydoc

Standardowo każda dystrybucja Pythona wyposażona jest w prosty skrypt: pydoc (plik pydoc.py leży w folderze lib razem z resztą modułów stadardowej biblioteki pythona. Pydoc umożliwia automatyczną generację dokumentacje do wszystkich modułów Pythona (zarówno tych z bibioteki standardowej jak i wszystkich jakie zainstalujemy).

Aby np. wyświetlić krótki manual na temat modułu md5 wystarczy że z poziomu shella wpiszemy np. pydoc modules md5

(Zamiast uruchamiać pydoc’a w shellu, można z poziomu interpretera wpisać: help(‘md5’). uzyskamy ten sam efekt co pydoc odpalony z shella. Odpowiada to mniej więcej uniksowym manualom.)

Można także wygenerować pliki html w stylu phpdoc’a albo po prostu odpalić na dowolnym porcie serwer www z dokumentacją do wszystkich modułów: pydoc -P 8080

Pod adresem http://localhost:8080 mamy witrynę z opisem wszystkich modułów Pythona zainstalowanych w systemie.

Istnieje znacznie więcej możliwości podpowiadania składni, uzupełniania kodu i innych udogodnień w Pythonie. Tu ograniczyłem się tylko do fragmentu, który nie ma odpowiednika w innych językach – docstringach – mechanizmowi tworzenia dokumentacji do kodu dla leniwych. :) To jedna z wielu doskonałych cech Pythona.

Posted in  | Tagi  | 1 comment

Dynamika otwartych klas: Ruby vs. Python

Opublikowane przez Jarosław Zabiełło Sat, 04 Mar 2006 05:36:00 GMT

Jedną z cech języka Ruby są tzw. otwarte klasy. Temat ten wywołuje mieszane uczucia i jest np. przedmiotem krytyki ze strony miłośników Pythona. Najczęściej jednak ta krytyka idzie w parze z nieznajomością Rubiego.

Np. w jednym z blogów spotkałem taki zarzut: zmiana działania klasy na której oparte są liczby całkowite może prowadzić do nieprzewidywalności w kodzie. Np.
class Fixnum
  def +(num)
    5
  end
end
print 2+2 # => 5 zamiast 4!

No i faktycznie, zmieniliśmy metodę operowania na liczbach całkowitych i Ruby nas oszukuje. Hmm, czy podobnej sytuacji nie ma w Pythonie? Ależ jest! Tylko że nie dotyczy podstawowych typów wbudowanych. Problem jednak jest ten sam. Ba, jest gorszy, co zaraz udowodnię. Ale wpierw prześledźmy różne scenariusze.

Podmiana metody w klasie

Załóżmy, że budujemy sobie klasę:
class Hello(object):
  def msg(self, msg):
    return "Hello " + msg
Miło i przyjemnie. Teraz mamy duży kod i sporo modułów z których co chwilę coś importujemy i na dodatek, pracujemy w kilka osób. Dyzio w jednym ze swych modułów stworzył klase o tej samej nazwie, ale o innej treści. Np.
class Hello(object):
  def msg(self, msg):
    return "Piss off " + msg

Teraz co się stanie jak moduł Dyzia zaimportuję do swojej przestrzeni nazw? Bez żadnego ostrzeżenia, klasa Dyzia wymieni moją klasę. Program może się nie posypie ale, klient uzyska zgoła odmienne przywitanie. :) Oczywiście może być gorzej, bo klasa Dyzia kompletnie usunie moją klasę co zaowocuje usunięciem wszystkich innych metod których się pracowicie natworzyłem.

Podobna sytuacja w Ruby nie owocuje kompletnym usunięciem wszystkich wcześniej stworzonych metod. Podmieniona zostanie tylko ta jedna, inna metoda. Cała reszta zostanie bez zmian.

Zabezpieczyć przed zmianą

Jak się zabezpieczyć przed modyfikacją klas? W Pythonie jest prosta odpowiedź: nie da się, bo Python nie posiada takich mechanizmów.

A co z Ruby? Okazuje się, że jest tu całkiem nieźle. Można dowolny obiekt (z klasą włącznie, bo klasa to też obiekt) zamrozić blokując możliwość jakiejkolwiek zmiany. Wystarczy więc, że wpiszę
Hello.freeze
Od tego momentu nikt nie będzie w stanie nic zmienić w mojej definicji. Można jedną instrukcją zablokować wszystkie klasy wbudowane jak ktoś bardzo tego chce:
ObjectSpace.each_object { |o| o.freeze if o.is_a? Class }

Zamrożenie obiektu jest nieodwracalne aż do końca działania programu. Nie da się żadnym sposobem za pomocą odpowiedniej komendy odmrozić raz zamrożony obiekt. Można co najwyżej sprawdzić czy już nie jest zamrożony (print obiekt.frozen?)

System Hooks

No dobrze, ale co w sytuacji kiedy nie chcemy zamrażać obiektu ale też nie chcemy aby gdzieś ktoś nam w nim coś zmienił bez wcześniejszego powiadomienia nas o tym? Tutaj z pomocą przychodzi coś co nazywa się System Hooks. W Ruby można bowiem świetnie śledzić co się dzieje z naszą klasą. Ruby potrafi wyłapywać następujące zdarzenia:

  • dodanie do klasy nowej metody dostępnej dla instancji klasy (Module#method_added)
  • usunięcie metody instancji z klasy (Module#method_removed)
  • wywołanie metody instancji, która nie istnieje (Module#method_undefined)
  • dodanie metody do singletona (Kernel.singleton_method_added)
  • usunięcie metody z singletona (Kernel.singleton_method_removed)
  • wywołanie nie istniejącej metody dla singletona (Kernel.singleton_method_undefineded)
  • stworzenie klasy potomnej (Class#inherited)
  • dodanie metod do klasy na drodze mixingu z modułów (Module#extend_object)
Przykład:
def info(msg)
  puts msg
end

class Hello
  def msg(msg)
    "Hello " + msg
  end
  def self.method_added(name)
    info "Dodano metode #{name}"
  end
  def self.inherited(name)
    info "Jakas klasa #{name} chce przeciazyc klase Hello"
  end
end

class Druga < Hello
end

class Hello    
  def nowy  
  end
end
Wynik:
Jakas klasa Druga chce przeciazyc klase Hello
Dodano metode nowy
Nie jest więc aż tak strasznie jak to co niektórzy trąbią. To prawda, że w Ruby można dodać metody do absolutnie każdej klasy (z wbudowanymi włącznie). Prawdą jest jednak także to, że można ten mechanizm w miarę kontrolować, śledzić, lub nawet zablokować. Zmiana metod klas wbudowanych pozwala na pisanie bardzo czytelnego kodu. Np. Ruby on Rails z tego sporo korzysta. Mogę samemu b. łatwo sobie zaimplementować coś podobnego.
class String
  def pluralize
    self + "s"
  end
  def singularize
    self[0...-1]
  end
end

puts "word".pluralize # => words
puts "books".singularize # => book

class Integer
  def kilobytes
    self * 1024
  end
end

puts 2.kilobytes # => 2048

Python (i żaden inny ze znanych mi języków) takich możliwości nie ma. A odnośnie tego, że Python nie pozwala zmienić definicji stringa czy integera (ogólnie typów wbudowanych) to mała to pociecha, skoro możne zmienić dowolnie inną klasę i to bez żadnego mechanizmu kontroli.

Posted in ,  | Tagi ,  | 5 comments

Pylons - czyli siła Myghty i wygoda RubyonRails

Opublikowane przez Jarosław Zabiełło Fri, 03 Mar 2006 23:51:00 GMT

Coraz bardziej ciekawie rozwija sie pythonowy framework do szybkiego budowania aplikacji internetowych: Pylons. W przeciwieństwie do TurboGears Pylons jest zbudowany na bazie Myghty a nie CherryPy. Myghty jest bardzo szybkim, stabilnym i dobrze napisanym frameworkiem. Pracuje jako cgi, mod_python, wielowątkowo lub wieloforkowo, dzięki WSGI. Posiada doskonały, elastyczny cache, obsługę AJAX’a, słowem prawie wszystko co trzeba dla współczesnej aplikacji internetowej. Jednak posiada za dużo cech które w branży pythonowej określa się jaki “perlish” (Myghty był wzorowany na perlowym Masonie)

I tu z pomocą przychodzi Pylons. Jest on czymś w rodzaju megaframeworku, czyli frameworku zbudowanym na bazie innego frameworku, w tym wypadku: Myghty. (Na podobnej zasadzie TurboGears jest megaframeworkiem opartym na CherryPy).

Pylons różni się jednak tym od TurboGears że jest oparty na frameworku znacznie bardziej solidnym i znacznie lepiej naśladuje framework bedący natchnieniem dla większości innych, czyli Ruby on Rails. Pylons czerpie pełnymi garściami z najlepszych pomysłów Railsów dodając do tego większą wydajność Pythona, elastyczność i prostotę składni oraz siłę jego bibliotek (np. Python ma doskonale zaimplementowaną obsługę Unicode, co jest w Ruby potraktowane trochę po macoszemu, a w PHP to w ogóle tragedia)

Zobaczmy przykładowo, co nam daje Pylons. Np. rozwiązywanie adresów. Adresy URL są rozwiązywane za pomoca bardzo ciekawej biblioteki Routes w sposób podobny do Railsów. Np. załóżmy że bieżący request zwraca następujący słownik: {‘controller’: ‘blog’, ‘action’: ‘view’, ‘id’: 2 (gdzie rozwiązywanie adresów url odbywa się wg definicji podobnej do Railsów: ’:controller/:action/:id’). Uzyskamy następujące wyniki:

url_for(id=4)                    =>  '/blog/view/4',
url_for(controller='/admin')     =>  '/admin',
url_for(controller='admin')      =>  '/admin/index/4'
url_for(action='edit')           =>  '/blog/post/4',
url_for(action='list', id=None)  =>  '/blog/list'

Pylons “przeportował do Pythona” całą masę użytecznych helperów znanych w Rails. Zajmuje się tym biblioteka RailsHelpers. Przykładowo wygląda to tak:

link_to("Delete this page", url(action="destroy", id=4), confirm="Are you sure?")
link_to("Help", url(action="help"), popup=True)
link_to("Busy loop", url(action="busy"), popup=['new_window', 'height=300,width=600'])
link_to("Destroy account", url(action="destroy"), confirm="Are you sure?", post => True)

Jaką to daje nam korzyść? Ogromną! Wyobraźmy sobie że chcemy zmienic sposób rozwiązywania adresów url. Co z milionami stron, które miały linki do różnych wewnętrznych części naszego serwisu? Koszmar! Trzeba ręcznie je poprawiać. Dzięki Pylon, nie musimy bezpośrednio wklepywać adres url, ale używamy do tego helperów. Zmiana zasad rozwiązywania adresów automatycznie poprawi adresy we wszystkich miejscach. Korzyść jest niewymierna!

RailsHelpers zawiera także więcej helperów. Np. można na nie zrzucić budowę formularzy.

Można też uzyskać efekty specjalne połączone z AJAX’em w identyczny sposób jak w Railsach. Pylons bowiem impelmentuje w Pythonie tą samą, znakomitą bibliotekę JavaScript: scriptaculous

Nie sposób nie wspomnieć także o interaktywnym debuggerze. To poprostu jest nowa jakość. Można interaktywnie prześledzić stan obiektów aplikacji internetowej. Świetny pomysł.

Jak dla mnie, Pylons staje się głównym rywalem Django do tytułu najlepszego frameworka dla języka Python. Jest znacznie bardziej elastyczny, posiada wysoką wydajność i możliwości Myghty oraz w łatwiejszy sposób rozwiązuje adresy url i ma wygodniejsze helpery, bo wzorowane na Ruby on Rails. Więcej na temat Pylons można śledzić także na stronie http://groovie.org/

Posted in ,  | Tagi ,  | 2 comments