Atak na zabezpieczenia protected/private Javy/Scali i PHP5

Opublikowane przez Jarosław Zabiełło Sun, 21 Jun 2009 03:45:00 GMT

Być może jednym z argumentów, dla których Ruby znajduje więcej zainteresowania ze strony programistów Javy niż Python, jest podobny mechanizm zabezpieczenia dostępu do atrybutów klasy za pomocą słów kluczowych private i protected. W języku PHP 5 wprowadzono podobny mechanizm. Ci jednak, którzy myślą, że te kwalifikatory zakresu dostępu stanowią jakiekolwiek poważne zabezpieczenie, są w głębokim błędzie. W banalny sposób można to obejść zarówno w w PHP 5, jak i w Javie. Przy czym o ile, w Javie wynika to raczej z celowego projektu w mechanizmie refleksji, w PHP 5 wygląda to na dziurę bezpieczeństwa…

Czytaj dalej...

Tagi , , , , , , ,  | 27 comments

Merb - tworzenie nowego projektu

Opublikowane przez Jarosław Zabiełło Wed, 19 Nov 2008 01:13:00 GMT

Rozpoczęcie pracy z Merb’em, podobnie jak w Rails, zaczyna się od stworzenia projektu. Domyślnie Merb proponuje predefiniowany zestaw dobranych modułów, nie jest to jednak jedyna opcja i dobrze wiedzieć o tym szczególnie dla tych co chcieliby użyć Merb w JRuby (jeden z domyślnych modułów, DataMapper, jeszcze nie jest przygotowany do pracy z JRuby).

Czytaj dalej...

Tagi , , , ,  | 33 comments

Merb 1.0RC

Opublikowane przez Jarosław Zabiełło Tue, 14 Oct 2008 23:21:00 GMT

Z lekkim opóźnieniem, ale już jest dostępny Merb 1.0RC (gemy wyświetlają wersję 0.9.9). Zostało także zmienione Wiki. Ruby szybko się rozwija. Aktualnie nie tylko Merb ale też i Rails bez problemu biją wydajnością pehapowe frameworki takie jak CakePHP, Symfony czy Code Igniter.

Czytaj dalej...

Tagi , , ,  | 5 comments

Sprzątanie po PHP czyli Passenger 2.0 i Ruby Enterprise 1.0

Opublikowane przez Jarosław Zabiełło Tue, 03 Jun 2008 23:40:00 GMT

Stało się! Twórcy świetnego modułu Apache’a – mod_rails – zmieniają jego nazwę na mod_passenger, bo mod_rails nie jest już więcej modułem tylko dla Rails. W nowej wersji 2.0 (ktora ma wyjść na dniach) dodano pełne wsparcie dla Rack i tym samym mod_passenger 2.0 obsługuje wszystkie pozostałe frameworki używające Rack’a (ze świetnym Merbem włącznie).

Czytaj dalej...

Tagi , , , , , , , ,  | 34 comments

Aplikacja webowa - wybór technologii

Opublikowane przez Jarosław Zabiełło Sat, 25 Aug 2007 19:22:00 GMT

Dość często spotykam się z prośbą o to, jaką technologię (i framework) bym polecił do tworzenia aplikacji webowych. Dziedzina aplikacji webowych rozwija się bardzo prężnie i trudno tak naprawdę przewidzieć, co będzie najlepszym wyborem za parę lat. Niniejszy artykuł stanowi krótkie podsumowanie moich doświadczeń w tej dziedzinie na dzień dzisiejszy.

Czytaj dalej...

Tagi , , , , ,  | 97 comments

Koniec PHP 4

Opublikowane przez Jarosław Zabiełło Sat, 28 Jul 2007 10:55:00 GMT

Wciąż popularny w ofertach hostingowych PHP 4.x będzie wkrótce musiał ustąpić miejsca dla PHP 5. Ogłoszono oficjalnie wstrzymanie prac nad rozwojem tej wersji. Wsparcie ma być jeszcze kontynuowane do końca tego roku. Potem nie będzie już żadnych nowych wersji (z wyjątkiem załatania ewentualnych błędów krytycznych, rzecz jasna).

Tagi  | 6 comments

PHP w Pythonie (WSGI)

Opublikowane przez Jarosław Zabiełło Thu, 15 Feb 2007 00:29:00 GMT

Osobiście tego nie testowałem, ale brzmi interesująco: wphp to moduł WSGI możliwiający integrację języka PHP z dowolnym (pythonowym) frameworkiem opartym na standardzie WSGI.

Tagi , ,  | 14 comments

Porównanie wydajności frameworków

Opublikowane przez Jarosław Zabiełło Sun, 04 Feb 2007 21:54:00 GMT

Ciekawe i dosyć dokładne porównanie wydajności paru frameworków:

Django bez trudu zdeklasowało konkurencję. Szkoda, że w porównaniu nie uwzględniono Pylonsów i CakePHP. Bardzo też dziwne, że nowy Rails 1.2.1 w tych testach jest mocno wolniejszy od starszej wersji 1.1.6. Frameworki pehapowe okazały się najwolniejsze. Najgorszy okazał się pehapowy Symfony. Jest skomplikowany i wolny, 35x wolniejszy od Django!

