Any fool can make things bigger, more complex, and more violent. It takes a touch of genius and a lot of courage to move in the opposite direction. Albert Einstein

o Ruby

Tribute to PHP - plugin do railsów, bez którego nie będziesz mógł żyć!

33 komentarze | Kategorie: Humor, Ruby, Ruby on Rails, Techblog | trackback
Tagi:

Myślę, że niewiele ryzykuję twierdząc, że większość piszących w Rubym tudzież Railsach dosyć intensywnie pisała wcześniej w PHP. Ja też nie jestem tu wyjątkiem. I chociaż uciekam od PHP jak najdalej i chyba tylko siłą można mnie zmusić by w tym pisać to są takie chwile, że tęskni się za pewnymi rozwiązaniami tego języka/środowiska.

Jednym z takich elementów PHP, za którym tęsknią bezwzględnie wszyscy są globalne zmienne $_GET, $_POST, $_COOKIE, $_SESSION. Otóż Railsy próbowały w jak najbardziej elegancki sposób rozwiązać te kwestie, jednak w tej kwestii na tle PHP wypadają słabo.

Sztucznie narzucony model MVC tylko zabiera nam swobodę programowania. Ile razy chciałeś sięgnąć w modelu to sesji, parametrów żądania czy też ciasteczek? A co z innymi miejscami takimi jak szablony czy też kod w katalogu RAILS_ROOT/lib/? Tak, tutaj Railsy są mocne ograniczone i tylko próbują to przed nami ukryć!

