Case statement pod lupou

Posted by Jan Kubr Tue, 30 Oct 2007 21:40:00 GMT

Jak pozorní budete, když v knížce o Ruby narazíte na příkaz case? Jestli jako já, tak moc ne. Rozhodnutí, jakou větví se provádění programu vydá se řídí operátorem ===, tak co je nutné vědět více, že? Následující určitě někomu přijde jako stará známá věc, ale věřím, že ne všem. Až do nedávna jsem si myslel, že následující case:

case wifes
  when 0
     puts 'single'
  when 1
     puts 'married'
  else
     puts 'mormon'
end

se přeloží do následující operace:

if wifes === 0
  puts 'single'
elsif wifes === 1
  puts 'married'
else
  puts 'mormon'
end

Chtěl jsem ale, aby můj test vlezl do všech těchto větví (to je takový dobrý testovací návyk;) a jal jsem se nahradit metodu === na objektu wifes něčím (mockem), co mi vrátí postupně všechny hodnoty. A ono to nefungovalo. Zkoumáním nalezené skutečnosti v irb jsem dospěl k různým zajimavostem, které jsem si předtím dostatečnš neuvědomil:

irb(main):001:0> String === ""
=> true
irb(main):002:0> "" === String
=> false
irb(main):003:0> /h/ === "hey"
=> true
irb(main):004:0> "hey" === /h/
=> false

Aneb potřeboval jsem si znova uvědomit, že === není žádný komutativní operátor, ale metoda a ta může (a je) v různých třídách implementována různě. A jak to navazuje na case statement? No ten příkaz se ve skutečnosti vykoná takhle:

if 0 === wifes
  puts 'single'
elsif 1 === wifes
  puts 'married'
else
  puts 'mormon'
end

Metoda === se tedy nevolá na objektu stojícím za klíčovým slovem case, ale na objektech za "whens" v jednotlivých větvích. Zajimavé to pak začíná být především v případech, kdy nejsou všechny objekty instance stejné třídy. Doufám, že to dává smysl. Objasňuje to i tyhle hojně využívané casy:

case extension.downcase
  when /jpg$/
    puts "picture"
  when /mp3$/
    puts "song"
end
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
 case res
  when Net::HTTPSuccess, Net::HTTPRedirection
    # OK
  else
    res.error!
 end

no comments |

Použití MemCache jako úložiště pro sessions

Posted by Kamil Kukura Thu, 18 Oct 2007 19:28:00 GMT

Railsy umí používat pro ukládání sessions různá uložiště, přičemž ve výchozím nastavení používá PStore, jenž je implicitním úložištěm, se kterým pracuje CGI::Session. To jsou ty malé soubory v adresáři tmp/sessions, které vlastně obsahují serializované proměnné, které jsou v danou dobu v konkrétní session uloženy. Dále je pak možné použít uložení těchto sessions do databáze (přes ActiveRecord) nebo taky přímo do obsahu cookie (CookieStore), což zvyšuje o něco traffic, ale na druhou stranu nejsou nutné dodateční pomalé IO operace.

Zajímavou možnosti je použití operační paměti přes speciální server memcached. Ten byl původně vyvinut pro zvládnutí zátěže na LiveJournal.com a dnes je k dispozici téměř na všech známých platformách. Na straně Ruby je potřeba gem memcache-client, který dokonce umí používat několik serverů zároveň. Protože všechny data jsou ukládany v páru klíč - hodnota, tak pomocí hashovací funkce dokáže rozhodit jednotlivé klíče (a samozřejmě jejich data) na více serverů. Jako úložiště je možné memcache použít i pro ukládání stránek, což může hodně pomoct odlehčit nápor na databázový server.

Zavedení pro ukládání sessions se děje obvykle v souboru environments/production.rb, který konfiguruje aplikaci v produkčním režimu. K tomu stačí vyrobit MemCache objekt a spolu se specifikací expirace ho napojit na ActionController:

CACHE = MemCache.new 'localhost:11211',
                     :namespace => "myapp-#{RAILS_ENV}"
ActionController::Base.session_options[:expires] = 1800
ActionController::Base.session_options[:cache] = CACHE

Samozřejmě v tomto případě musí na localhostu běžet memcache daemon na svém výchozím portu 11211. V případě, že nějaká masívně využívaná aplikace, resp. hodně navštěvovaný web běží v clusteru na více serverech, tak je logicky nutné vyhradit jeden nebo více serverů, kde bude běžet memcached daemon a na něj, resp. na ně nasměrovat všechny instance aplikace/webu.

Bohužel, v čase psaní v aktuální verzi Rails (1.2.5) je menší chyba, který způsobuje podivné chování při nasazení memcache úložiště v prostředí clusterů. Je nutné aplikovat tuhle opravu, která už bude zahrnutá do dalších verzí, je možné že to už bude přímo Rails 2.0

Posted in | no comments |

Kniha o Ruby on Rails zdarma

Posted by Jan Kubr Tue, 16 Oct 2007 15:05:00 GMT

Narazil jsem na tuto knihu o Ruby on Rails, která je dostupná zdarma. Jenom jsem ji rychle proletěl, kvalita bude asi podobná ceně, ale říkal jsem si, že by se mohla hodit nějakému úplnému začátečníkovi, který chce ušetřit peníze (nebo je neutratit ZATÍM). Lepší než hledat nějaké staré tutoriály nebo kusé informace na blozích..

no comments |

Střípky rubínu

Posted by Jan Kubr Tue, 09 Oct 2007 11:17:00 GMT

Pokud jako já někdy dumáte, jestli se Ruby dostane v budoucnu většího rozšíření, pomoci vám může toto video se Zedem Shawem (autorem Mongrelu) a Mattem Pelletierem, kde pánové rozebírají, jak moc je Ruby "enterprise-ready." Za pozornost stojí i slajdy z přednášky Davida Majdy, které promítal na své přednášce na minulém setkání Ruby on Rails komunity v Praze. Prezentace se sice jmenuje "Alternativní implementace Ruby", ale naznačuje, že brzy až tak alternativní být nemusí. David uvádí i zajímavé odkazy na další články rozebírající fázi, v jaké se Ruby v současnosti nachází. Myslím, že přehlednější a především rychlejší implementace by mohla Ruby pořádně nakopnout.

Pokud chcete mít rychlou i dokumentaci, zkuste tu na Rubybrain, obdoby Railsbrain, který už asi znáte. Prý se chystá i gemsbrain. Pokud ale upřednostňujete mít vše na jednom místě před "živým" vyhledáváním (které mě osobně baví nejvíc), můžete zkusit noobkit.

A pak až něco v Ruby napíšete a budete chtít vědět, jak moc (příliš) složité to je, zkuste flog.

Jinak v listopadu se chystám na Rubyconf, pokud někdo z Česka jedete také, dejte vědět. Pokud se zas někdo vyrazí na evropskou obdobu, rád se dozvím vaše dojmy.

A aby tento příspěvek byl také trochu o Railsech: Nevím jak vy, ale já nejsem superpečlivý v přidávání metody h (totéž co htmlescape, převede HTML tagy na "neškodné" HTML entity) před (skoro) každý řetězec. Nainstaloval jsm si tedy pluing safeerb, který mě na všechna neošetřená místa upozorní. Upozorní mě ale vyhozením výjimky, takže ho na produkci instalovat nedoporučuju, nějaké zapomenuté místo nepokryté testy by mohlo (typicky nezákeřného) uživatele nemile potěšit.

2 comments |