Tagi , , , , , , , ,  | 15 comments

Szablony i wzorzec MVC - cz. III

Opublikowane przez Jarosław Zabiełło Sun, 14 Jan 2007 03:25:00 GMT

W poprzedniej części omówiono szablony dedykowane głównie do współpracy z designerami bojącymi się programować. Były to albo szablony wkładające swoją logikę do znaczników XML/XHTML (ZPT, SimpleTAL, Kid, Genshi, MasterView, PHP TAL), albo szablony posiadające swój własny, specjalizowany język (Smarty, Django, Jinja, Liquid). W założeniu taki język miał być prostym substytutem języka używanego w warstwie kontrolera. Szablony tego typu może są wygodne dla designera, ale na pewno nie dla programisty, który musi je przygotować. Po pierwsze, trzeba się uczyć kolejnego języka… szablonów. Po drugie, wszystkie tego typu języki są ograniczające dla programisty. Mimo że pozornie prostsze, w praktyce są bardziej złożone i to nawet dla designera. Np. szablony Django i Jinja nie posiadają żadnej składni na określenie trywialnego warunku większości, mniejszości:

{{ x }} jest 
{% if x > y %} 
    większe 
{% else %} 
    mniejsze 
{% endif %} 
od {{ y }}

Powoduje to masę kłopotów dla programisty1. Prymitywna składnia szablonu wymusza więc kupę dodatkowej pracy. O ileż prościej jest użyć po prostu pełnej składni języka tak jak to robią szablony Cheetah:

$x jest 
# if x > y 
    większe 
# else 
    mniejsze 
# endif  
od $y

Dochodzimy tu więc do sytuacji kiedy byśmy chcieli coś bardziej elastycznego – pełnego dostępu do języka programowania. Taka sytuacja jest pożądana wtedy kiedy i tak szablony budują programiści na podstawie dostarczonego czystego kodu HTML od designerów.

PHP

Język PHP jest dosyć specyficzny, bo w istocie jest to język szablonów. Tzn. pierwotnie tak został stworzony, ale z czasem się skomplikował że dostąpił miana języka skryptowego. Ale jego korzenie widać w składni, która z definicji jest zagnieżdżaniem instrukcji PHP wewnątrz kodu HTML. Idąc tym tropem, niektórzy pomyśleli, że nie ma sensu wymyślać dodatkową składnię. Wystarczy użyć PHP w odpowiedni sposób. I tak powstały szablony Savant.

Właściwie to Savant nie powinny nazywać się szablonami, bo to nic innego jak PHP użyty w taki sposób, aby rozdzielić warstwę prezentacji, od wartwy logiki biznesowej. A skoro to PHP, to odpada nauka dodatkowej składni oraz potrzeby kompilacji specjalizowanego języka szablonów do końcowego kodu PHP (jak to ma miejsce w szablonach Smarty).

Czy takie podejście jest lepsze, czy gorsze, to już każdy może sobie ocenić. Moim zdaniem PHP ma na tyle mętną składnię, że warstwa prezentacji używająca Smarty2 jest bardziej czytelna niż czysty PHP jaki używają Savant.

Ruby

Kiedy mówimy o Ruby w kontekście stron internetowych to najczęściej mamy na myśli jego najsłynniejszy framework – Rails. Ruby sam w sobie nie jest związany z HTML tak jak PHP. Rails do szablonów używa biblioteki ERb (ang. “embed Ruby”, czyli “zagnieżdżony Ruby”) Składnia jest bardzo podobna do PHP, JSP czy ASP. Ruby jest tu językiem zagnieżdżonym w HTML.

<%= x %> jest 
<% if x > y %> 
    większe 
<% else %>
    mniejsze 
<% end %>
od <%= y %>

Python

Jeśli chodzi o Pythona to istnieje cała masa systemów szablonowych. Ograniczę się do paru, tych bardziej interesujących.

Spyce

Szablony Spyce zostało stworzone jako pythonowa konkurencja dla PHP. Podobnie potrafią przeplatać język (tu: Pythona) z tagami HTML. Najbardziej oczywista przewaga Spyce wynika z faktu używania języka Python, który jest znacznie lepiej zaprojektowany i posiada dużo więcej możliwości niż PHP. Spyce potrafii budować własne znaczniki (custom tags, podobnie jak to potrafią javowe JSP) oraz łatwiej w nich zbudować komponenty, kod do wielokrotnego użytku.

Myghty

Szablony Myghty powstały pierwotnie jako pythonowa implementacja systemu komponentowego Mason dla Perla. Mimo wielu podobieństw, Myghty są znacznie potężniejsze o Masona, np. intensywnie wykorzystują obiektowość Pythona (zobacz różnice). Od początku Myghty powstało z myślą o dużych obciążeniach, ciężkich, profesjonalnych zastosowaniach. Mają doskonały własny cache, są bardzo szybkie, odporne na wątki, świetnie się nadają do tworzenia komponentów.