Na szczęście są sposoby by to obejść. Specjalnie na tę okazję napisałem dla Was plugin: Tribute to PHP. Wprowadza on wspomniane globalne zmienne. Możesz je używać dokładnie tak jak w PHP! Dodatkowo posiada chyba najlepsze co mogło się przydarzyć PHPowi (i nie wiem dlaczego zostało to wycofane z najnowszych wersji PHP - być może to jeden z tych złych posunięć, które poprowadzi PHP do śmierci:( ) a chodzi oczywiście o słynne (nie bez przyczyny) "register globals". W oryginale można było włączyć bądź wyłączyć tę opcję, w tym pluginie "register globals" jest włączone zawsze. Uważam, że wyłączanie tak przydatnej opcji mija się z celem.

Pozostaje mi tylko pokazanie małego przykładu użycia i umieszczenia kodu samego pluginu. Zachęcam wszystkich do pisania własnych propozycji co do rozwoju pluginu. Myślę, że Railsy w połączeniu z tymi najlepszymi cechami PHP mogą być jeszcze lepsze!

class User < ActiveRecord::Base
  def self.authenticate
    return $_POST['login'] == "radarek"
  end
end

class HelloController < ApplicationController
  def index
    if request.post?
      render :layout => true, :inline => %Q{
      Twoj imie to: #{$imie}
      }
    else
      render :layout => true, :inline => %Q{
      <form method="post">
        Podaj imie: <input type="text" name="imie" />
        <input type="submit" value="Ok" />
      </form>
      }
    end
  end
  
  def login_form
    render :layout => true, :inline => %Q{
    <form method="post" action="login">
      Podaj imie: <input type="text" name="login" />
      <input type="submit" value="Ok" />
    </form>
    }
  end
  
  def login
    if User.authenticate
      render :text => "OK"
    else
      render :text => "Sorry..."
    end
  end
  
  def guess
    if $_GET["a"] == "1" && $_GET["b"] == "2"
      $_SESSION["c"] = "3"
      redirect_to :action => "guessed"
      return
    end
    render :text => "guess"
  end
  
  def guessed
    render :text => $_SESSION["c"]
  end
end

To tylko kilka prostych przykładów. Pamiętaj o tym, że dostęp do tych zmiennych masz z każdego miejsca aplikacji! Otwiera to nowe możliwości i tylko Twoja wyobraźnia jest ich ograniczeniem. Czekam na Wasze opinie i jestem ciekaw ilu z Was oprze się pokusie użycia tego w produkcji!

Na koniec kod pluginu

Kod pliku init.rb

TributeToPhp.setup_global_variables
ActionController::Base.send(:include, TributeToPhp::Controller)

Kod pliku lib/tribute_to_php.rb

# TributeToPhp
module TributeToPhp
  module Controller
    def self.included(base)
      base.alias_method_chain :perform_action, :extract_php_params
    end
    
  protected
  
    def perform_action_with_extract_php_params(*args, &block)
      $_GET.params     = self.request.query_parameters
      $_POST.params    = self.request.request_parameters
      $_COOKIE.params  = self.request.cookies
      $_SESSION.params = self.session
      
      # register globals
      registered_globals = []
      [$_GET, $_POST, $_COOKIE, $_SESSION.data].each do |superglobal|
        superglobal.each do |name, value|
          if name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
            registered_globals << name
            eval("$#{name} = #{value.inspect}")
          end
        end
      end
      begin
        perform_action_without_extract_php_params(*args, &block)
      ensure
        registered_globals.each do |variable_name|
          eval("$#{variable_name} = nil")
        end
      end
    end
  end # Controller
  
  class HashParamsProxy
    attr_accessor :params
    
    def initialize(params = nil)
      @params = params
    end
    
    def [](*args)
      self.params.send(:[], *args) if self.params
    end
    
    def []=(*args)
      self.params.send(:[]=, *args) if self.params
    end
    
    def method_missing(method_name, *args, &block)
      if self.params && self.params.respond_to?(method_name)
        return self.params.send(method_name, *args, &block)
      else
        return super(method_name, *args, &block)
      end
    end
  end # HashParamsProxy
  
  def self.setup_global_variables
    $_GET  = TributeToPhp::HashParamsProxy.new
    $_POST = TributeToPhp::HashParamsProxy.new
    $_COOKIE = TributeToPhp::HashParamsProxy.new
    $_SESSION = TributeToPhp::HashParamsProxy.new
  end
end

Jeśli spodobał Ci się wpis to może umieścisz ten blog w swoim czytniku RSS?

Komentarze

1. avatar icon Albi napisał(a) 21 Kwi 2008 o godz. 07:18:

Żart? Register globals doprowadziło do tylu błędów, że jak widzę kod z ich użyciem, to mnie mdli…

2. avatar icon BTM napisał(a) 21 Kwi 2008 o godz. 10:05:

ZOMG! Jesteś chyba jedyną osobą, która uważa że RG jest dobre, a wynika to pewnie z: – byciem omega-programistą, który przewiduje każdy wypadek wykorzystania skryptu i definiuje każdą zmienną przed jej użyciem – nie znajomości zagrożeń z tym związanych – skończonego kretynizmu – byciem dupą a nie programistą ;-)

3. avatar icon Tomash napisał(a) 21 Kwi 2008 o godz. 10:11:

LOL
666/10 za pomysł i realizację :D
Globale pehapowe to pikuś, wykorzystanie inline’owych renderów niszczy w tym tekście najbardziej. :D

Brawo dla wszystkich, którzy nie zrozumieli dowcipu Radarka ;)

4. avatar icon btm napisał(a) 21 Kwi 2008 o godz. 10:13:

Jeżeli defacto jest to dowcip, to wyjątkowo nie udany – nie każdy musi znać RoR. Tak samo mogę zaraz napisać dowcip w Brainfuck’u i ciekawe, kto zrozumie? ;>

5. avatar icon Tomash napisał(a) 21 Kwi 2008 o godz. 11:12:

Targetem tej notki są programiści RoR, co widać po – tytule – wstępie – tagach – tekście – fragmentach kodu

Po prostu nie złapałeś dowcipu i tyle, nie ma co się wykręcać z braku lotności :P

6. avatar icon Seban napisał(a) 21 Kwi 2008 o godz. 13:11:

Co za perfidna prowokacja. ;-)

7. avatar icon dr_bonzo napisał(a) 21 Kwi 2008 o godz. 14:10:

jak prowokacja – to dobra :D
jak rzeczywista potrzeba – to o japierdole

8. avatar icon Albi napisał(a) 21 Kwi 2008 o godz. 15:19:

Właśnie dlatego pytałem, czy to żart :>

9. avatar icon Radarek napisał(a) 21 Kwi 2008 o godz. 17:51:

Nie myślałem, że ktoś weźmie to na poważnie :D. Dobrze chociaż, że Ci co dobrze odgadli moje intencje byli tego w 100% pewni.

Jeżeli defacto jest to dowcip, to wyjątkowo nie udany – nie każdy musi znać RoR.

Dobre żarty zwykle wymagają pewnej wiedzy. Mój blog jest dedykowany Rubiemu, a póki co po ludziach piszących w tym języku mogę się spodziewać, że znają Railsy.

10. avatar icon BTM napisał(a) 21 Kwi 2008 o godz. 17:53:

Akurat nie piszę w Ruby, a wpis ukazał się na jogger.pl a nie ruby.pl więc nie zakładajmy, że każdy kto odwiedza Twój blog wie o czym jest ;-)

11. avatar icon Radarek napisał(a) 21 Kwi 2008 o godz. 17:55:

Oczywiście nikomu nie zabraniam, a właściwie zachęcam do śledzenia mojego bloga :). Każdy blog ma swoją tematykę, wystarczy prześledzić kilka postów z głównej strony joggera. Czyżby zachęciło Cię słowo „PHP” w tytule do przeczytania wpisu?:P

12. avatar icon btm napisał(a) 21 Kwi 2008 o godz. 17:56:

Jak programistę PHP, tak właśnie się stało ;-)
Nie ukrywam, że PHP nie jest w moich oczak idealnym językiem, ma wiele wad ale nadaje się do tego, czego od niego oczekuję.
Ruby liznąłem parę razy – ma fajną składnie, ale jakoś do mnie RoR nie przemawia ;-)

13. avatar icon Radarek napisał(a) 21 Kwi 2008 o godz. 18:06:

@btm i wiesz co Ci powiem? Pozostań przy PHP póki co. Serio. Dopóki jest to dla Ciebie wystarczające narzędzie i nie denerwuje Cię to co denerwowało nas wszystkich* w PHP to nie ma sensu na siłę pisać w Rubym/Rails. Railsy są super, ale to nie jest złoty środek na wszystko.

Czasem też trzeba tak bardzo pomęczyć dany język, aż zacznie nas coś w nim denerwować (tak miałem z PHP). U mnie to się przerodziło we frustrację stąd przejście na Ruby. I nie dość, że Ruby to co denerwowało mnie w PHP ma zrobione porządnie (przede wszystki OOP) to jeszcze doszło do tego masę wspaniałych rzeczy (np. metaprogramowanie, DSL).

Aczkolwiek tak jak wspomniałem, gdybym nie posiadał pewnej wiedzy to nie doceniłbym tego w Rubym. To tak jakbyś komuś chciał pokazać, że MVC jest lepsze niż 1 plik php w którym masz html + php + sql, osobie, która w ogóle nie programowała. Trzeba wpierw poczuć na własnej skórze czym to się kończy :).

*nas wszystkich – czyli ludzi piszących w Rubym, którzy wcześniej pisali w PHP (myślę, że około 95% obecnych programistów Rubiego)

14. avatar icon btm napisał(a) 21 Kwi 2008 o godz. 18:11:

Ale widzisz, ja (aktualnie) nie mam ambicji pisać większych aplikacji, bo wiem ile przy tym jest rypania – wiem ile jest rypania już przy średnich aplikacjach.
Nie chcę zaczynać dyskusji o przewadze proszku A nad proszkiem B – jak mówiłem, w PHP jest wiele rzeczy które mnie denerwują (np. nie ma możliwości przeładowania większości funkcji, że o przeładowaniu operatorów nie wspomnę) – ale jako osoba koncentrująca się raczej na tworzeniu stron, sklepów i średni zaawansowanych portali a przy tym w PHP orientująca się – powiem nie skromnie – doskonale + posiadająca pewien warsztat (swój własny CMS, swój własny framework) etc. nie widzę aktualnie potrzeby zmiany platformy.
Dodatkowo, wierzę, że rozwój języka zmierzać będzie w dobrym kierunku.