Programiści Pythona bardzo cenią sobie filozofię tego języka (która podkreśla prostotę, oczywistość i elegancję składni). Problem w tym, że Myghty dla pythonowców jest zbyt podobne do Perla. Są za mało “pythonic” – pythonowe. Dodatkowo, poprzez podkreślanie swojej komponentowości, Myghty niektórym zbyt kojarzy się z filozofią komponentową frameworku ASP.NET (a wzorzec MVC wydaje się być bardziej przejrzysty niż wzorzec sterowanych zdarzeniami komponentów). Myghty, jako system komponentowy, może być używane w stylu MVC, ale nie jest to takie naturalne i oczywiste. (Na szczęście, wszystko zmienił Pylons który zapewnia przejrzystą pracę zgodną z wzorcem MVC i Myghty są tam zredukowane tylko do obsługi szablonów szablonów. Sterowaniem zajmują się kontrolery Pylonsa a nie Myghty).

Cheetah

Szablony Cheetah posiadają jedną z najbardziej czytelnych i eleganckich składni. Autorzy wzorowali się trochę na javowych Velocity i Webmacro. Tym, którzy cenią sobie czystość Pythona z prostotą składni szablonów z pewnością Cheetah mogą przypaść do gustu. Przez dłuższy czas były moimi ulubionymi szablonami i do te pory lubię ich klarowność. Cheetah posiadają elegancką składnię obiektowego budowania szablonów potomnych na bazie już istniejących. Myghty też to potrafi, ale Cheetah to ma bardzo czytelnie zrobione. Cheetah są również bardzo szybkie.

Mako