A dodatkowo, jak mam z tego kasę na którą nie mam podstaw narzekać (powiem tylko, że ostatnio pewna firma oferowała mi prawie 4.500 netto na miesiąc, ale im odmówiłem i zostałem tam gdzie jestem) ;-)

15. avatar icon Radarek napisał(a) 21 Kwi 2008 o godz. 18:17:

Dlatego właśnie napisałem: Ruby nie jest złotym środkiem, nie trafi do każdego i nie ma potrzeby bo wszyscy na niego przechodzili :). To nie są żadne podchody, ale życiowe i pragmatyczne podejście. Jeśli ktoś zainwestował sporo czasu w swoje umiejętności (np. programowania PHP, frameworki, biblioteki) to przejście na inną technologię nigdy nie obędzie się bez ogromnego wysiłku i sporej ilości czasu.

ps. Ruby też ma wady, swoje kruczki i „quirks”... :)

16. avatar icon Paweł Rutkowski napisał(a) 21 Kwi 2008 o godz. 19:02:

Trollujesz :)

17. avatar icon Radarek napisał(a) 21 Kwi 2008 o godz. 19:05:

Jak to trolluje?:>

18. avatar icon Psi napisał(a) 21 Kwi 2008 o godz. 19:23:

Kurde, Radarek, aleś nawymyślał... :D sam się nabrałem, dopiero po paru akapitach zacząłem mieć wątpliwości, a przy widokach inline sprawa się wyjaśniła ;)

19. avatar icon Radarek napisał(a) 21 Kwi 2008 o godz. 19:24:

Psi, zobaczysz, jeszcze będą tacy co będą mi dziękować za ten plugin! :P

20. avatar icon Tomash napisał(a) 21 Kwi 2008 o godz. 21:58:

BTM, prosta sprawa – do odrzucenia pehapa trzeba… jak by to ująć, żeby nie urazić pehapowców (sam jestem, co prawda byłym, ale zawsze)... dojrzeć. Zrobić w tym języku jakiś poważniejszy sajt „from scratch” albo chociaż uczestniczyć w tworzeniu lub utrzymaniu takiego.
To główny powód, dla którego rubiowcy (railsowcy konkretnie) nie ewangelizują „na siłę” pehapowców – dojrzeją, sfrustrują się, po drodze poznają zaawansowane techniki i narzędzia i będą bardzo dobrym i podatnym materiałem na nauczenie RoR :)

21. avatar icon egzemplarz napisał(a) 22 Kwi 2008 o godz. 13:43:

E tam, wcale nie trzeba dojrzewać. Czasem wystarczy poznać inny język i już :). Ja odrzuciłem PHP od kiedy poznałem Pythona i zacząłem interesować się Django, oraz GAE . Co prawda programowaniem zajmuje się totalnie hobbystycznie (nie wiążę z tym swojej przyszłości), ale naprawdę poznanie Pythona wystarczyło do stwierdzenia, że jeżeli musiał nie będę to do PHP nie wrócę.

22. avatar icon NetManiac napisał(a) 22 Kwi 2008 o godz. 21:37:

Psi, zobaczysz, jeszcze będą tacy co będą mi dziękować za ten plugin! :P

Na pewno się tacy znajdą.

23. avatar icon Radarek napisał(a) 22 Kwi 2008 o godz. 21:39:

Nie no, bądźmy poważni. Jak ktoś użyje tego na serio to ma lekko niepoukładane w głowie. Nie wierzę, że jest ktoś w stanie przebrnąć przez railsy i widzieć sens użycia tego :).

24. avatar icon JO napisał(a) 22 Kwi 2008 o godz. 21:52:

Szanuje cie Radarek ale to są spore Jaja :) JA nie pisałem nigdy w PHP ale jakbym zobaczyl ten plugin to bym sie wystraszył i zapytał ludzi w projekcie czy komuś przez przypadek nie zlasował sie mózg.

25. avatar icon NetManiac napisał(a) 22 Kwi 2008 o godz. 21:55:

Serio, serio

Moje ostatnie doświadczenia z wyrobnikami od Javy, którzy zostali zmuszeni do pisania w Rails (w sensie – klienci na nich to wymogli) jest takie, że z chęcią po coś takiego by sięgnęli.

A tak na poważnie – niestety, ale są miejsca gdzie brak dostępu do sesji HTTP uniemożliwia pisanie aplikacji fat model/skinny controller (dopuszczam możliwość, że czegoś nie wiem ;) ). Chodzi na przykład o Facebook API – obiekty do komunikacji z FB muszą mieć dostęp do sesji, więc w modelu nie użyjesz ich, a to oznacza że cała logika korzystająca z calli do FB API musi pozostać w kontrolerze.

26. avatar icon Radarek napisał(a) 22 Kwi 2008 o godz. 21:56:

@JO: no bo to są po prostu jaja. Taki przerywnik. Przy okazji można czegoś się nauczyć (ktoś analizował kod pluginu?). Chyba nie wziąłeś tego serio?;)

27. avatar icon JO napisał(a) 22 Kwi 2008 o godz. 21:57:

Nie no :D niema czasu na takie marnotrastow jak analiza kodu plugina :)

28. avatar icon Radarek napisał(a) 22 Kwi 2008 o godz. 22:02:

@JO: aha, Ty jesteś z tych co wezmą, skopiują i użyją?:D (żart)

@NetManiac: niech zgadnę, Ci javowcy piszą kod Javy w Rubym?;) (http://radarek.jogger.pl/2008/04/14/you-can-write-fortran-in-any-language/ ).

To, że są miejsca, w których nie ma dostępu do żądania http czy też sesji to zbawienie. Inaczej kończysz na zapytaniach SQL wprost z szablonu.
A co do FaceBook API – nie używałem ale pamiętam, że chyba opisywałeś ten problem na blogu. Nie ma tu innej siły jak po prostu przekazywać explicite parametr do metody.

29. avatar icon JO napisał(a) 22 Kwi 2008 o godz. 22:09:

:D Tak ! masz mnie :> Od dziś używam tylko PHP_RAILS i zaraz zaczne rozkminiac jego kod :>

30. avatar icon ja napisał(a) 04 Maj 2008 o godz. 12:08:

akurat prowokacja… uratuwał swoją dupę w badziewny sposób…. „obłsuga parametrów żądań w modelu” .. mega kurwa lol

31. avatar icon Radarek napisał(a) 04 Maj 2008 o godz. 14:27:

Mr @ja: jeśli chcesz podyskutować to nie używaj brzydkich słów (te zostaw na inne okazje) i podpisz się. Mogę zrozumieć, że nie załapałeś żartu, ale takiego zachowania nie bardzo. Pozdro.

32. avatar icon pow(b*k; n) napisał(a) 05 Maj 2008 o godz. 10:38:

Gdybym znał RoR, gdybym znał PHP to bym może zaoszczędził życia na analizie tego kodu ;P a tak … zabrakło mi definicji metody perform_action_without_extract_php_params
i już wiedziałem, że coś tu śmierdzi :/
ehhh życie :D

33. avatar icon Radarek napisał(a) 05 Maj 2008 o godz. 13:11:

To po części magia rails.

base.alias_method_chain :perform_action, :extract_php_params

to inny zapis

base.class_eval do
  alias_method :perform_action_without_extract_php_params, :perform_action
  alias_method :perform_action, :perform_action_with_extract_php_params
end

Tutaj można doczytać: http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain i google: alias_method_chain .

Dodaj coś od siebie

Możesz korzystać ze składni Textile.

Pola oznaczone * są wymagane.

Proszę o dodawanie komentarzy związanych z tematem postu, sprawy osobiste proszę załatwiać przez maila bądź gg.

Zastrzegam sobie prawo do moderacji komentarzy (edycja, usuwanie).