Mako to najmłodsze dziecko stworzone przez programistów Pylonsów. Powstały na bazie doświadczeń i najlepszych cech szablonów Myghty, Cheetah, Django/Jinja czy Smarty. Największą ich zaletą jest ogromna szybkość i pythonowa filozofia pracy. Programiści Pythona mogą zauważyć, że składnia Mako jest bardzo bliska sposobowi pracy w samym języku Python. Mako posiadają wielką łatwość tworzenia komponentów, ale w sposób bardzo podobny do tego jak Python wykorzystuje swoje moduły. Szablony można także rozszerzać na drodze obiektowego dziedziczenia. Dziedziczenie szablonów może być określane w sposób dynamiczny (tego już nie potrafią np. Cheetah). Dowolny fragment szablonu można również zamienić na komponent z własnym cache. Mako posiadają także składnię modyfikatorów, które spopularyzowane zostały przez Smarty. Działają one jak uniksowe pipes (${zmienna|filter}.

Mako automatycznie kompilują swój kod do modułów Pythona. Można je więc debugować tak jak zwykły kod Pythona (Cheeatah wymaga ręcznej kompilacji). Można je bez problemu używać jako niezależną bibliotekę. Nie są one zależne od jakiegokolwiek frameworku. Można je zintegrować z dowolnym frameworkiem używającym standardu3 WSGI. Użytkownicy frameworka Pylons prawie nic nie muszą robić, bo Mako są już tam przygotowane do pracy.

Ogólnie rzecz biorąc, Mako to – moim zdaniem – najlepszy aktualnie istniejący system szablonów dla Pythona.

Zaś co do frameworków… to coraz bardziej zaczynam nabierać pewności, że przyszłość nie należy ani do Django, ani do Railsów. Nic nie może równać się z możliwościami czystego, 100% frameworka WSGI. Takim jest np. Pylons. Ale o tym, i o “bitwie” Pylons vs. Django i Rails, napiszę już innym razem.

Appendix 2007-01-29: Zobacz też szablony Haml .


1 Poprawnie rzecz mówiąc, powinien napisać swojego helpera. Jeśli więc chcemy wyświetlić w pętli rekordy z bazy, a widok jest czuły na zawartość tych danych, to powinniśmy cała listę rekordów wrzucić do helplera, przeiterować w pętli, dodać dodatkową zmienną i dopiero tak zmodyfikowaną listę przekazać do szablonu.

2 Smarty mimo posiadania własnej składni pozwala na odpalanie pełnego języka PHP: {php}print phpinfo();{/php}. Tak praktyka jest jednak odradzana, bo wprowadza jeszcze większy bałagan niż już jest w PHP.

3 Zobacz artykuł Introducing WSGI: Python’s Secret Web Weapon oraz prezentację koncepcji WSGI na video.

Tagi , , , , , , , , , , , , ,  | 15 comments

Ruby najszybciej rosnącym językiem

Opublikowane przez Jarosław Zabiełło Thu, 04 Jan 2007 17:00:00 GMT

Ruby ostro idzie do przodu przesuwając się w górę na liście popularności oczko za oczkiem. Wg TIOBE Programming Community Index Ruby był językiem roku 2006 (w styczniu 2007 Ruby jest 10 pozycji). Z pewnością przyczynił się do tego framework Rails. Pewnie z tego samego powodu (tu jest nią AJAX) rosnie popularność języka JavaScript.

Dawniej popularność języka dyktowało wsparcie dużych firm (Sun dla Javy i Microsoft dla C#). Ale współcześnie dużo większe znaczenie zaczyna mieć “killer application” (“zabójcza” aplikacja promująca język w jakim została napisana) oraz to co twierdzi internet. Stąd zwycięzcy w ostatnich dwóch latach (PHP i Java) w tym roku (2006) są przegranymi.

Można też zauważyć trend rosnącej popularności języków typowanych dynamicznie przy malejącym tych typowanych statycznie. Ale to nic dziwnego. Od czasu przełamania pewnej bariery wydajności sprzętu upadł główny powód od aby nie korzystać z języków dynamicznych na szerszą skalę. (Z pewnością taki Smalltalk narodził się zdecydowanie w złym czasie) Ciekawa jest też uwaga, że większość popularności języka PHP nabijana jest jego problemami z bezpieczeństwem zamiast faktycznym uzyskiwaniem popularności w kręgach programistów.

Interesujące jest również to, że szybko zdobywa popularność język D, o którym do niedawna mało kto słyszał. To dosyć ciekawy język i do tego ekstremalnie szybki (stosuje jakieś agresywne algorytmy kompilacji). Ma też automatyczne zarządzanie pamięcią (garbage collector). Chyba może bez kompleksów iść na wojnę C++, Javą czy C#. (Zobacz porównanie D z innymi językami.)

Z kolei z języków bardziej niszowych odnotować można wzrost popularności Lua (z pozycji 58 na 47) oraz funkcyjnego Haskella (z 56 na 42). Przewiduje się też, że z powodu oczekiwanej migracji z C++ i Visual Basic, w roku 2007 zwycięzcą w kategorii najbardziej popularnego języka, będzie C#.

Tagi , , , , , , ,  | 3 comments

Ruby 1.9 (YARV) vs. Python, Lua & PHP

Opublikowane przez Jarosław Zabiełło Mon, 01 Jan 2007 18:36:00 GMT

Korzystając z tego, że niedawno do repozytorium Rubiego został dodany YARV (wirtualna maszyna Rubiego) pokusiłem się o małe porównanie wydajności. Jako test użyłem prostego programu jaki pojawił się na liście pl.comp.lang.pyhon (musiałem tylko trochę zwiększyć pętle do 10 milionów iteracji, aby były widoczne jakieś wyniki) Użyty sprzęt: Athlon64 3700+, 64bit Ubuntu 6.0.6.

Sprawdziłem też z ciekawości PHP 5.2 na tym samym sprzęcie. Dla tak prostego testu powinien móc dać z siebie wszystko. Jest jednak wolniejszy od Rubiego 1.9.

Kod dla Pythona:

import time
t=time.time()
a=0
for i in xrange(10000000):
    a += i
print a
print time.time() - t
Kod dla Lua:
t = os.clock()
a = 0
for i = 1,10000000 do
    a=a+i
end
print(a)
print(os.clock() - t)

Kod dla Rubiego:

t = Time.now
a = 0
for i in 1..10_000_000
  a = a+i
end
puts a
puts Time.now - t

Kod dla PHP:

<?php
function microtime_float() {
 $time = microtime();
 return (double)substr($time, 11) + (double)substr($time, 0, 8);
}
$t =  microtime_float();
$a = 0;
for ($i = 0; $i < 10000000; $i++) {
  $a += $i;
}
print "$a\n";
print  microtime_float()- $t;
?>

Wyniki:

  1. Lua: 1.14 s
  2. Ruby 1.9: 1.49 s
  3. PHP 5.2: 1.74 s
  4. Python 2.5: 2.64 s
  5. Python 2.4.3: 2.72 s
  6. Ruby 1.8.5: 3.83 s.

Drugie podejście

Tym razem wynik uśredniam dla 10 prób. Zwiększyłem ilość iteracji do 20 mln. No i… Ruby 1.9 pobił wszystko. Zarówno Pythona jak i Lua! (PHP 5.2 po 30 sek. zgłosił timeout. Musiałem więc uśrednić po 5 wynikach.)

PYTHON

import time
def bench():
    a, t = 0, time.time()
    for i in xrange(20000000):
        a+=i
    return time.time()-t
result = 0
for i in range(10):
  result += bench()
print result / 10.0

RUBY

def bench
  a, t = 0, Time.now
  20_000_000.times { |i| a += i }
  Time.now - t
end
result = 0
10.times { |i| result += bench }
puts result / 10

LUA

function bench()
  a = 0
  t = os.time()
  for i = 1, 20000000 do
    a = a + i
  end
  return os.time() - t
end
result = 0
for x = 1,10 do
  result = result + bench()
end
print(result/10)

PHP

<?php
function bench() {
  $a = 0;
  $t =  time();
  for ($i = 0; $i < 20000000; $i++) $a += $i;
  return time() - $t;
}
$result = 0;
for ($x = 1; $x <= 5; $x++) $result += bench();
print $result / 5.0;
?>

Wyniki

  1. Ruby 1.9: 2.0953268 s.
  2. Lua 5.1: 2.4 s.
  3. Python 2.5: 2.49481592178 s.
  4. Python 2.4.3: 2.71687791348 s.
  5. PHP 5.2: 4.2 s.
  6. Ruby 1.8.5: 9.0153751 s.

Jestem ciekaw kiedy wyjdzie Rails dostosowany do Ruby 1.9. Zapowiada się bardzo obiecująco!

Posted in , ,  | Tagi , , , , ,  | 19 comments

Django i Rails biją PHP

Opublikowane przez Jarosław Zabiełło Fri, 14 Jul 2006 15:34:00 GMT

Porównanie wydajności trzech frameworków: Symfony, Ruby on Rails i Django pokazuje że Rails jest znacznie szybszy od pehapowego Symfony, a Django znacznie szybszy od Railsów. Co ciekawe, PHP5 używał akceleratora.

Posted in , ,  | Tagi , ,  | 19 comments

Edytory dla Pythona, Ruby, PHP

Opublikowane przez Jarosław Zabiełło Sat, 11 Feb 2006 23:17:00 GMT

Osoby zaczynające pracę z językiem Python, Ruby czy PHP często pytają się na grupach dyskusyjnych na temat edytorów zalecanych do pracy. Istnieją dwie szkoły, ci którym zależy na minimalnych wymaganiach pamięci i procesora oraz ci, którzy chcieliby aby edytor nie tylko kolorował składnię, ale także podpowiadał kod, uzupełniał składnię, miał wbudowany debugger itp.

Edytory tekstowe (nie IDE):

  • SciTE – łatwy w obsłudze, kolorowanie b. wielu języków
  • Vim – powszechny na każdym linuksie, jest wersja dla win32. B. szybki, doskonały do obsługi wielkich plików, niezbyt intuicyjna obsługa, np. kto by wpadł na pomysł aby wyjść z edytora za pomocą kombinacji: Esc + :q! (klawisz Escape, potem znak cudzysłowa, małe q i znak wykrzyknika)
  • Notepad++ – prosta, intuicyjna obsługa, po instalacji podmienia dla Internet Explorera idiotycznego Notatnika do podglądu źródeł stron html, warto instalować choćby dla tej jednej cechy i wymiany starego Notatnika.
  • JEdit – napisany w Javie, mnóstwo pluginów
  • XEmacs – kompletnie nieintuicyjna obsługa, ten edytor zupełnie w niczym nie przypomina skrótów klawiszy z innych programów, ale jest b. potężny. Jak ktoś już się przekatuje i go nauczy, to podobno jest to doskonałe narzędzie. Mnie nigdy nie starczyło cierpliwości aby go opanować. Wolę już edytor Vi.

Edytory IDE – Python

Użytkownikom win32 polecam instalację ActivePython zamiast instalacji na stronie główej Pythona. Do Pythona istnieje mnóstwo niezłych edytorów tekstowych jak i edytorów IDE. Moimi ulubionymi są:

  • Eclipse + pyDEV – chyba najlepsza opcja. Edytor Eclipse jest napisany w Javie i wymaga trochę pamięci, ale jest b. dobry. Posiada intuicyjny interfejs, mnóstwo pluginów dających spójne środowisko do pracy z javą, pythonem, ruby i php. pyDEV z zintegrowanym pakietem pyLint nie tylko podpowiada kod, ale także ma możliwość wyłapania nieużytej zmiennej, czy brak zgodności stylu programowania z zaleceniem PEP8 itp. Oczywiście jest też zintegrowany debugger.
  • PythonWin – standardowo instalowany w ActivePython. Jest znacznie szybszy i lżejszy od Eclipse, bo jest napisany w języku C. Ma świetny debugger, wbudowaną konsolę, podgląd obiektów COM. Jedyną jego wadą jest brak obsługi utf-8. Zaletą jest też to, że nadaje się do szybkiej edycji pojedyńczych plików (Eclipse wymaga tworzenia projektu, co często jest b. niewygodne). PythonWin ma także ulepszoną konsolę, bo pełnoekranową. Łatwiej w nim szybko zaznaczyć fragment poprzedniej komendy i uzupełnić.
  • SPE – edytor napisany w Pythonie z wykorzystaniem biblioteki wxPython. Ma unikalne, b. ładne kolorowe zakładki (umożliwia lepsze wyświetlanie podglądu metod i atrybutów klas). Wbudowany debugger, listę Todo, wyszukiwanie po wielu plikach i co ważniejsze: lepiej podpowiada kod niż np. PythonWin.
  • Eric – napisany w Pythonie z użyciem biblioteki PyQT. Ma dużo możliwości, wspomaganie tworzenia unittestów, refactoring, debugger itp. Obsługuje nie tylko Pythona ale i Rubiego.
  • Boa Constructor – ten edytor może zainteresować osoby piszące aplikacje oparte na wxPython bo posiada wbudowane wizualne wspomaganie tego procesu. Wzorowany jest na Delphi.
  • Komodo: Kombajn podobnie jak Eclipse. Występuje w wersji IDE (płatnej, ale licencja od razu obejmuje Windows, Linux i Mac OS X) i Edit (bezpłatnej). Ma świetny debuger do Pythona. Jest szybszy od Eclipse i obsługuje dobrze Pythona, Rubiego, PHP, C++ i inne języki (nawet szablony Django). Bardzo dobrze podpowiada kod HTML, CSS, zamyka tagi HTML podobnie jak Dreamweaver. Niestety, podpowiadanie kodu pozbawione jest na razie wyświetlania zintegrowanej dokumentacji (docstringów dla Pythona czy rdoc dla Rubiego, wyświetlana jest tylko lista metod).
  • WingIDE – wymieniam go na końcu bo jest płatny. Doskonale (zdecydownie najlepiej z wszystkich) podpowiada kod, posiada możliwość edycji w Zope, doskonały debugger.

Edytory IDE – Ruby

Do Rubiego istnieje też sporo niezłych edytorów, choć nie aż tyle co do Pythona.

  • Netbeans IDE 6.x ma zdecydowanie najlepsze podpowiadanie składni do Rubiego. Najlepszy IDE do Rubiego i Rails obok Aptana IDE.
  • Aptana IDE+Rails (RadRails został przejęty) to nic innego jak Eclipse dostosowany do pracy z Ruby on Rails. Posiada wszystkie zalety Eclipse, np. po dodaniu pluginów ma dobre wsparcie dla innych języków, np. Pythona. Od chwili wchłonięcia RadRails przez Aptanę, posiada świetne dodatkowe mocne wsparcie dla kodu HTML, CSS, JavaScript.
  • Arachno IDE – bardzo ładny i szybki. Może kolorować kod (nie tylko samego Rubiego ale także szablonów ERb, czyli nadaje się dobrze do Railsów) podobnie jak TextMate, ma wbudowany debugger, generowanie dokumentacji RDoc dla projektu, przeglądarka klas Rubiego i zainstalowanych gemsów. Niestety jest płatny i bieżąca wersja nie obsługuje jeszcze utf-8.
  • TextMate – działa tylko z systemem OS-X, czyli wymaga Macintosha. Ale jest to ulubiony edytor developerów Railsów. Sam edytor jest niestety płatny. Ma bardzo rozbudowane makra (snipety) przyśpieszające wprowadzanie kodu, ale ma beznadziejnie słabe podpowiadanie kodu, nie rozwija metod do bibliotek wbudowanych Rubiego, dokumentacji RDOC w ogóle nie ma scalonej z podpowiedziami do kodu. Do Pythona jest jeszcze gorzej. Ale edytor jest szybki, lekki i ma ładne kolorowanie wielu języków.
  • RDE czyli Ruby Development Environmnent. Edytor jest b. szybki i pomocny jak ktoś chce pisać kod w czystym Ruby.

Edytory IDEPHP

Do PHP istnieje sporo edytorów, ale moim zdaniem większość to badziewie. Sam PHP jest językiem który bardzo utrudnia napisanie na niego dobrego debuggera. Właściwie w nic dobrego tu nie ma poza komercyjnym Zendem. Ale gdybym miał wybierać, to wybrałbym:

  • Eclipse + plugin phpeclipse – po pierwsze jest darmowy, po drugie doskonale zarządza kodem PHP i koloruje szablony Smarty. Po trzecie, doskonale współpracuje z SVN. Miałem okazję sprawdzić nowy Zend Studio 5.1. Mimo, że lepiej podpowiada kod, to nie koloruje Smartów i kiepsko współpracuje z SVN, beznadziejnie wręcz.
  • Zend Studio – komercyjny IDE stworzony przez twórców PHP. Najlepiej ze wszystkich podpowiada kod (lepiej od Eclipse) Niestety nie potrafi kolorować kodu popularnych szablonów Smarty (Eclipse to potrafi!) Szybkość ta sama co Eclipse, wymagania co do pamięci – też.
  • Macromedia Dreamwever 8 – komercyjny, ale nieźle koloruje i podpowiada kod. Najnowsza wersja Dreamweawera ma sporo usprawnień, np. w końcu bada końce bloków (klamr). Dreamweawer jest też oczywście szybszy od Zend Studio i Eclipse bo jest napisany w języku C.

Niestety edytory PHP mają fatalne możliwości debugowania kodu w stosunku do tego, co można spotkać dla Pythona i Ruby. Do szybkiego testowania kodu PHP, najlepiej użyć SciTE. Można mu ustawić opcję aby po wciśnięciu klawisza F5 natychmiast generował wynik bez żadnego pośrednictwa serwera www.

Posted in , , ,  | Tagi , , ,  | 14 comments

Akcesory w Javie, Pythonie, Ruby i PHP5

Opublikowane przez Jarosław Zabiełło Tue, 07 Feb 2006 22:25:00 GMT

Java, język który dobył sobie silną pozycję na rynku korporacyjnym, jest od jakiegoś czasu pod obstrzałem krytyki z różnych stron. Wyszła cała seria książek krytykujących model obiektowy oraz metodologie promowane przez Javę (od najsłynniejszej Beyond Java po Bitter Java, Bitter EJB, czy inne)

Nie umniejszając zalet Javy, jej krytycy wytykają jej niepotrzebną nadmiarowość kodu, ociężałość i małą zwrotność, która powoduje że język ten słabo nadaje się do modnej ostatnio metodologii _agile programming. _ Aby lepiej ten problem zobaczyć, przyjrzyjmy się typowej praktyce programistów Javy. Tekst ten zainspirowany jest niedawną dyskusją jaka miała miejsce w jednym z blogów mojego kolegi.

Czym są akcesory?

Akcesory (lub inaczej: gettery i settery) to slangowe okreslenie metod jakie używa obiekt do odczytu i modyfikacji swoich atrybutów. Są one tak nagminnie używane przez programistów Javy, że niektóre edytory (np. Eclipse) zostały nawet wyposażone w makra do automatycznego ich generowania.

Dorzucanie nieużywanego kodu “na wszelki wypadek”...

Nagminna (wśród programistów Javy) praktyka dodawania akcesorów do atrybutów klasy pachnie jakimś antipatternem i są głosy, które używanie akcesorów nazywają wprost złą praktyką . Jest w tym trochę racji. Ale, jak to poniżej wykażę, jest to pewnego rodzaju kompromis w związku ze słabym modelem obiektowy Javy.

Dlaczego programiści Javy generują akcesory dla każdego atrybutu nawet, jak nie przewidują potrzeby ich używania? Otóż czynią to “na wszelki wypadek” bo nie wiedzą, czy w przyszłości nie będzie im to potrzebne…

Weźmy np. taki kod (z powodu kolejnego ograniczenia Javy nie można w jednym pliku trzymać więcej, niż jednej klasy; tu dla krótkości umieszczam kod z obu plików razem)

public class First {
  public String msg = "hello";
}

public class Second extends First {
  public static void main(String[] args) {
    First obj = new First();        
    System.out.println(obj.msg);
  }
}

Jak widać, w Javie można sięgać do atrybutu w sposób bezpośredni.

Wyobraźmy sobie jednak, że projekt nam się rozrósł i mamy już całkiem sporo kodu oraz sporo plików (pomnażanych wydatnie przez javowe ograniczenia co do ilości klas mogących wystąpić w pliku). Teraz przychodzi polecenie aby w momencie odczytu i zapisu atrybutu coś dodatkowego wykonać. (Np. niech to będzie logowanie informacji o takim zdarzeniu, albo zablokowanie możliwości modyfikacji treści atrybutu. Wszystko jedno co)

Mamy zatem pierwszy problem. Trzeba w tych wszystkich milionach miejsc, gdzie odwoływaliśmy się bezpośrednio do atrybutów, wymienić kod…

Właśnie dlatego, aby takich niespodzianek uniknąć w przyszłości, programiści Javy dorzucają dodatkowe metody opakowujące odczyt i zapis atrybutów. Eclipse upraszcza ten proces zwalniając programistę od ręcznego wpisywania tego kodu.

Klasa First po zmianie:

public class First {
  public String msg = "hello";
  public String getMsg() {
    return msg;
  }
  public void setMsg(String msg) {
    this.msg = msg;
  }
}

Wydaje się, że problem jest rozwiązany. Ale to dopiero początek innych problemów.

Jeśli bowiem, automatycznie dorzucamy te metody do wszystkich tysięcy atrybutów nowo tworzonych klas, to pierwszą rzeczą którą zauważamy, jest nagłe “spuchnięcie kodu”. Mamy kupę nieużywanych linii kodu, z których prawdopodobnie większość nie będzie nigdy używana!

Ale to nie wszystko. Załóżmy, że stajemy przed potrzebą zmiany nazwy atrybutu. Oczywiście, możemy to zmienić w jednym miejscu (w ciele akcesora), ale wtedy wprowadzamy chaos w pozostałej części odnośnie… nazw (atrybut “msg” zmieniony na “title” trochę głupio wygląda z akcesorami o nazwie “getMsg” i “setMsg”) Musimy przekopać się przez miliony miejsc w kodzie i pozmieniać nazwy starym wywołaniom.

Zobaczmy jak ta sytuacja wygląda w językach dynamicznych.

Python

Python (podobnie jak Java) pozwala na bezpośredni dostęp do atrybutów klasy. A co w sytuacji kiedy chcemy opakować atrybut akcesorami? Nic prostszego. Python pozwala na dodanie akcesorów wtedy, i tylko wtedy, kiedy są potrzebne. Na dodatek czyni to w sposób całkowicie przezroczysty dla pozostałej części kodu. Programista Javy może sobie o tym tylko pomarzyć.

class X(object):
    def get_msg(self):
        return self.__msg
    def set_msg(self, val):
        self.__msg = val
    msg = property(get_msg, set_msg)

obj = X()
obj.msg = "hello" 
print obj.msg

Python pozwala także związać z dowolną metodą, atrybutem, klasą czy modułem docstring, czyli tekst z dokumentacją, objaśnieniem itp. To jedna z genialnych cech Pythona specjalnie pomyślana dla leniwych programistów, którym nie chce się pisać dokumentacji. ;)

Ruby

W języku Ruby z definicji nie ma żadnej możliwości dostępu do atrubutów klasy inaczej jak przez akcesory. Odpada więc problem zapominania aby je dodać. Ruby jednak narzuca nazwy dla akcesorów (mają nazwę taką jak atrybut!) i całość wygląda tak, jakby operowano bezpośrednio na atrybucie.

class X
  def msg
    @msg
  end
  def msg=(val)
    @msg = val
  end
end

obj = X.new
obj.msg = "hello" 
puts obj.msg

Dla osób, które nie lubią za dużo pisać, Ruby ma wygodne skróty. Powyższą definicję klasy można zapisać także w ten sposób:

class X
  attr_accessor :msg
end

Istnieją także oddzielne skróty dla getterów i setterów. No i można po przecinku dodać akcesory dla całej grupy atrybutów.

PHP5

PHP w wersji 5 ma przebudowany model obiektowy od podstaw. Twórcy języka PHP nie starali się poprawiać modelu obiektowego PHP4 (był on tak zły, że prościej było im napisać go od nowa). W nowym PHP5 mamy już możliwość przezroczystego dodania akcesora.

<?php
class X {
  private $attributes = array('msg'=>null);
  private function __get($attrname) {
    return $this->attributes[$attrname];
  }
  private function __set($attrname, $val) {
    $this->attributes[$attrname] = $val;
  }
}

$obj = new X();
$obj->msg = "hello";
print $obj->msg;
?>

Składnia może nie jest tak prosta jak w Ruby, ale (przynajmniej w tym miejscu), PHP5 zachowuje się tu sensownie i unika dylematów Javy.

Posted in , ,  | Tagi , , ,  | 25 comments

Symfony - kolejny naśladowca RoR

Opublikowane przez Jarosław Zabiełło Tue, 10 Jan 2006 06:30:00 GMT

Pojawia się coraz więcej naśladowców drogi jaką podążają frameworki Ruby on Rails i Django. Bardzo ciekawie wygląda pehapowy framework Symfony. Polecam przyjrzeć się udostępnionemu na stronie głównej filmowi.

Posted in  | Tagi ,  | 3 comments

Brakująca metoda GetMany dla ADOdb

Opublikowane przez Jarosław Zabiełło Tue, 15 Nov 2005 11:01:00 GMT

Jedną z najlepszych bibliotek opakowujących połączenia do baz relacyjnych dla PHP jest "ADOdb":http://adodb.sf.net. Pomijając wiele zalet używania ADOdb (zintegrowany cache, moduł w C, czytelne API) zamiast PEAR::DB lub natywnych (i koszmarnych składniowo) funkcji PHP chciałbym zatrzymać się nad jedną niedoróbka. Otóż od dawna brakuje tam Funkcji GetMany() która byłaby odpowiedzialna za pobieranie porcji danych z bazy. Jest co prawda funkcja SelectLimit() ale jest jest beznadziejna gdyż nie umożliwia korzystania z parametryzowanych zapytań SQL. Poza tym ma fatalną, nieintuicyjną nazwę. Skoro jest GetOne(), GetAll(), GetRow() to dlaczego jej też nie nazwali GetMany()? Postanowiłem te braki uzupełnić. Poniżej przykład implementacji opartej na ADOdb:
<?php
require_once 'adodb/adodb.inc.php';
require_once 'adodb/adodb-errorhandler.inc.php';

class Database
{
    var $conn;
    
    function Database($cfg)
    {
        $this->conn =& NewADOConnection($cfg['dbtype']);
        $this->conn->Connect(
            $cfg['host'], 
            $cfg['user'], 
            $cfg['passwd'], 
            $cfg['db']);
         $this->conn->SetFetchMode(ADODB_FETCH_ASSOC);
    }
    
    function GetAll($sql, $params=null)
    {
        return $this->conn->GetAll($sql, $params);
    }
       
    function GetRow($sql, $params=null)
    {
        return $this->conn->GetRow($sql, $params);
    }   
    
    function GetOne($sql, $params=null)
    {
        return $this->conn->GetOne($sql, $params);
    }   
    
    function GetMany($sql, $params=null, $from, $limit)
    {
        $result = array();
        $recordSet = $this->conn->Execute($sql, $params);
        while (!$recordSet->EOF) {
            if ($from > 0) {
                $from -= 1;
                $recordSet->MoveNext();
            } elseif ($limit > 0) {
                $limit -= 1;
                $result[] = $recordSet->fields;
                $recordSet->MoveNext();
            } else {
                $recordSet->MoveNext();
            }
        }
        return $result;
    }   
}

$cfg = array(
    'dbtype' => 'mysql',
    'host' => 'localhost',
    'user' => 'root',
    'passwd' => '',
    'db' => 'baza',
    );

# przykład:

$db = new Database($cfg);
var_dump($db->GetMany("SELECT * FROM tabelka", null, 0, 10));
?>

Posted in  | Tagi  | 9 comments