<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.zabiello.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Jarosław Zabiełło - BLOG : </title>
    <link>http://blog.zabiello.com/.rss</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.zabiello.com/hipertracker" /><feedburner:info uri="hipertracker" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Rails 3.0 beta</title>
      <description>&lt;p&gt;Muszę przyznać, że wydana parę tygodni temu wersja beta Ruby on Rails 3.0 wygląda bardzo obiecująco. Choć to dopiero beta, to wprowadzone razem z nią ulepszone zarządzanie gemami za pomocą &lt;code&gt;Bundler'a&lt;/code&gt; robi dobre wrażenie. Aby ułatwić sobie eksperymentowanie z nowym RoR 3.0, najlepiej zainstalować wpierw &lt;code&gt;RVM&lt;/code&gt;...&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;RVM&lt;/span&gt; (Ruby Version Manager)&lt;/h2&gt;


	&lt;p&gt;&lt;code&gt;RVM&lt;/code&gt; (&lt;a href="http://rvm.beginrescueend.com"&gt;http://rvm.beginrescueend.com/&lt;/a&gt;) wprowadza nową jakość do niezbyt wygodnego zarządzania wersjami Ruby&amp;#8217;ego jakie było do tej pory stosowane. Pozwala na instalację, izolację i błyskawiczne przełączanie się między różnymi wersjami (i implementacjami!) Ruby&amp;#8217;ego &amp;#8211; od stabilnych po rozwojowe, od Ruby 1.8.0 po 1.9.2 preview1, JRuby, IronRuby, MacRuby (dla OS-X), MagLev czy Rubinius.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;rvm list known&lt;/code&gt; &amp;#8211; wyświetli listę wszystkich dostępnych instalacji&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rvm install 1.9.1&lt;/code&gt; &amp;#8211; zainstaluje Ruby 1.9.1&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rmv use 1.9.1 --default&lt;/code&gt; &amp;#8211; ustawi Ruby 1.9.1 jako domyślną wersję (dla nowej konsoli)&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rvm use system&lt;/code&gt; &amp;#8211; powróci do ustawień systemowych &lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rvm help&lt;/code&gt; &amp;#8211; wyświetli dostępne komendy&lt;/li&gt;
	&lt;/ul&gt;


&lt;pre class="brush:bash"&gt;     
$ rvm install 1.9.1              
$ rvm use 1.9.1
$ which ruby
/Users/adm/.rvm/rubies/ruby-1.9.1-p378/bin/ruby 
$ which gem
/Users/adm/.rvm/rubies/ruby-1.9.1-p378/bin/gem
&lt;/pre&gt;

	&lt;p&gt;Instalacja i przełączenie się na najnowszego JRuby&amp;#8217;ego:&lt;/p&gt;


&lt;pre class="brush:bash"&gt;
$ rvm install jruby-head
$ rvm use jruby-head

$ which ruby
/Users/adm/.rvm/rubies/jruby-head/bin/ruby

$ which gem
/Users/adm/.rvm/rubies/jruby-head/bin/gem

$ ruby -v
jruby 1.5.0.dev (ruby 1.8.7 patchlevel 174) (2010-02-23 944db04) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_17) [x86_64-java]
&lt;/pre&gt;

	&lt;p&gt;Powrót do Ruby 1.9.1:&lt;/p&gt;


&lt;pre class="brush:bash"&gt;       
$ rvm use 1.9.1
$ ruby -v
ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-darwin10.2.0]
&lt;/pre&gt;

	&lt;p&gt;Proste i wygodne. Nigdy więcej paskudnych nazw typu ruby1.8, ruby1.9, gem1.9 itp. Koniec też z niespójnością skryptów które mają taką samą nazwę ale różną linijkę &lt;em&gt;shebang&lt;/em&gt; (wskazującą jaki interpreter Ruby&amp;#8217;ego należy użyć dla odpalenie skryptu).&lt;/p&gt;


	&lt;p&gt;Zobacz też screencast &lt;a href="http://railscasts.com/episodes/200-rails-3-beta-and-rvm"&gt;Rails 3 Beta and &lt;span class="caps"&gt;RVM&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Uwaga: w wypadku używania &lt;span class="caps"&gt;RVM&lt;/span&gt; nie należy używać komendy &lt;code&gt;sudo&lt;/code&gt; (dla systemów &lt;span class="caps"&gt;POSIX&lt;/span&gt;) gdyż wszystkie wersje Ruby’ego wraz ze swymi gemami są instalowane w katalogu domowym użytkownika &lt;code&gt;~/.rvm&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Updated 2010-02-28:&lt;/p&gt;


	&lt;p&gt;W wypadku korzystania z wersji rozwojowych, np. jruby-head lub maglev-head, aktualizacja do najnowszej wersji polega na usunięciu i zainstalowaniu danego interpretera Ruby&amp;#8217;ego. Ta operacja jednak &lt;em&gt;nie wymaga reinstalacji&lt;/em&gt; gemów bo nie są one kasowane.&lt;/p&gt;


&lt;pre class="brush:bash"&gt;       
rvm remove maglev-head
rvm install maglev-head
&lt;/pre&gt;

	&lt;h2&gt;Rails 3 i bundler&lt;/h2&gt;


	&lt;p&gt;Instalacja bety Rails 3.0 jest prosta. Zakładając że mamy wiele wersji Ruby&amp;#8217;ego, i wiedząc że Rails 3 wymaga Ruby w wersji minimum 1.8.7, cała instalacja sprowadza się do krótkiego polecenia:&lt;/p&gt;


&lt;pre class="brush:bash"&gt;
gem install rails --pre
&lt;/pre&gt;

	&lt;p&gt;Z tego co sprawdziłem,  nie ma już potrzeby instalowania całej listy wcześniejszych gemów, jak to &lt;a href="http://weblog.rubyonrails.org/2010/2/5/rails-3-0-beta-release/"&gt;podawano na oficjalnym blogu&lt;/a&gt; Rails.&lt;/p&gt;


	&lt;p&gt;Razem z instalacja Rails 3 beta zostanie zainstalowany gem &lt;code&gt;bundler&lt;/code&gt;. Od tego momentu, można używać skryptu &lt;code&gt;bundle&lt;/code&gt; zamiast &lt;code&gt;gem&lt;/code&gt;. W Rails 3 zależności między gemami dla aplikacji są ustawianie w pliku Gemfile. To jest główne miejsce gdzie są ustawiane wszystkie zależności. Jeśli nasza aplikacja potrzebuje do swej pracy jakiegoś konkretnego gemu, to tam należy to sobie dodać. Wybrane komendy:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;bundle check&lt;/code&gt;  &amp;#8211; sprawdzi czy nie brakuje nam jakiegoś gemu niezbędnego do działania aplikacji RoR3&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;bundle install&lt;/code&gt; &amp;#8211; instaluje wszystkie gemy niezbędne do działania aplikacji RoR3&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;bundle lock&lt;/code&gt; &amp;#8211; &amp;#8220;zamraża&amp;#8221; gemy potrzebne dla aplikacji RoR3 tworząc plik Gemfile.lock. Nie jest możliwe instalowanie gemów (wcześniejsze )&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;bundle pack&lt;/code&gt; &amp;#8211; kopiuje gemy potrzebne do aplikacji do &lt;code&gt;vendor/cache&lt;/code&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;bundle show&lt;/code&gt; &amp;#8211; wyświetli listę gemów używanych przez aplikację RoR3&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;bundle install --relock&lt;/code&gt; &amp;#8211; instaluje najnowsze (jeśli trzeba) wersje gemów i ponownie zamraża listę gemów.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Wczesniejsze komendy &lt;code&gt;rake rails:freeze:gems&lt;/code&gt; czy &lt;code&gt;rake rails:unfreeze&lt;/code&gt; nie są zalecane. Zamiast nich należy używać bundler&amp;#8217;a.&lt;/p&gt;


	&lt;p&gt;Zobacz też screencast &lt;a href="http://railscasts.com/episodes/201-bundler"&gt;Bundler&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Rails 3 &amp;#8211; zmiany&lt;/h2&gt;


	&lt;p&gt;Poza większą wydajnością i modularnością, w Rails 3 wprowadzono szereg innych zmian i ulepszeń. M.in. zlikwidowano grupę skryptów z katalogu &lt;code&gt;script/&lt;/code&gt; i zastąpiono go jednym &amp;#8211; &lt;code&gt;rails&lt;/code&gt;. ActiveRecord, dzięki nowemu gemowi &lt;a href="arel"&gt;http://github.com/nkallen/arel&lt;/a&gt; uzyskał bardziej obiektową składnię oraz opóźnione (lazy) wywoływanie połączeń z bazą. Dane są pobierane z bazy dopiero w momencie kiedy są potrzebne. To ułatwia ich buforowanie, składanie z warunków oraz testowanie. Nowy AR doczekał się, wzorowanego na &lt;a href="http://sequel.rubyforge.org/"&gt;Sequelu&lt;/a&gt;, polecenia &lt;a href="http://apidock.com/rails/ActiveRecord/ConnectionAdapters/TableDefinition/to_sql"&gt;.to_sql&lt;/a&gt; dzięki któremu można wyświetlić generowany kod &lt;span class="caps"&gt;SQL&lt;/span&gt; przed jakimkolwiek połączeniem z bazą. Zobacz też screencast &lt;a href="http://railscasts.com/episodes/202-active-record-queries-in-rails-3"&gt;Active Record Queries in Rails 3&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Rails 3 wspiera również tzw. &lt;a href="http://zaa.ch/24"&gt;nieiwazyjny JavaScript&lt;/a&gt; (czyni to za pomocą składni z &lt;span class="caps"&gt;HTML5&lt;/span&gt;) dzięki czemu helpery widoku nie generują już więcej wstawek JavaScriptu w kodzie &lt;span class="caps"&gt;HTML&lt;/span&gt;. &lt;a href="http://joshhuckabee.com/jquery-rails-3"&gt;Łatwiej zatem przełączyć się&lt;/a&gt; z (domyślnego) Prototype na inną bibliotekę, np. jQuery.&lt;/p&gt;


	&lt;p&gt;Wspomniana wcześniej modularność Rals 3 to też silna strona nowej wersji tego frameworka. Każdy wcześniejszy główny moduł składający sie na Rails został gruntownie przebudowany i odizolowany. Rails 3 nie posiada znanych z wersji 2.x zależności frameworka od Active Record. Zarówno Active Record jaki i Action Controller czy Action Mailer są niezależnymi modułami które można sobie wyłączyć lub wymienić (np. teraz jest łatwiej wymienić Active Record na inny &lt;span class="caps"&gt;ORM&lt;/span&gt;). Z perspektywy Rails 3 wszystkie te moduły są nowymi pluginami (zobacz &lt;a href="https://gist.github.com/af7e572c2dc973add221"&gt;Railtie&lt;/a&gt;). Rails 3 wprowadził także montowalne aplikacje. Każda aplikacja Rails 3 może być użyta jako komponent wchodzący w część kolejnej aplikacji Rails 3. W zasadzie to nie dotyczy tylko Rails 3 ale dowolnego frameworka zgodnego z webowym interfejsem &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;. Tzn. w Rails 3 można wpiąć sobie w wybrane adresy &lt;span class="caps"&gt;URL&lt;/span&gt; zarówno inna aplikację Rails 3 jak i Sinatrę, Merba, Ramaze czy inny framework zgodny z Rack (teraz praktycznie wszystkie są z tym zgodne).&lt;/p&gt;


	&lt;p&gt;Dokładniejsza lista zmian jest dostępna na&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://guides.rails.info/3_0_release_notes.html"&gt;Rails 3.0: Release Notes&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Zobacz też artykuły Yehuda Katz&amp;#8217;a na &lt;a href="http://yehudakatz.com/tags/rails-3/"&gt;blogu&lt;/a&gt; oraz na stronach firmy Engine Yard:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2010/rails-3-beta-is-out-a-retrospective/"&gt;Rails 3 Beta is Out — A Retrospective&lt;/a&gt;            &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-the-anniversary-part-1-of-6/" title="Part 1 of 6"&gt;Rails and Merb Merge: The Anniversary&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/" title="Part 2 of 6"&gt;Rails and Merb Merge: Performance&lt;/a&gt;                                                        &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2010/rails-and-merb-merge-plugin-api-part-3-of-6/" title="Part 3 of 6"&gt;Rails and Merb Merge: Plugin &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2010/rails-and-merb-merge-rails-core-part-4-of-6/" title="Part 4 of 6"&gt;Rails and Merb Merge: Rails Core&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.engineyard.com/blog/2010/rails-and-merb-merge-orm-agnosticism-part-5-of-6/" title="Part 5 of 6"&gt;Rails and Merb Merge: &lt;span class="caps"&gt;ORM&lt;/span&gt; Agnosticism&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=64P82YdUiZA:-p0eQgW6f4U:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=64P82YdUiZA:-p0eQgW6f4U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=64P82YdUiZA:-p0eQgW6f4U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=64P82YdUiZA:-p0eQgW6f4U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Wed, 24 Feb 2010 03:30:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:3ae7b5c4-e4ee-4143-9a32-0930261fe59b</guid>
      <comments>http://blog.zabiello.com/2010/02/24/rails-3-0-beta#comments</comments>
      <category>rails</category>
      <category>rails3</category>
      <category>bundler</category>
      <category>rvm</category>
      <category>jruby</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/64P82YdUiZA/rails-3-0-beta</link>
    <feedburner:origLink>http://blog.zabiello.com/2010/02/24/rails-3-0-beta</feedburner:origLink></item>
    <item>
      <title>Scala i  bezpieczny "duck typing"</title>
      <description>&lt;p&gt;Duck typing (&lt;a href="http://blog.zabiello.com/2006/05/12/programowa%C4%87-jak-kaczka"&gt;opisywany przeze mnie wcześniej&lt;/a&gt; na przykładzie Pythona) to dosyć użyteczna technika popularna w językach dynamicznie typowanych. W typowym języku statycznie typowanym, takim jak Java, nie da się jej stosować. Ale ograniczeniem nie jest statyczne typowanie, lecz to że Java, &lt;strong&gt;jako język&lt;/strong&gt;, jest po prostu słaba. W statycznie typowanej Scali &amp;#8220;duck typing&amp;#8221; to żaden problem. Mało tego. Fakt, że Scala jest statycznie typowana daje jej tu dodatkową  &lt;em&gt;przewagę&lt;/em&gt; na językami dynamicznie typowanymi.&lt;/p&gt;


	&lt;p&gt;Duck typing w języku dynamicznie typowanym ma pewne wady od których Scala jest wolna. Wpierw przykład dla języka Ruby:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
class Kaczka
  def kwacz
    puts "kwa kwa" 
   end
end   

class Slowik
  def kwacz
    puts "fiu fiu" 
  end
end

class Kot
  def miau
    puts "miau miau" 
  end
end

def kwacz_kaczuszko(k)        
  k.kwacz
end

kwacz_kaczuszko(Kaczka.new) # =&amp;gt; kwa kwa
kwacz_kaczuszko(Slowik.new) # =&amp;gt; fiu fiu
kwacz_kaczuszko(Kot.new) 
# =&amp;gt; NoMethodError: undefined method ‘kwacz’ for #&amp;lt;Kot:0x000001010195d8&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Błędy tego typu są trudne do wyłapania w językach dynamicznie typowanych, bo o ich wystąpieniu można się dowiedzieć dopiero w trakcie działania programu. I jeśli taki fragment kodu jest wykonywany rzadko, to trudno powiedzieć kiedy zostanie wychwycony. Jedynym sposobem aby tak błąd odpowiednio wcześniej wyłapać jest pisanie dodatkowych testów jednostkowych.&lt;/p&gt;


	&lt;p&gt;Co prawda, powyższy kod można co prawda lekko zmodyfikować (bo Ruby pozwala na ładne odpytanie obiektu, czy jest w stanie wywołać daną metodę)&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
def kwacz_kaczuszko(k)        
  if k.respond_to? :kwacz      
    k.kwacz                
  else
    puts "ja nie kwaczę!" 
  end
end

kwacz_kaczuszko(Kot.new) # =&amp;gt; ja nie kwaczę!
&lt;/pre&gt;

	&lt;p&gt;Tylko czy to coś zmienia? Zamiast pisać dodatkową obsługę takiego błędu, nie lepiej go po prostu nie mieć?&lt;/p&gt;


	&lt;p&gt;Scala takie błędy wyłapuje już na etapie kompilacji. Tym samym gwarantuje (statycznie) że do kodu nic takiego się nie prześliznie. Można powiedzieć, że Scala obsługuje &amp;#8220;duck typing&amp;#8221; w sposób bezpieczny, prawidłowy. Odpada pisanie testów jednostkowych i obsługiwanie takich błędów bo w Scali one nigdy się nie pojawią!&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
class Kaczka {
  def kwacz {
    println("kwa kwa")
   }
}

class Slowik {
  def kwacz {
    println("fiu fiu")
   }  
}

class Kot {
  def miaucz {
    println("miau miau")
  }
}                     

def kwacz_kaczuszko(k : {def kwacz}) {
  k.kwacz
}

kwacz_kaczuszko(new Kaczka) 
kwacz_kaczuszko(new Slowik)
kwacz_kaczuszko(new Kot)

/*
(fragment of przyklad.scala):25: error: type mismatch;
 found   : this.Kot
 required: AnyRef{def kwacz: Unit}
kwacz_kaczuszko(new Kot)
                 ^
one error found

!!!
*/
&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=Adm6g9C4NkY:PU4wbuPsRAE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=Adm6g9C4NkY:PU4wbuPsRAE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=Adm6g9C4NkY:PU4wbuPsRAE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=Adm6g9C4NkY:PU4wbuPsRAE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 23 Jan 2010 07:40:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:8559db6f-f544-4114-945f-1da54d88ad1d</guid>
      <comments>http://blog.zabiello.com/2010/01/23/scala-duck-typing#comments</comments>
      <category>scala</category>
      <category>ruby</category>
      <category>duck_typing</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/Adm6g9C4NkY/scala-duck-typing</link>
    <feedburner:origLink>http://blog.zabiello.com/2010/01/23/scala-duck-typing</feedburner:origLink></item>
    <item>
      <title>Uwolnienie potęgi iPhona - jailbreaking</title>
      <description>&lt;p&gt;Tak, jak pewnie większość użytkowników iPhone&amp;#8217;a, mimo że słyszałem od dawna o możliwości zdjęcia apple&amp;#8217;owskich blokad (proces określany jako jailbreaking), to trochę się obawiałem że taka operacja to potencjalne ryzyko zablokowania aparatu lub jakichś innych nieodwracalnych uszkodzeń. Prawda jest taka, że to wszystko to brednie i ploty. Jailbreak jest bardzo łatwy do przeprowadzenia i jest to proces w pełni odwracalny.&lt;/p&gt;


	&lt;p&gt;Jailbreak iPhone&amp;#8217;a wytrąca z ręki krytyków tego urządzenia większość argumentów. Nie wszyscy wiedzą, ale Cydia (jedno z najpopularniejszych zasobów aplikacji na jailbreakowanego iPhone&amp;#8217;a) istniała na długo zanim Apple wpadł na pomysł ze swoim AppStore. Aktualnie istnieje już wiele tego typów repozytoriów aplikacji, wszystkie są integrowane w jeden, szybki system za pomocą pakietu &lt;code&gt;Rock&lt;/code&gt; (o czym niżej).&lt;/p&gt;


	&lt;p&gt;Czy są jakieś wady (lub ograniczenia) związane z  jailbreakiem? Owszem, jest pewna niedogodność. Przed aktualizacją kolejnej wersji systemu operacyjnego iPhone\a (co jest dosyć rzadkim wydarzeniem) należy przywrócić z powrotem oryginalny system, zrobić aktualizację, i dopiero po tym odpalić ponownie jailbreak  (choć przy większych zmianach iPhone OS można się wcześniej upewnić czy jailbreak już jest z nim kompatybilny).&lt;/p&gt;


	&lt;p&gt;Dla pewności,  dobrze zrobić sobie backup iPhone (oczywiście za pomocą ITunes). Gdyby cokolwiek poszło źle można łatwo odzyskać z powrotem poprzednią zawartość iPhone&amp;#8217;a.&lt;/p&gt;


	&lt;p&gt;Jailbreak (przy okazji usuwany jest simlock) przeprowadza się w banalny sposób. Należy podpiąć iPhone kabelkiem &lt;span class="caps"&gt;USB&lt;/span&gt; do komputera i uruchomić program &lt;code&gt;blackra1n&lt;/code&gt; ściągnięty ze strony  &lt;a href="http://www.blackra1n.com"&gt;http://www.blackra1n.com&lt;/a&gt; (program jest dostępny zarówno dla Mac OS-X jak i dla sytemu Windows)&lt;/p&gt;


	&lt;p&gt;&lt;img src="/images/articles/jailbreak1.png" /&gt;&lt;/p&gt;


	&lt;p&gt;Po kliknięciu w  przycisk &amp;#8220;make it ra1n&amp;#8221;, może pojawić się okienko ITunes z informacją że iPhone  został przełączony w tryb recovery. Można je spokojnie zignorować.&lt;/p&gt;


	&lt;p&gt;&lt;img src="/images/articles/jailbreak2.png" /&gt;&lt;/p&gt;


	&lt;p&gt;Po odpaleniu &lt;code&gt;blackra1n&lt;/code&gt; iPhone zostanie przeładowany, a na liście aplikacji pojawi się dodatkowa &lt;code&gt;blackra1n&lt;/code&gt;. Należy ją uruchomić. Z zaproponowanych do instalacji pakietów: Cydia, Rock i sn0w. Należy wybrać &lt;strong&gt;Rock&lt;/strong&gt; (zobacz: &lt;a href="http://www.rockyourphone.com/"&gt;http://www.rockyourphone.com&lt;/a&gt;). Jest dużo szybszy od Cydii i oczywiście wszystkie aplikacje dostępne dla Cydii są też dostępne dla Rock&amp;#8217;a. Poza tym Rock posiada automatyczny system backupu. Wystarczy zarejestrować sobie darmowe konto na serwerze (robi się to z poziomu Rock&amp;#8217;a) i wtedy nie trzeba się przejmować aby robić backup ściągniętych aplikacji. Rock zrobi to automatycznie i automatycznie je przywróci jak trzeba. Do kontrolowania pakietów/aplikacji Rock używa &lt;span class="caps"&gt;APT&lt;/span&gt;,  system podobny do używanego w  Debianie/Ubuntu, lecz wszystko działa w ładnym &lt;span class="caps"&gt;GUI&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Jeśli po jailbreake&amp;#8217;u masz jakieś problemy z działaniem Wifi, należy zrestartować w iPhonie ustawienia sieciowe (Ustawienia -&amp;gt; Ogólne -&amp;gt; Wyzeruj -&amp;gt; Wyzeruj ustawienia sieciowe) Ja musiałem to zrobić dwa razy. Od tego momentu już więcej nie było problemów.&lt;/p&gt;


	&lt;p&gt;Co warto sobie zainstalować na początek?&lt;/p&gt;


	&lt;p&gt;Na pewno warto zacząć od &lt;a href="http://simblog.pl/sbsettings-centrum-dowodzenia-w-iphonie/"&gt;SBSettings&lt;/a&gt; (oczywiście wszystko się instaluje za pomocą aplikacji Rock). SBSettings to b. wygodna aplikacja, pozwala ubijać inne aplikacje, wyświetla ilość dostępnego &lt;span class="caps"&gt;RAM&lt;/span&gt;&amp;#8217;u, pozwala czyścić &lt;span class="caps"&gt;RAM&lt;/span&gt;, chować ikony innych aplikacji itp.&lt;/p&gt;


	&lt;p&gt;Drugą aplikacją &amp;#8220;must have&amp;#8221; to &lt;a href="http://code.google.com/p/iphone-backgrounder/wiki/Documentation"&gt;Backgrounder&lt;/a&gt;  &amp;#8211; służy do odpalania dowolnej innej aplikacji w tle.&lt;/p&gt;


	&lt;p&gt;Trzecią to &lt;a href="http://www.topiphoneresource.info/organize-your-iphone-apps-with-categories-jailbreak-app/"&gt;Categories&lt;/a&gt; pozwalająca na grupowanie ikon programów w foldery. Dużo wygodniej niż stary bałagan, zwłaszcza jak się ma dużo aplikacji.&lt;/p&gt;


	&lt;p&gt;Do łatwiejszej lokalizacji aplikacji (bo są w katalogach o mało czytelnych nazwach) dobrze doinstalować sobie Prostą aplikację &lt;code&gt;AppLinks&lt;/code&gt; (w &lt;code&gt;/var/mobile/AppLinks&lt;/code&gt; stworzy czytelne linki symboliczne do wszystkich aplikacji).&lt;/p&gt;


	&lt;p&gt;Co dalej? No, zależy co kto potrzebuje. Ja zainstalowałem sobie  Pythona, Ruby, Haskella, Javę (kompaktowa &lt;a href="http://jamvm.sourceforge.net/"&gt;JamVM&lt;/a&gt;), Scalę, Clojure, Vim&amp;#8217;a, Midnight Commandera, wget, lynx, git, svn oraz oczywiście serwer OpenSSH. Dzięki temu ostatniemu mogę połączyć się z iPhonem za pomocą &lt;span class="caps"&gt;SSH&lt;/span&gt; (dla tych co nie wiedzą, domyślne hasło root&amp;#8217;a w iPhonie to &amp;#8220;alpine&amp;#8221;). Dzięki &lt;span class="caps"&gt;SSH&lt;/span&gt; można łatwo modyfikować dowolne pliki i aplikacje. Przeszkadzają komuś reklamy w jakimś programie? :) Najczęściej wystarczy tylko prosta edycja pliku javascriptowego. Poza tym za pomocą &lt;span class="caps"&gt;SFTP&lt;/span&gt; można przerzucać dowolne programy i pliki z pominięciem iTunes. Jest nawet program &lt;a href="http://iphoneblloger.blogspot.com/2009/03/installous.html"&gt;Installous&lt;/a&gt; specjalnie do instalowania aplikacji bez pośrednictwa ITunes.&lt;/p&gt;


&lt;pre&gt;
$ ruby -v
ruby 1.8.6 (2007-09-24 patchlevel 111) [arm-darwin9]

$ python    
Python 2.5.1 (r251:54863, xx/xx/xx, xx:xx:xx) 
[GCC 4.2.1 (Based on Apple Inc. build 5555)] on darwin

$ java -version
java version "1.5.0" 
JamVM version 1.5.1
Copyright (C) 2003-2008 Robert Lougher &amp;lt;rob@lougher.org.uk&amp;gt;
...
Execution Engine: direct-threaded interpreter with stack-caching
Compiled with: gcc 4.2.1 (Based on Apple Inc. build 5555)

Boot Library Path: /usr/lib/classpath
Boot Class Path: /usr/share/jamvm/classes.zip:/usr/share/classpath/glibj.zip
&lt;/pre&gt;

	&lt;p&gt;Python zainstalował mi się w wersji 2.5. Za pomocą setuptools doinstalowałem ipythona, django, pylons, sqlalchemy, mako. Odpaliłem prosty projekt w Django. Działa bez problemu. Ruby instaluje się w wersji 1.8.6 ale ma starsze RubyGems 1.3.2. Ściągnąłem zatem z sieci najnowsze i bez problemu doinstalowały się: Rails, Merb i Sinatra. Niestety jako serwer działa tylko Webrick. Thin i Mongrel się nie skompilowały, ale to dlatego że nie miałem programu make.&lt;/p&gt;


	&lt;p&gt;Powodzenia w hackowaniu. Teraz to iPhone naprawdę Rocks ;)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=SVeYUF6Weh0:I9XTQnubBQ0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=SVeYUF6Weh0:I9XTQnubBQ0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=SVeYUF6Weh0:I9XTQnubBQ0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=SVeYUF6Weh0:I9XTQnubBQ0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 17 Jan 2010 03:58:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:c1eef2cf-b136-4ee5-8fc7-96797471cb68</guid>
      <comments>http://blog.zabiello.com/2010/01/17/iphone-jailbreak#comments</comments>
      <category>iphone</category>
      <category>jailbreak</category>
      <category>apple</category>
      <category>cydia</category>
      <category>rock</category>
      <category>osx</category>
      <category>python</category>
      <category>ruby</category>
      <category>django</category>
      <category>pylons</category>
      <category>rails</category>
      <category>merb</category>
      <category>sinatra</category>
      <category>hacking</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/SVeYUF6Weh0/iphone-jailbreak</link>
    <feedburner:origLink>http://blog.zabiello.com/2010/01/17/iphone-jailbreak</feedburner:origLink></item>
    <item>
      <title>Spotkanie entuzjastów Scali z okolic Wrocławia</title>
      <description>&lt;p&gt;W najbliższy wtorek (19 stycznia 2010) odbędzie się pierwsze spotkanie &lt;a href="http://groups.google.pl/group/wroclaw-scala-enthusiasts"&gt;WrASSE&lt;/a&gt; (grupy entuzjastów &lt;a href="http://scala-lang.org"&gt;Scali&lt;/a&gt; z okolic Wrocławia) pt. &amp;#8220;Scala w projekcie komercyjnym&amp;#8221;. Szczegóły: &lt;a href="http://jdn.pl/node/1917"&gt;tutaj&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=dg6Vzs1Y4OA:r0UQKCzddSM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=dg6Vzs1Y4OA:r0UQKCzddSM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=dg6Vzs1Y4OA:r0UQKCzddSM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=dg6Vzs1Y4OA:r0UQKCzddSM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 15 Jan 2010 02:37:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:af21fc59-004f-4545-8b0a-581586f59afc</guid>
      <comments>http://blog.zabiello.com/2010/01/15/spotkanie-entuzjastow-scali-z-okolic-wroc%C5%82awia#comments</comments>
      <category>scala</category>
      <category>wrocław</category>
      <category>meeting</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/dg6Vzs1Y4OA/spotkanie-entuzjastow-scali-z-okolic-wroc%C5%82awia</link>
    <feedburner:origLink>http://blog.zabiello.com/2010/01/15/spotkanie-entuzjastow-scali-z-okolic-wroc%C5%82awia</feedburner:origLink></item>
    <item>
      <title>IPLA i odbieranie live TV spoza Polski</title>
      <description>&lt;p&gt;Osoby mieszkające poza Polską, nawet jeśli mają wykupiony abonament na odbiór strumieniowych kanałów telewizji Polsat, mogą poczuć się oszukani, że transmisje na żywo z co ciekawszych wydarzeń są dla nich niedostępne. Poniżej podaję prosty sposób jak to obejść i  ośmieszyć takie &amp;#8220;polsatowe&amp;#8221; blokady. Sposób jest jak najbardziej legalny i nie wymaga nigdzie żadnego włamywania się, ani hackowania programu &lt;span class="caps"&gt;IPLA&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Należy ściągnąć program &lt;span class="caps"&gt;IPLA&lt;/span&gt; ze strony &lt;a href="http://www.ipla.pl/"&gt;http://ipla.pl&lt;/a&gt;. Ale uwaga, musi to być wersja dla systemu Windows bo wersja Lite dostępna dla Mac OS-X lub Linuksa się nie nadaje. Nie ma opcji logowania niezbędnej do użycia konta &lt;span class="caps"&gt;VIP&lt;/span&gt; bez którego nie można korzystać z transmisji na żywo. Użytkownicy Mac OS-X (lub Linuksa) mogą skorzystać z dowolnego emulatora Windowsów, np. &lt;a href="http://www.vmware.com/"&gt;VMWare&lt;/a&gt;, &lt;a href="http://www.parallels.com/"&gt;Parallers&lt;/a&gt; lub darmowego &lt;a href="http://www.virtualbox.org/"&gt;VirtualBoxa&lt;/a&gt;. Dla OS-X używam najlepszego moim zdaniem, &lt;a href="http://www.vmware.com/products/fusion/"&gt;VMWare Fusion&lt;/a&gt;. (Nie sprawdzałem czy można odpalić &lt;span class="caps"&gt;IPL&lt;/span&gt;Ę przez Wine lub &lt;a href="http://www.codeweavers.com/products/"&gt;CrossOver&lt;/a&gt;, czyli programy pozwalające uruchamiać aplikacje windowsowe bez zainstalowanego systemu Windows. Jeśli tak, to odpada posiadanie samych Windowsów). Zakładam dalej, że używamy do tego celu Windows (bezpośrednio, lub spod emulatora).&lt;/p&gt;


	&lt;p&gt;Transmisje na żywo są dostępne tylko dla użytkowników posiadających konto &lt;span class="caps"&gt;VIP&lt;/span&gt;. Trzeba się &lt;a href="https://getmedia.redefine.pl/signup2/"&gt;zarejestrować&lt;/a&gt; i wykupić jakiś abonament. Najtańszy, 30-dniowy kosztuje 14 zł.&lt;/p&gt;


	&lt;p&gt;Potrzebne będzie jakieś konto shellowe na polskim serwerze oraz program do obługi &lt;span class="caps"&gt;SSH&lt;/span&gt;, np. &lt;a href="http://pl.wikipedia.org/wiki/PuTTY"&gt;Putty &lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/a&gt;. Ważne aby takie serwer stał w Polsce a nie za granicą.&lt;/p&gt;


	&lt;p&gt;Aby sobie ułatwić ustawianie proxy, najwygodniej pobrać program &lt;a href="http://www.proxifier.com/"&gt;Proxifier&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;1. Zestawiamy tunelowanie &lt;span class="caps"&gt;SSH&lt;/span&gt; do polskiego serwera. Można to sobie ustawić w Putty &lt;span class="caps"&gt;SSH&lt;/span&gt; albo uruchomić w konsoli  komendę:&lt;/p&gt;


&lt;pre&gt;
putty.ssh  -D 127.0.0.1:1044 login@jakis.server.pl
&lt;/pre&gt;

	&lt;p&gt;Po podaniu hasła i zalogowaniu, mamy zestawiony tunel między lokalnym komputerem na porcie 1044 z zdalnym &amp;#8220;jakis.server.pl&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;2. Należy odpalić Proxyfier, wejśc do menu -&amp;gt; Options -&amp;gt; Proxy Settings i ustawić&lt;/p&gt;


&lt;pre&gt;
address: 127.0.0.1
port 1044
socks: 5
&lt;/pre&gt;

	&lt;p&gt;&lt;img src="/images/articles/proxy.png" /&gt;&lt;/p&gt;


	&lt;p&gt;3. Odpalamy program &lt;span class="caps"&gt;IPA&lt;/span&gt; i logujemy się do swojego konta &lt;span class="caps"&gt;VIP&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="/images/articles/ipla.png" /&gt;&lt;/p&gt;


	&lt;p&gt;To wszystko. Dla Polsatu będziemy widziani jako użytkownik łączący się z Polski. Można oglądać wszelkie transmisje Live.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=XJbf4cz-J2A:PFUzFGT4sy8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=XJbf4cz-J2A:PFUzFGT4sy8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=XJbf4cz-J2A:PFUzFGT4sy8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=XJbf4cz-J2A:PFUzFGT4sy8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 12 Dec 2009 14:58:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:eb9470ed-1bd3-4631-8b89-0a55e9d06f96</guid>
      <comments>http://blog.zabiello.com/2009/12/12/ipla-spoza-polski#comments</comments>
      <category>polsat</category>
      <category>wideo</category>
      <category>vod</category>
      <category>streaming</category>
      <category>hacking</category>
      <category>tips</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/XJbf4cz-J2A/ipla-spoza-polski</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/12/12/ipla-spoza-polski</feedburner:origLink></item>
    <item>
      <title>MagLev - pierwsza wersja publiczna</title>
      <description>&lt;p&gt;Gdy ok 1.5 roku pisałem o &lt;a href="http://blog.zabiello.com/2008/06/14/maglev"&gt;szumie i nadziejach związanych z MagLev&amp;#8217;em&lt;/a&gt;, trudno było przewidzieć ile czasu zajmie dostosowanie wirtualnej maszyny Smalltalka do pracy z kodem bajtowym Ruby&amp;#8217;ego. Dziś (właściwie to jakieś 2 godziny temu) &lt;a href="http://groups.google.com/group/maglev-discussion/browse_thread/thread/1102993e9e21492a"&gt;oficjalnie ogłoszono&lt;/a&gt; ż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&amp;#8217;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 &lt;span class="caps"&gt;ORM&lt;/span&gt;&amp;#8217;ach i &lt;span class="caps"&gt;RDBMS&lt;/span&gt;? (technologia baz relacyjnych pochodzi z lat 70-tych, jest wolna i przestarzała).&lt;/p&gt;


	&lt;p&gt;Ruby everywhere &amp;#8211; czyli najważniejsze implementacje Ruby&amp;#8217;ego:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Ruby 1.8 &lt;span class="caps"&gt;MRI&lt;/span&gt; &amp;#8211; implementacja w języku C (najstarsza)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.rubyenterpriseedition.com/"&gt;Ruby Enterprise Edition&lt;/a&gt; &amp;#8211; implementacja w C, mniejsze zużycie pamięci, używana głównie z &lt;a href="http://www.modrails.com/"&gt;Passengerem&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Ruby 1.9 &amp;#8211; implementacja w języku C, używa wirtualnej maszyny &lt;span class="caps"&gt;YARV&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://jruby.org/"&gt;JRuby&lt;/a&gt; &amp;#8211; implementacja w języku Java, wirtualna maszyna Javy (JVM)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://ironruby.net/"&gt;IronRuby&lt;/a&gt; &amp;#8211; implementacja w języku C# (środowisko .NET) &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://maglev.gemstone.com/"&gt;Maglev&lt;/a&gt; &amp;#8211; implementacja w języku &lt;a href="http://www.smalltalk.org/main/"&gt;Smalltalk&lt;/a&gt;, wirtualna maszyna Smalltalka (&lt;a href="http://www.gemstone.com/"&gt;Gemstone&lt;/a&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.macruby.org/"&gt;MacRuby&lt;/a&gt; &amp;#8211; implementacja w języku Objective-C dla systemu Mac OS-X&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt; &amp;#8211; implementacja Ruby w&amp;#8230; Ruby (z loaderem w C++)&lt;/li&gt;
		&lt;li&gt;&lt;a href="https://wiki.sdn.sap.com/wiki/display/Research/BlueRuby"&gt;BlueRuby&lt;/a&gt; &amp;#8211; Ruby działający w &lt;span class="caps"&gt;SAP&lt;/span&gt; Web Application Server (ABAP Virtual Machine)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Zobacz też &lt;a href="http://www.igvita.com/2009/11/20/state-of-ruby-vms-ruby-renaissance"&gt;State of Ruby VMs: Ruby Renaissance&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=Vh8AwbIjW3A:1fvaukeVpV4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=Vh8AwbIjW3A:1fvaukeVpV4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=Vh8AwbIjW3A:1fvaukeVpV4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=Vh8AwbIjW3A:1fvaukeVpV4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 21 Nov 2009 04:43:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:04ee2cd6-af93-4c99-bba7-c258784041e3</guid>
      <comments>http://blog.zabiello.com/2009/11/21/maglev-pierwsza-wersja-publiczna#comments</comments>
      <category>jruby</category>
      <category>maglev</category>
      <category>smalltalk</category>
      <category>ruby</category>
      <category>gemstone</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/Vh8AwbIjW3A/maglev-pierwsza-wersja-publiczna</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/11/21/maglev-pierwsza-wersja-publiczna</feedburner:origLink></item>
    <item>
      <title>Scala w Trójmieście</title>
      <description>&lt;p&gt;19 listopada 2009 w auli Uniwersytetu Gdańskiego odbędzie się spotkanie poświęcone językowi &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. Organizuje je &lt;a href="http://it.wtrojmiescie.org/about/grupy-trojmiasto-java-user-group"&gt;Trójmiasto Java User Group&lt;/a&gt;. Szczegóły tutaj: &lt;a href="http://it.wtrojmiescie.org/spotkania/scala"&gt;http://it.wtrojmiescie.org/spotkania/scala&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=tWj8tcbEf_4:KSduWuSYoxM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=tWj8tcbEf_4:KSduWuSYoxM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=tWj8tcbEf_4:KSduWuSYoxM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=tWj8tcbEf_4:KSduWuSYoxM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 09 Nov 2009 21:29:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:2eaa0a68-c72b-4ae0-9409-184d552dfcfa</guid>
      <comments>http://blog.zabiello.com/2009/11/09/scala-w-trojmiescie#comments</comments>
      <category>scala</category>
      <category>trójmiasto</category>
      <category>java</category>
      <category>news</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/tWj8tcbEf_4/scala-w-trojmiescie</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/11/09/scala-w-trojmiescie</feedburner:origLink></item>
    <item>
      <title>RubyMine - najlepszy IDE dla Ruby i Rails</title>
      <description>&lt;p&gt;Mimo, że spora część programistów Ruby&amp;#8217;ego i Rails pozostaje wierna edytorom tekstowym takim jak TextMate, Emacs, Vim czy (&lt;a href="http://blog.zabiello.com/2007/01/30/jedit-for_rails"&gt;opisywany&lt;/a&gt; dwa lata temu) JEdit, druga część woli &lt;span class="caps"&gt;IDE&lt;/span&gt; ze względu na rozbudowany lepszy refactoring, wbudowany (graficzny) debugger, podpowiedzi i analiza składni kodu Ruby&amp;#8217;ego w czasie rzeczywistym. Z różnych &lt;span class="caps"&gt;IDE&lt;/span&gt; do Rails to tak naprawdę liczą się tylko trzy.&lt;/p&gt;


	&lt;p&gt;Jednym z pierwszych &lt;span class="caps"&gt;IDE&lt;/span&gt; do Rails był (oparty na Eclipse) &lt;strong&gt;RadRails&lt;/strong&gt;, który później został wchłonięty przez Aptanę i jest rozprowadzany jako &lt;a href="http://aptana.com/"&gt;Aptana RadRails&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Znacznie lepszą od Aptany analizę kodu Ruby&amp;#8217;ego w czasie rzeczywistym posiada &lt;a href="http://www.netbeans.org/features/ruby/index.html"&gt;&lt;strong&gt;Netbeans&lt;/strong&gt;&lt;/a&gt; który, będąc produktem darmowym i obsługującym wiele języków (Ruby, Python, &lt;span class="caps"&gt;PHP&lt;/span&gt;, Scala, Java itp) do dziś ma wielu zwolenników.&lt;/p&gt;


	&lt;p&gt;Od jakiegoś czasu mam przyjemność pracować z produktem &lt;a href="http://www.jetbrains.com/ruby/index.html"&gt;&lt;strong&gt;RubyMine&lt;/strong&gt;&lt;/a&gt; i muszę przyznać, że jest jeszcze lepszy od Netbeans (którego rozwój jakby ostatnio coś zwolnił).  Aktualnie wyszła &lt;a href="http://www.jetbrains.com/ruby/nextversion/index.html"&gt;wersja 2.0beta&lt;/a&gt; która ma sporo dodanych ulepszeń, wspiera podpowiedzi do Cucumber, RSpec, Haml, i18n czy Ruby 1.9. Działa faktycznie szybko i przyjemnie (zobacz np. jak elegancko rozwiązano &lt;a href="http://ruby.dzone.com/articles/navigation-inside-rubymine"&gt;nawigację po kodzie&lt;/a&gt;). Mimo, że RubyMine to aplikacja płatna, to zdecydowanie jest warta swej ceny (przed wyjściem wersji finalnej 2.0 dostępna jest zniżka 20%)&lt;/p&gt;


	&lt;p&gt;Jeśli ktoś chce używać nie tylko Ruby, ale także Scali i innych języków, dostępny jest potężny &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ &lt;span class="caps"&gt;IDEA&lt;/span&gt;&lt;/a&gt;  (RubyMine jest tam dostępny w formie pluginu).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=qTQW6rRVzlo:5nYWZ3LyPcg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=qTQW6rRVzlo:5nYWZ3LyPcg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=qTQW6rRVzlo:5nYWZ3LyPcg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=qTQW6rRVzlo:5nYWZ3LyPcg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 13 Oct 2009 00:13:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a24a76b7-2576-48f1-b615-9f455f449e67</guid>
      <comments>http://blog.zabiello.com/2009/10/13/rubymine#comments</comments>
      <category>ruby</category>
      <category>jruby</category>
      <category>rails</category>
      <category>rubymine</category>
      <category>netbeans</category>
      <category>edytor</category>
      <category>radrails</category>
      <category>scala</category>
      <category>intellij</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/qTQW6rRVzlo/rubymine</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/10/13/rubymine</feedburner:origLink></item>
    <item>
      <title>Rails dopalony Sinatrą</title>
      <description>&lt;p&gt;Dostępne w Rails 2.x kontrolery rackowe (tzw. &lt;a href="http://guides.rubyonrails.org/rails_on_rack.html#rails-metal-applications"&gt;metal applications&lt;/a&gt;) wprowadzono aby maksymalnie przyśpieszyć działanie Rails (pomijają prawie cały stos wywołań frameworka). Ich wadą jest trochę niewygodna, niskopoziomowa składnia. Z drugiej strony, dzięki &lt;a href="http://guides.rubyonrails.org/rails_on_rack.html#introduction-to-rack"&gt;Rackowi&lt;/a&gt;, istnieje kilka bardzo szybkich mikroframeworków, z których najbardziej znany to &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; i &lt;a href="http://ramaze.net/"&gt;Ramaze&lt;/a&gt;. Dzięki możliwości wpięcia ich do Rails, uzyskuje się połączenie dużej szybkości z wygodniejszą składnią.&lt;/p&gt;


	&lt;p&gt;Klasyczny kontroler rackowy, stworzony za pomocą generatora kodu&lt;/p&gt;


&lt;pre class="brush:bash"&gt;  
$ script/generate metal hello
&lt;/pre&gt;

	&lt;p&gt;wygląda tak:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;  
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class Hello
  def self.call(env)
    if env["PATH_INFO"] =~ /^\/hello/
      [200, {"Content-Type" =&amp;gt; "text/html"}, ["Hello World!"]]
    else
      [404, {"Content-Type" =&amp;gt; "text/html"}, ["Not Found"]]
    end
  end
end
&lt;/pre&gt;

	&lt;p&gt;Po zastąpieniu go Sinatrą, kod staje się bardziej znośny:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;  
require 'sinatra/base'
class Hello &amp;lt; Sinatra::Base
  get '/hello' do
    "Hello World!" 
  end
end
&lt;/pre&gt;

	&lt;p&gt;Wydajnościowo (na MacBook Pro 2.16GHz Core2 Duo, Ruby 1.9.1 i Thin 1.2.4 i dla &lt;code&gt;ab -n 10000 -c 10&lt;/code&gt;) różnice wyglądają następująco:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;czysty metal: 2054 req/s&lt;/li&gt;
		&lt;li&gt;metal z Sinatrą: 1335 req/s&lt;/li&gt;
		&lt;li&gt;klasyczny kongtroler: 456 req/s&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Co prawda, wciąż czysty kontroler rackowy jest najszybszy, ale zastąpienie go Sinatrą i tak jest dużo szybsze od normalnego kontrolera Rails. Poza tym uzyskujemy uproszczenie kodu (może na podanym, trywialnym przykładzie nie jest to spektakularne, ale &lt;a href="http://www.slideshare.net/adamwiggins/rails-metal-rack-and-sinatra"&gt;przy bardziej złożonym&lt;/a&gt; zalety takiego rozwiązania stają się bardziej oczywiste)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=3waccgt8ROA:j0GLoLLtK50:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=3waccgt8ROA:j0GLoLLtK50:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=3waccgt8ROA:j0GLoLLtK50:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=3waccgt8ROA:j0GLoLLtK50:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 13 Oct 2009 00:11:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a52b891a-893c-44cd-b213-480ce710ec11</guid>
      <comments>http://blog.zabiello.com/2009/10/13/rails-rack-sinatra#comments</comments>
      <category>rails</category>
      <category>sinatra</category>
      <category>ruby</category>
      <category>rack</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/3waccgt8ROA/rails-rack-sinatra</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/10/13/rails-rack-sinatra</feedburner:origLink></item>
    <item>
      <title>Aplikacja multiplatformowa za pomocą cross-kompilatora</title>
      <description>&lt;p&gt;Od jakiegoś czasu interesuje mnie możliwość pisania aplikacji działających na różnych systemach operacyjnych. Rozwiązaniem najbardziej oczywistym jest oczywiście użycie Javy (może niekoniecznie samego języka jako takiego, ale na pewno platformy). Rozwiązaniem znacznie mniej znanym, ale ciekawym, jest użycie produktu firmy Real Software &amp;#8211; &lt;a href="http://www.realsoftware.com/realbasic/"&gt;RealBasic&amp;#8217;a&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;RealBasic to prosty język obiektowy (podobny do Visual Basica). RealBasic to jednak nie tylko język, to także ciekawe zintegowane środowisko programistyczne (IDE). Jest ciekawe, bo posiada &lt;strong&gt;wbudowany &lt;a href="http://pl.wikipedia.org/wiki/Cross-kompilator"&gt;cross-kompilator&lt;/a&gt;&lt;/strong&gt; &amp;#8211; z jednej aplikacji można automatycznie wygenerować &lt;strong&gt;kod binarny&lt;/strong&gt; dla trzech głównych platform: Mac OS-X, Linux i Windows. W przeciwieństwie do Javy nie ma tu żadnej wirtualnej maszyny. Kod wynikowy jest kodem binarnym dla danej platformy. Jedno kliknięcie i trzy wersje programu gotowe. Oczywiście &lt;span class="caps"&gt;IDE&lt;/span&gt; można uruchomić także na każdej z trzech w/w platform. Twórcy RealBasica podkreślają pewną &lt;a href="http://www.realsoftware.com/realbasic/javadevelopers.php"&gt;przewagę takiego rozwiązania&lt;/a&gt; nad Javą.&lt;/p&gt;


	&lt;p&gt;Sam edytor jest ładny i intuicyjny w obsłudze (przypomina trochę Delphi). Dokumentacja jest dobra i przejrzysta. Standardowo obsługiwane są bazy danych takie jak PostgreSQL, MySQL a także oparty na SQLite &amp;#8211; &lt;a href="http://www.realsoftware.com/realsqlserver/"&gt;RealServer&lt;/a&gt;. Wszystkie bazy korzystają z identycznego &lt;span class="caps"&gt;API&lt;/span&gt;, więc można je łatwo zmienić bez większych zmian w kodzie źródłowym aplikacji.&lt;/p&gt;


	&lt;p&gt;Niestety, nie jest to rozwiązanie open-source, ale płatne (z wyjątkiem wersji Personal Edition for Linux która &lt;a href="http://www.realsoftware.com/store/opensource"&gt;jest darmowa do projektów open-source&lt;/a&gt;). Lecz mimo to, jeśli ktoś chce prosto i szybko zmontować aplikację która natywnie będzie pracować pod kilkoma głównymi platformami, to może to być kusząca perspektywa. Tym bardziej, że całość jest po prostu łatwa w obsłudze.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://blog.zabiello.com/images/articles/realbasic.png" /&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=po11XzN5r9M:y2qwu9vKXUo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=po11XzN5r9M:y2qwu9vKXUo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=po11XzN5r9M:y2qwu9vKXUo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=po11XzN5r9M:y2qwu9vKXUo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Thu, 10 Sep 2009 02:00:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:5a908b41-b63f-43ce-9a4d-c01cc7a6706c</guid>
      <comments>http://blog.zabiello.com/2009/09/10/realbasic#comments</comments>
      <category>apple</category>
      <category>osx</category>
      <category>windows</category>
      <category>linux</category>
      <category>realbasic</category>
      <category>multiplatform</category>
      <category>crosscompiler</category>
      <category>IDE</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/po11XzN5r9M/realbasic</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/09/10/realbasic</feedburner:origLink></item>
    <item>
      <title>Problem znaków UTF-8 w Scali i Javie pod Mac OS-X</title>
      <description>&lt;p&gt;Wczoraj, na polskim kanale &lt;span class="caps"&gt;IRC&lt;/span&gt; &lt;a href="irc://irc.eu.freenode.net/scala.pl"&gt;#scala.pl&lt;/a&gt; mieliśmy małą dyskusję na temat złego wyświetlania polskich znaków w Scali pod systemem Mac OS-X Leopard (pod Linuksem jest OK). Co dziwne, mimo, że zmienna środowiska &lt;code&gt;LANG&lt;/code&gt; pokazuje wartość &lt;code&gt;pl_PL.UTF-8&lt;/code&gt;, próby wyświetlenia polskich napisów &lt;strong&gt;nie działają&lt;/strong&gt;. Więcej, w konsoli Scali w ogóle nie ma możliwości wprowadzenia polskich znaków, ani bezpośrednio z klawiatury, ani poprzez wklejenie ze schowka. Wszystkie polskie ogonki zamieniane są na znak zapytania.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;     
println(java.nio.charset.Charset.defaultCharset) 
// x-MacCentralEurope

println("Zażółć gęślą jaźń")
// Za???? g??l? ja??
&lt;/pre&gt;

	&lt;p&gt;Jak podaje &lt;a href="http://developer.apple.com/mac/library/documentation/Java/Conceptual/Java14Development/04-JavaUIToolkits/JavaUIToolkits.html"&gt;Mac Dev Center&lt;/a&gt; domyślnym kodowaniem znaków w Javie pod systemem Mac OS-X jest&amp;#8230; &lt;code&gt;MacRoman&lt;/code&gt;. (Tak jest oczywiśie tylko w wypadku angielskiego interfejsu. Po przełączeniu na polski, domyślnym kodowaniem znaków pod Javą staje się &lt;code&gt;x-MacCentralEurope&lt;/code&gt;).&lt;/p&gt;


	&lt;p&gt;Najgorsze, że nie pomaga, pozornie oczywiste, użycie javowego &lt;span class="caps"&gt;API&lt;/span&gt; zmieniające własność &lt;code&gt;file.encoding&lt;/code&gt;.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;     
System.setProperty("file.encoding", "UTF8")
println(java.nio.charset.Charset.defaultCharset) 
// x-MacCentralEurope 
&lt;/pre&gt;

	&lt;p&gt;Dla sprawdzenie, czy problem ten dotyczy tylko Scali, skompilowałem testowy kod Scali do Javy i uruchomiłem go z jej poziomu.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;     
// plik Znaki.scala
object Znaki extends Application {
  println(java.nio.charset.Charset.defaultCharset) 
  println("Zażółć gęślą jaźń")
  System.setProperty("file.encoding", "UTF8")
  println(java.nio.charset.Charset.defaultCharset) 
  val s = "Zażółć gęślą jaźń" 
  println(new String (s.getBytes(), "UTF-8"))    
}
&lt;/pre&gt;

&lt;pre class="bash"&gt;
$ scalac Znaki.scala
$ java -cp $SCALA_HOME/lib/scala-library.jar:. Znaki

x-MacCentralEurope
Za???? g??l? ja??
x-MacCentralEurope
Za? g??l? ja??
&lt;/pre&gt;                   

	&lt;p&gt;Po obejrzeniu pliku java/nio/charset/Charset.java wydawałby się że można problem rozwiązać za pomocą refleksji.&lt;/p&gt;


&lt;pre class="brush:java"&gt;                                              
// plik java/nio/charset/Charset.java

private static volatile Charset defaultCharset;

public static Charset defaultCharset() {
    if (defaultCharset == null) {
        synchronized (Charset.class) {
            java.security.PrivilegedAction pa =
                new GetPropertyAction("file.encoding");
            String csn = (String)AccessController.doPrivileged(pa);
            Charset cs = lookup(csn);
            if (cs != null)
                defaultCharset = cs;
            else 
                defaultCharset = forName("UTF-8");
        }
    }
    return defaultCharset;
}
&lt;/pre&gt;

	&lt;p&gt;Niestety, mimo że za pomocą refleksji można zmienić wartość &lt;code&gt;defaultCharset&lt;/code&gt;, nadal to nie rozwiązuje poprawnego wyświetlania polskich znaków.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
import java.nio.charset._

println(Charset.defaultCharset) 
// x-MacCentralEurope 

val f = classOf[Charset].getDeclaredField("defaultCharset")
f.setAccessible(true)
// f.set(null, null)
// System.setProperty( "file.encoding", "utf-8")
// lub krócej:
f.set(null, Charset.forName("utf-8"))

println(Charset.defaultCharset) 
// UTF-8

println("Zażółć gęślą jaźń")
// Za???? g??l? ja?? 
&lt;/pre&gt;

	&lt;p&gt;Okazuje się, że jedynym, skutecznym i zarazem prostym &lt;strong&gt;rozwiązaniem&lt;/strong&gt; tego problemu jest dodanie flagi  &lt;code&gt;-Dfile-encoding=utf8&lt;/code&gt; do wywolania kodu Javy.&lt;/p&gt;


&lt;pre class="bash"&gt;
$ java -Dfile.encoding=utf8 -cp $SCALA_HOME/lib/scala-library.jar:. Znaki
UTF-8
Zażółć gęślą jaźń
UTF-8
Zażółć gęślą jaźń
&lt;/pre&gt;

	&lt;p&gt;W wypadku Scali, powyższą flagę dodajemy do skryptu shellowego &lt;code&gt;scala&lt;/code&gt;. Przy okazji naprawi się wpisywanie i wyświetlanie polskich znaków w interaktywnej konsoli Scali.&lt;/p&gt;


	&lt;p&gt;Oczywiście powyższy problem ze znakami &lt;span class="caps"&gt;UTF&lt;/span&gt;-8 ostatecznie nie ma ze Scalą nic wspólnego. To wina takiego, a nie innego, zachowania się Javy w Mac OS-X. Scala &amp;#8220;z rozpędu&amp;#8221; ten problem tylko &amp;#8220;odziedziczyła&amp;#8221;, gdyż działa na bazie &lt;span class="caps"&gt;JVM&lt;/span&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=kJ0Kfz4OZhs:F6RdFL8Zkbw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=kJ0Kfz4OZhs:F6RdFL8Zkbw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=kJ0Kfz4OZhs:F6RdFL8Zkbw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=kJ0Kfz4OZhs:F6RdFL8Zkbw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 08 Sep 2009 03:15:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:939f4558-55c5-47c3-854e-c5826d6dd02a</guid>
      <comments>http://blog.zabiello.com/2009/09/08/osx-utf8-java-scala#comments</comments>
      <category>scala</category>
      <category>java</category>
      <category>encoding</category>
      <category>apple</category>
      <category>osx</category>
      <category>leopard</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/kJ0Kfz4OZhs/osx-utf8-java-scala</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/09/08/osx-utf8-java-scala</feedburner:origLink></item>
    <item>
      <title>Czy Apple jest droższy od PC?</title>
      <description>&lt;p&gt;Czy spotkałeś się z obiegową opinią że komputery Apple&amp;#8217;a są dużo droższe od analogicznych odpowiedników z segmentu PC? Jeśli tak, to przeczytaj i pokaż ten tekst tym co takie brednie rozpowszechniają. Napisałem go, aby odsyłać do niego niedowiarków, bo już znudziło mi się &lt;a href="http://webhosting.pl/Laboratorium.DailyTECH.pl.MacBook.Pro.15.Unibody"&gt;prostowanie bzdur&lt;/a&gt; wypisywanych na ten temat.&lt;/p&gt;


	&lt;p&gt;W zasadzie nie jest łatwo znaleźć odpowiednik PC dla takiego laptopa MacBook Pro. Ale aby porównanie cen miało jakikolwiek sens, postawiłem zestawić maksymalnie podobny sprzętowo laptop w ramach tego samego kraju. Ze strony Appl&amp;#8217;e wybrałem laptopa MacBook Pro i desktopowego MacPro&amp;#8230;&lt;/p&gt;


	&lt;h3&gt;MacBook Pro (http://apple.ie) vs &lt;span class="caps"&gt;DELL&lt;/span&gt; Precision &lt;span class="caps"&gt;M4440&lt;/span&gt; (http://dell.ie)&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;Procesor: Core2Duo 2.66GHz, 6MB L2 Cache, 1066MHz&lt;/li&gt;
		&lt;li&gt;Pamięć: 4GB 800Hz &lt;span class="caps"&gt;DDR2&lt;/span&gt; (niestety, nie było opcji wybrania pamięci &lt;span class="caps"&gt;DDR3 1066&lt;/span&gt;, co jest dziwne, gdyż ten procesor pracuje z 1066MHz, idealnie dla takich pamięci)&lt;/li&gt;
		&lt;li&gt;OS: English Windows Vista Ultimate &lt;span class="caps"&gt;SP1&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Monitor 15.4&amp;#8221; antiglare 1440&amp;#215;900 &lt;/li&gt;
		&lt;li&gt;Grafika: nVidia &lt;span class="caps"&gt;FX1700M&lt;/span&gt;, 512MB&lt;/li&gt;
		&lt;li&gt;HD: 500GB &lt;span class="caps"&gt;SATA&lt;/span&gt;, 5400rpm    &lt;/li&gt;
		&lt;li&gt;8x &lt;span class="caps"&gt;DVD&lt;/span&gt;+-/RW&lt;/li&gt;
		&lt;li&gt;Podświetlana klawiatura&lt;/li&gt;
		&lt;li&gt;Bateria 9 cell 85W W/HR LI-ION&lt;/li&gt;
		&lt;li&gt;Wifi  Intel Pro Wireless 5300 (802.11a/g/ Draft-n 3&amp;#215;3) MiniCard for Centrino 2 Label &lt;/li&gt;
		&lt;li&gt;Bluetooth: &lt;span class="caps"&gt;EMEA&lt;/span&gt; Dell Wireless 370 Bluetooth 2.1 MiniCard &lt;/li&gt;
		&lt;li&gt;Kamerka 0.3 Mega Pixel + mikrofon&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;USB&lt;/span&gt;/Firewire: brak informacji odnośnie portów &lt;span class="caps"&gt;USB&lt;/span&gt; (ale pewnie jakieś ma) oraz Fireware (tu domyślam się że nie ma, bo by się pochwalili, a jak ma to na pewno nie szybki &lt;span class="caps"&gt;FW800&lt;/span&gt;)&lt;/li&gt;
		&lt;li&gt;Karta sieciowa: brak informacji, nie wiem czy ma i jaką, załóżmy że jakąś ma.&lt;/li&gt;
		&lt;li&gt;SD-card: brak informacji, pewnie nie ma&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;span class="caps"&gt;CENA KO&lt;/span&gt;ŃCOWA (z &lt;span class="caps"&gt;VAT&lt;/span&gt; i dostawą): &lt;strong&gt;3019 euro&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;MacBook Pro 15-inch&lt;/li&gt;
		&lt;li&gt;Procesor: taki sam jak w &lt;span class="caps"&gt;DELL&lt;/span&gt;&amp;#8217;u&lt;/li&gt;
		&lt;li&gt;Pamięć: też 4GB ale szybsza od tej w &lt;span class="caps"&gt;DELL&lt;/span&gt;&amp;#8217;u, bo &lt;span class="caps"&gt;DDR3&lt;/span&gt; 1066MHz&lt;/li&gt;
		&lt;li&gt;OS: Mac OS-X Leopard 10.5 64bit&lt;/li&gt;
		&lt;li&gt;Monitor: też 15.4&amp;#8221; i też natywna rozdzielczość 1440&amp;#215;900, też matowy (domyślnie proponowany jest glossy)&lt;/li&gt;
		&lt;li&gt;Grafika: dwie karty graficzne: nVidia GeForce 9600M GT (512MB własnej pamięci) oraz nVidia 8400M z pamięcią współdzieloną z &lt;span class="caps"&gt;RAM&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;HD: taki sam&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;: SuperDrive, mniej więcej podobny&lt;/li&gt;
		&lt;li&gt;też podświetlana klawiatura&lt;/li&gt;
		&lt;li&gt;Bateria litowo-polimerowa o wydłużonym czasie pracy &amp;#8211; do 7 godzin z włączonym WiFi!&lt;/li&gt;
		&lt;li&gt;Wifi: Built-in AirPort Extreme Wi-Fi wireless networking2 (based on &lt;span class="caps"&gt;IEEE 802&lt;/span&gt;.11n draft specification); &lt;span class="caps"&gt;IEEE 802&lt;/span&gt;.11a/b/g compatible&lt;/li&gt;
		&lt;li&gt;Bluetooth: wbudowany Bluetooth 2.1 + &lt;span class="caps"&gt;EDR&lt;/span&gt; (Enhanced Data Rate) &amp;#8211; to chyba jakaś przyśpieszona wersja&lt;/li&gt;
		&lt;li&gt;Kamerka: iSight &amp;#8211; wbudowana + mikrofon&lt;/li&gt;
		&lt;li&gt;2 x &lt;span class="caps"&gt;USB2&lt;/span&gt; + 1 x Firewire 800&lt;/li&gt;
		&lt;li&gt;SD card&lt;/li&gt;
		&lt;li&gt;MagSave &amp;#8211; kabel zasilający wpinany jest na magnes. Potknięcie się o kabel nie grozi zrzuceniem laptopa ze stołu. Oczywiście, &lt;span class="caps"&gt;DELL&lt;/span&gt; tego nie ma.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;span class="caps"&gt;CENA KO&lt;/span&gt;ŃCOWA (z &lt;span class="caps"&gt;VAT&lt;/span&gt; i dostawą): &lt;strong&gt;2032 euro&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Jak widać, laptop firmy Apple jest DUŻO tańszy od &lt;span class="caps"&gt;DELL&lt;/span&gt;&amp;#8217;a &amp;#8211; aż o prawie 1000 euro!&lt;/p&gt;


	&lt;p&gt;Zasadniczo oba modele są porównywalne, choć &lt;span class="caps"&gt;MBP&lt;/span&gt; jest lepiej wyposażony. Ma &lt;span class="caps"&gt;FW800&lt;/span&gt; oraz przydatny MagSave oraz co ważniejsze, specjalną baterię o bardzo długim czasie pracy. System operacyjny Apple&amp;#8217;a też od razu oferuje wszystkie wersje językowe. Windowsy zaś są sprzedawane oddzielnie dla każdej wersji językowej, co powoduje dodatkowe koszty. Apple też ma dużo lepszy (bo multitouch) trackpad. Ma też pilota, ale już go nie włączałem do zestawu. &lt;span class="caps"&gt;MBP&lt;/span&gt; ma też 2 karty graficzne dzięki czemu może jeszcze bardziej oszczędzać baterię. Karty są mniej więcej podobne, choć ponoć te w &lt;span class="caps"&gt;DELL&lt;/span&gt;&amp;#8217;u są &lt;a href="http://forum.pclab.pl/index.php?showtopic=396031"&gt;lepiej zoptymalizowane do oprogramowania &lt;span class="caps"&gt;CAD&lt;/span&gt;, ale już niekoniecznie do gier&lt;/a&gt;. Można próbować trochę zbić cenę &lt;span class="caps"&gt;DELL&lt;/span&gt;&amp;#8217;a wstawiając słabszą nVidia &lt;span class="caps"&gt;FX770M&lt;/span&gt; ale to raptem oszczędność tylko 230 euro, co sprowadza cenę końcową do wartości 2740 euro, wciąż dużo drożej od laptopa Apple&amp;#8217;a.&lt;/p&gt;


	&lt;p&gt;Dodatkowo trzeba powiedzieć, że na laptopie Apple można bez problemu odpalić praktycznie dowolny system (w tym Windows!) czego nie można powiedzieć o &lt;span class="caps"&gt;DELL&lt;/span&gt;&amp;#8217;u. Przynajmniej legalnie nie jest możliwe aby postawić na nim system Mac OS-X. Na &lt;span class="caps"&gt;MBP&lt;/span&gt; można też odpalać programy Windowsowe nawet bez posiadania w ogóle Windowsów dzięki programom takim jak Wine lub, dla tych co cenią sobie prostotę &amp;#8211; &lt;a href="http://www.codeweavers.com/products/"&gt;CrossOver&lt;/a&gt;. W sumie więc, nie widzę żadnego sensu aby kupować laptopa pecetowego. Pod praktycznie każdym względem przegrywa z laptopem Apple&amp;#8217;a. Ci, co kupują blaszakowe laptopy to frajerzy bo przepłacają za sprzęt o mniejszych możliwościach. No chyba, że potrzebują laptopa z niższej półki, wolniejszego i tańszego. Apple po prostu nie oferuje laptopów w tym segmencie. I tyle.&lt;/p&gt;


	&lt;p&gt;Dlaczego ludzie więc twierdzą, że laptopy Apple&amp;#8217;a są droższe? Moim zdaniem, jest tak z kilku powodów.&lt;/p&gt;


	&lt;p&gt;1. Ci co tak twierdzą, nigdy nie zadali sobie trudu aby faktycznie porównać ceny jakiegoś laptopa o podobnych parametrach i powtarzają gdzieś zasłyszane ploty z dawnych lat (kiedy Apple był faktycznie droższy),&lt;/p&gt;


	&lt;p&gt;2. Niektórzy porównują ze sobą laptopy należące do zupełnie innej półki. Porównują &lt;span class="caps"&gt;MBP&lt;/span&gt; z jakimiś nędznymi Acerami i innymi laptopami z niskiej półki (tzn. o gorszym hardware i wyposażeniu). Jest to tak samo idiotyczne jak porównywanie Harleya z hulajnogą.&lt;/p&gt;


	&lt;p&gt;3. Porównują ceny z różnych krajów. Np. cenę laptopa w &lt;span class="caps"&gt;USA&lt;/span&gt; z ceną innego laptopa w Polsce. To zupełnie nie ma sensu. Aby porównanie miało sens, należy porównywać obu ceny w tym samym kraju.&lt;/p&gt;


	&lt;p&gt;Czy &lt;span class="caps"&gt;MBP&lt;/span&gt; jest tani? Oczywiście, że nie. Ale przecież żaden laptop w tej klasie nie jest tani. Czy jest droższy od odpowiedników PC? Nie. Cena jest typowa dla laptopów z tej półki lub niższa (na korzyść &lt;span class="caps"&gt;MBP&lt;/span&gt;).&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Aktualizacja&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Czy tylko laptopy Apple&amp;#8217;a są tańsze? Niekoniecznie. Dla odmiany porównałem podobne sprzętowe konfiguracje desktopów (też w Irlandii), czyli&lt;/p&gt;


	&lt;h3&gt;MacPro vs &lt;span class="caps"&gt;DELL&lt;/span&gt; Precision &lt;span class="caps"&gt;T5500&lt;/span&gt;&lt;/h3&gt;


	&lt;p&gt;No to porównajmy&amp;#8230;&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;DELL&lt;/span&gt; Precision &lt;span class="caps"&gt;T5500&lt;/span&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Obudowa desktop+IEEE 1394b&lt;/li&gt;
		&lt;li&gt;OS: (English) Genuine Windows Vista® Ultimate x64 &lt;span class="caps"&gt;SP1&lt;/span&gt; Media &lt;/li&gt;
		&lt;li&gt;Procesor: Intel® Xeon® Processor &lt;span class="caps"&gt;X5550&lt;/span&gt; (2.66GHz,8MB L3, 6.4GT/s, 95W,QC)&lt;/li&gt;
		&lt;li&gt;Grafika:  Nvidia Quadro &lt;span class="caps"&gt;FX580 512MB&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Pamięć: 3GB &lt;span class="caps"&gt;DDR3&lt;/span&gt; 1066MHz &lt;span class="caps"&gt;ECC&lt;/span&gt;-UDIMM (3&amp;#215;1GB) &lt;/li&gt;
		&lt;li&gt;1TB (7200 &lt;span class="caps"&gt;RPM&lt;/span&gt;) SATA 3.0Gb/s Hard Drive with &lt;span class="caps"&gt;NCQ&lt;/span&gt; and 16MB DataBurst Cache&lt;/li&gt;
		&lt;li&gt;16xDVD+/-RW Drive &lt;ins&gt;16xDVD&lt;/ins&gt;/-RW Drive for Vista Ultimate 32Bit-64Bit with Roxio (PowerDVD in OS)&lt;/li&gt;
		&lt;li&gt;Dell Black 2 Button &lt;span class="caps"&gt;USB&lt;/span&gt; Optical Mouse&lt;/li&gt;
		&lt;li&gt;no sound&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;span class="caps"&gt;CENA KO&lt;/span&gt;ŃCOWA (z &lt;span class="caps"&gt;VAT&lt;/span&gt; i przesyłką):  &lt;strong&gt;3526&lt;/strong&gt; euro&lt;/p&gt;


	&lt;p&gt;MacPro&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Ten sam procesor, pamięć i dysk, &lt;/li&gt;
		&lt;li&gt;Grafika: &lt;span class="caps"&gt;ATI&lt;/span&gt; Radeon &lt;span class="caps"&gt;HD 4870 512MB&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;One 18x SuperDrive&lt;/li&gt;
		&lt;li&gt;Apple Mighty Mouse&lt;/li&gt;
		&lt;li&gt;AirPort Extreme Wi-Fi Card with 802.11n&lt;/li&gt;
		&lt;li&gt;wbudowany dźwięk&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;span class="caps"&gt;CENA KO&lt;/span&gt;ŃCOWA (z &lt;span class="caps"&gt;VAT&lt;/span&gt; i przesyłką):  &lt;strong&gt;2643&lt;/strong&gt; euro&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=pupqkqrjvoI:nwEvwNI8ajY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=pupqkqrjvoI:nwEvwNI8ajY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=pupqkqrjvoI:nwEvwNI8ajY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=pupqkqrjvoI:nwEvwNI8ajY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 15 Aug 2009 01:52:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:cc9a91ea-1878-4f4f-be4c-6da8c30ce8d6</guid>
      <comments>http://blog.zabiello.com/2009/08/15/czy-apple-jest-drozszy-od-pc#comments</comments>
      <category>apple</category>
      <category>pc</category>
      <category>porównanie</category>
      <category>laptop</category>
      <category>mbp</category>
      <category>dell</category>
      <category>leopard</category>
      <category>osx</category>
      <category>windows</category>
      <category>vista</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/pupqkqrjvoI/czy-apple-jest-drozszy-od-pc</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/08/15/czy-apple-jest-drozszy-od-pc</feedburner:origLink></item>
    <item>
      <title>Atak na zabezpieczenia protected/private Javy/Scali i PHP5</title>
      <description>&lt;p&gt;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 &lt;em&gt;private&lt;/em&gt; i &lt;em&gt;protected&lt;/em&gt;. W języku &lt;span class="caps"&gt;PHP 5&lt;/span&gt; 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 &lt;span class="caps"&gt;PHP 5&lt;/span&gt;, jak i w Javie. Przy czym o ile, w Javie wynika to raczej z celowego projektu w mechanizmie refleksji, w &lt;span class="caps"&gt;PHP 5&lt;/span&gt; wygląda to na dziurę bezpieczeństwa&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Aby przełamać zabezpieczenia dostępu do atrybutów &lt;em&gt;private&lt;/em&gt; i &lt;em&gt;protected&lt;/em&gt; w wypadku Javy wystarczy użyć refleksji. W związku z tym, że Scala korzysta z tego samego mechanizmu refleksji co Java, problem ten dotyczy tak samo Scali. Poniższy kod wyświetla wartości atrybutów &lt;em&gt;private&lt;/em&gt; i &lt;em&gt;protected&lt;/em&gt;.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;   
import java.lang.reflect.{Field}

class SecureData  {
  private val priv = "my-private-value" 
  protected val prot = "my-protected-value" 
}

object Main {
  def main(args:Array[String]) {
    val obj = new SecureData()
    for(f &amp;lt;- obj.getClass.getDeclaredFields) {
      f.setAccessible(true)
      println(f.getName+"="+f.get(obj))
    }
  }
}
&lt;/pre&gt;

	&lt;p&gt;Powyższy kod nie jest jakimś hackerskim zabiegiem. Jest zwykłym użyciem tego co daje refleksja. Tzn. domyślnie metoda &lt;code&gt;setAccessible&lt;/code&gt; pozwala zmienić dostęp do tych atrybutów (można to samo zrobić z metodami), o ile nie podejmiemy specjalnych działań zapobiegawczych poprzez użycie np. SecurityManagera.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;W PHP 5&lt;/span&gt; użycie refleksji nic nie pomoże, bo nie ma tam metody &lt;code&gt;setAccessible&lt;/code&gt;. Jednakże, na skutek błędów w implementacji &lt;span class="caps"&gt;PHP 5&lt;/span&gt; (sprawdzane włącznie z najnowszym, wydanym 2 dni temu, &lt;span class="caps"&gt;PHP 5&lt;/span&gt;.3 &lt;span class="caps"&gt;RC4&lt;/span&gt;) złamanie zabezpieczeń tego języka jest też bardzo łatwe. Poniższa funkcja &lt;code&gt;expose&lt;/code&gt; wyświetli każdy atrybut danej instancji klasy, bez względu na to czy atrybut ten jest chroniony kwalifikatorem &lt;em&gt;protected&lt;/em&gt; czy &lt;em&gt;private&lt;/em&gt;.&lt;/p&gt;


&lt;pre class="brush:php"&gt;
&amp;lt;?php
class SecureData {
  private $priv="my-private-value";
  protected $prot="my-protected-value";
}

function expose($obj, $attr_name) {
  $a = (array)$obj;
  $r = new ReflectionProperty($obj, $attr_name);
  if ($r-&amp;gt;isPrivate())
    return $a["\0".get_class($obj)."\0".$attr_name];
  elseif ($r-&amp;gt;isProtected()) 
    return $a["\0*\0".$attr_name];
  else 
    return $obj-&amp;gt;$attr_name;
}

$c = new SecureData;
echo expose($c, 'priv'); # =&amp;gt; my-private-value
echo expose($c, 'prot'); # =&amp;gt; my-protected-value
?&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Można też iść &amp;#8220;na całość&amp;#8221; i zmodyfikować treści udostępnianie przez te atrybuty, co może być trochę katastrofalne w skutkach. Wystarczy zamiast rzutowania do array&amp;#8217;a użyć metody &lt;code&gt;settype&lt;/code&gt;. Jedyną wadą jest to, że po użyciu &lt;code&gt;settype&lt;/code&gt; zniszczona została cała informacja o klasie i interfejsie obiektu.&lt;/p&gt;


&lt;pre class="brush:php"&gt;
&amp;lt;?php
function hack(&amp;#38;$obj, $attr_name, $value) {
  $r = new ReflectionProperty($obj, $attr_name);
  $class = get_class($obj);
  settype($obj, 'array');
  if ($r-&amp;gt;isPrivate())
    $obj["\0$class\0".$attr_name] = $value;
  elseif ($r-&amp;gt;isProtected()) 
    $obj["\0*\0".$attr_name] = $value;
} 

$c = new SecureData;
hack($c, 'priv', 'my-hacked-private-value'); 
var_dump($c);
/*
array(2) {
  ["Cpriv"]=&amp;gt;
  string(23) "my-hacked-private-value" 
  ["*prot"]=&amp;gt;
  string(18) "my-protected-value" 
} 
*/
?&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Na tym tle stanowisko Pythona nie brzmi wcale aż tak źle. W Pythonie wszystkie metody i atrybuty są &lt;em&gt;publiczne&lt;/em&gt;. Jeśli programista chce to ma dostęp do wszystkiego. I tak przecież będzie miał taki dostęp jak się uprze, więc po co mu utrudniać życie, prawda? Wg filozofii Pythona, jedyną zaletą posiadani takich kwalifikatorów dostępu byłoby to, aby uniknąć &lt;strong&gt;pomyłki&lt;/strong&gt; a nie, aby bić programistę po łapach. W Pythonie  rozwiązano to za pomocą tzw. &amp;#8220;manglingu&amp;#8221;  nazw. Otóż metody (i atrybuty) których nazwy zaczynają się od dwóch znaków podkreślenia (ale równocześnie nie mogą się kończyć takimi znakami) są traktowane specjalnie przy próbie uzyskania do nich dostępu. Tzn. formalnie nadal są public (tak jak wszystko inne), trzeba jednak użyć trochę innej, lekko zamotanej, składni. I to jest wystarczające, aby programista się nie pomylił.&lt;/p&gt;


&lt;pre class="brush:python"&gt;                   
class SecureData(object):
  __priv = "my-private=value" 
  _prot = "my-protected-value" 

try: 
  print SecureData.__priv
except AttributeError:
  print "Wrong syntax, you lame!" 

print SecureData._SecureData__priv 
# =&amp;gt; my-private=value  
&lt;/pre&gt;  

	&lt;p&gt;Zobacz też&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://javabeans.asia/2008/10/13/hack_any_java_class_using_reflection_attack.html"&gt;Hack any Java class using reflection attack&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://javabeans.asia/2008/10/12/how_to_set_securitymanager_and_java_security_policy_programmatically.html"&gt;How to set SecurityManager and Java security policy programmatically&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=_4kb5H-C4eM:zo27GNdPzGI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=_4kb5H-C4eM:zo27GNdPzGI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=_4kb5H-C4eM:zo27GNdPzGI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=_4kb5H-C4eM:zo27GNdPzGI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 21 Jun 2009 05:45:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:d18aaae6-dd48-4837-a811-120621c84922</guid>
      <comments>http://blog.zabiello.com/2009/06/21/zabezpieczenia-protected-private-java-scala-php5#comments</comments>
      <category>scala</category>
      <category>java</category>
      <category>php</category>
      <category>python</category>
      <category>reflection</category>
      <category>hacking</category>
      <category>security</category>
      <category>ruby</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/_4kb5H-C4eM/zabezpieczenia-protected-private-java-scala-php5</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/06/21/zabezpieczenia-protected-private-java-scala-php5</feedburner:origLink></item>
    <item>
      <title>Scala i Lift on GAE</title>
      <description>&lt;p&gt;Google opublikowało &lt;a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine"&gt;listę języków i javowych frameworków&lt;/a&gt; dostępnych dla swojego &lt;span class="caps"&gt;GAE&lt;/span&gt; (Google App Engine). Na liście jest m.in. JRuby, Jython, Groovy i Scala. Z powodu ograniczeń dostępności do wątków i &lt;span class="caps"&gt;JDBC&lt;/span&gt; napisano, że &lt;a href="http://liftweb.net/"&gt;Lift&lt;/a&gt; nie jest wspierany.  Jak jednak można wyczytać z jednym ostatnich &lt;a href="http://www.scala-lang.org/node/1440"&gt;wątków na liście dyskusyjnej Scali&lt;/a&gt;, trochę pośpieszono się z tą informacją. Lift daje się odpalić na &lt;span class="caps"&gt;GAE&lt;/span&gt; (to jest &lt;a href="http://github.com/ymnk/liftweb/tree/master"&gt;fork do kodu źródłowego&lt;/a&gt;). Scala posiada &lt;a href="http://www.scala-lang.org/node/242"&gt;dwa rodzaje Aktorów&lt;/a&gt; &amp;#8211; opartych na natywnych wątkach OS oraz opartych na asynchronicznej pętli, bez użycia wątków. Lift nie potrzebuje więc obsługi wątków do swej pracy. Co do &lt;span class="caps"&gt;JDBC&lt;/span&gt;, to sprawa jest trochę mętna, bo udało się uruchomić Lifta na pamięciowej bazie H2. Być może ograniczenie Google&amp;#8217;a dotyczy tylko baz relacyjnych?&lt;/p&gt;


	&lt;p&gt;Updated: &lt;a href="http://spreadsheets.google.com/pub?key=pRJ_0hajVrhacLjp3HqD5ew"&gt;Frameworks and libraries supported by Google App Engine Java : List&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=GALqWNqrWQk:aT53WdOhVe4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=GALqWNqrWQk:aT53WdOhVe4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=GALqWNqrWQk:aT53WdOhVe4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=GALqWNqrWQk:aT53WdOhVe4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 13 Apr 2009 06:32:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:5e0ee4d7-369d-4081-88a6-d581af6f0c9c</guid>
      <comments>http://blog.zabiello.com/2009/04/13/scala-lift-on-gae#comments</comments>
      <category>gae</category>
      <category>java</category>
      <category>scala</category>
      <category>lift</category>
      <category>google</category>
      <category>h2</category>
      <category>jruby</category>
      <category>jython</category>
      <category>groovy</category>
      <category>jdbc</category>
      <category>actors</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/GALqWNqrWQk/scala-lift-on-gae</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/04/13/scala-lift-on-gae</feedburner:origLink></item>
    <item>
      <title>Projekt Eulera 17 -  Ruby, Python, Scala</title>
      <description>&lt;p&gt;Na polskim forum RoR pojawiła się &lt;a href="http://rubyonrails.pl/forum/t1611-Wprowadzenie"&gt;informacja o projekcie Eulera&lt;/a&gt; składającym się z różnych łamigłówek programistycznych. Na forum RoR przedstawiane są &lt;a href="http://rubyonrails.pl/forum/f14-Projekt-Euler-w-Ruby"&gt;rozwiązania w języku Ruby&lt;/a&gt;. Istnieją też &lt;a href="http://clojure-euler.wikispaces.com/"&gt;rozwiązania w języku Clojure&lt;/a&gt;. Takie projekty są dobrym pretekstem do poćwiczenia swoich umiejętności programowania.&lt;/p&gt;


	&lt;p&gt;Zadanie 17 brzmi następująco.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Jeśli liczby od 1 do 5 zapisać za pomocą ich (angielskich) słów: one, two, three, four, five, to wtedy użyte zostanie 3 + 3 + 5 + 4 + 4 = 19 liter. Gdyby wszystkie liczby od 1 do 1000 zapisać za pomocą słów to ile w sumie by użyto liter?
Uwaga: nie należy liczyć spacji ani myślników. Np. liczba 342 (three hundred and fourty-two) zawiera 23 litery a liczba 115 (one hundred and fifteen) zawiera 20 liter. Łącznik &amp;#8220;and&amp;#8221; jest wymagany w jęz. angielskim.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Rozwiązane &lt;a href="http://rubyonrails.pl/forum/viewtopic.php?pid=9461#p9028"&gt;podesłane&lt;/a&gt; w Ruby:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
def to_words(num)
  a0 = %w{ one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen }
  a1 = %w{ twenty thirty forty fifty sixty seventy eighty ninety }
  case num
  when 1..19
    a0[num-1]
  when 20..99
    num % 10 != 0 ? "#{a1[(num-20)/10]}#{a0[num % 10 - 1]}" : a1[(num-20)/10]
  when 100..999
    num % 100 != 0 ? "#{to_words(num/100)}hundredand#{to_words(num % 100)}" : "#{to_words(num/100)}hundred" 
  when 1000
    "onethousand" 
  end
end

puts (1..1000).inject('') { |acc,n| acc &amp;lt;&amp;lt; to_words(n)}.size
&lt;/pre&gt;

	&lt;p&gt;W Pythonie można by to samo zapisać w zwarty sposób jako&lt;/p&gt;


&lt;pre class="brush:python"&gt;
def to_words(num):
  a0 = 'one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'.split(' ')
  a1 = 'twenty thirty forty fifty sixty seventy eighty ninety'.split(' ')
  if 1&amp;lt;= num &amp;lt;= 19:  return a0[num-1]
  if 20 &amp;lt;= num &amp;lt;= 99: return  "%s%s" % (a1[(num-20)/10], a0[num % 10 - 1]) if num % 10 != 0 else a1[(num-20)/10]
  if 100 &amp;lt;= num &amp;lt;= 999: return "%shundredand%s" % (to_words(num/100), to_words(num % 100)) if num % 100 != 0 else "%shundred" % to_words(num/100)
  if num == 1000: return "onethousand" 

print sum([len(to_words(n)) for n in range(1,1001)])
&lt;/pre&gt;

	&lt;p&gt;Zaś w Scali odpowiednikiem mógłby być kod:&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
def to_words(num: Int): String = {
  val a0 = "one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split(' ')
  val a1 = "twenty thirty forty fifty si6xty seventy eighty ninety".split(' ')
  if (1 to 19 contains num) return a0(num-1)
  if (20 to 99 contains num) return if (num % 10 != 0) "%s%s".format(a1((num-20)/10), a0(num % 10 - 1)) else a1((num-20)/10)
  if (100 to 999 contains num) return if (num % 100 != 0) "%shundredand%s".format(to_words(num/100), to_words(num % 100)) else "%shundred".format(to_words(num/100))
  if (num == 1000) "onethousand" else "" 
}

println((for(n &amp;lt;- 1 to 1000) yield to_words(n).length).foldLeft(0)(_ + _))                                                                          
&lt;/pre&gt;
Kod 

&lt;pre class="brush:scala"&gt;
1 to 19 contains num
&lt;/pre&gt;

	&lt;p&gt;to zapis w &lt;em&gt;notacji operatorowej&lt;/em&gt; odpowiadający&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
(1.to(19)).contains(num)
&lt;/pre&gt;

	&lt;p&gt;Warunek logiczny &lt;code&gt;if&lt;/code&gt; zwraca wartość którą można przypisać do zmiennej. &lt;code&gt;for()&lt;/code&gt; jest też wyrażeniem. Słówko &lt;code&gt;yield&lt;/code&gt; powoduje, że całość jest zwracana jako lista.  Z kolei kod&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
for(n &amp;lt;- 1 to 1000) yield to_words(n).length
&lt;/pre&gt;

	&lt;p&gt;można by zapisać w Pythonie za pomocą wyrażenia listowego&lt;/p&gt;


&lt;pre class="brush:python"&gt;
[len(to_words(n)) for n in range(1,10001)]
&lt;/pre&gt;

	&lt;p&gt;zaś w Ruby byłoby to&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
(1..1000).map{|n| to_words(n).size}
&lt;/pre&gt;

	&lt;p&gt;Z powyższego kodu można by wyrzucić uprościć warunki logiczne. Poza tym możemy nie chcieć, aby zmienne &lt;code&gt;a0&lt;/code&gt; i &lt;code&gt;a1&lt;/code&gt; były inicjowane przy każdym uruchomieniu funkcji. Poza tym Scala posiada świetny mechanizm znany w z języków funkcyjnych &amp;#8211; &lt;em&gt;pattern matching&lt;/em&gt;. Zatem w innej wersji, rozwiązanie mogłoby wyglądać następująco:&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
def to_words(num: Int): String = num match {
  case n if n &amp;lt;= 19 =&amp;gt; a0(n-1)
  case n if n &amp;lt;= 99 =&amp;gt; if (n % 10 != 0) "%s%s".format(a1((n-20)/10), a0(n % 10 - 1)) else a1((n-20)/10)
  case n if n &amp;lt;= 999 =&amp;gt; if (n % 100 != 0) "%shundredand%s".format(to_words(n/100), to_words(n % 100)) else "%shundred".format(to_words(n/100))
  case _ =&amp;gt; "out of 1..1000" 
}                                           

val a0 = ("one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen").split(' ')
val a1 = "twenty thirty forty fifty sixty seventy eighty ninety".split(' ')

println((for(n &amp;lt;- 1 to 1000) yield to_words(n).length).foldLeft(0)(_ + _))       
&lt;/pre&gt;

	&lt;p&gt;Pewnym problemem jest to, że definicje zmiennych &lt;code&gt;a0&lt;/code&gt; i &lt;code&gt;a1&lt;/code&gt; które są wystawione na zewnątrz. Można to ominąć poprzez użycie funkcji jako obiektu i stworzenie w nim wewnętrznej metody.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
  def to_words = {
    val a0 = ("one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen").split(' ')
    val a1 = "twenty thirty forty fifty sixty seventy eighty ninety".split(' ')                

    def res(num: Int): String = num match {
      case n if n &amp;lt;= 19 =&amp;gt; a0(n-1)
      case n if n &amp;lt;= 99 =&amp;gt; if (n % 10 != 0) "%s%s".format(a1((n-20)/10), a0(n % 10 - 1)) else a1((n-20)/10)
      case n if n &amp;lt;= 999 =&amp;gt; if (n % 100 != 0) "%shundredand%s".format(res(n/100), res(n % 100)) else "%shundred".format(res(n/100))
      case n if n == 1000 =&amp;gt; "onethousand" 
      case _ =&amp;gt; "out of 1..1000" 
    }
    res _
  }
&lt;/pre&gt;

	&lt;p&gt;Taki kod uruchomi inicjację listy słów tylko raz. Jednakże Scala pozwala na bardziej idiomatyczny zapis.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
val to_words: Int =&amp;gt; String = {
  val a0 = ("one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen").split(' ')
  val a1 = "twenty thirty forty fifty sixty seventy eighty ninety".split(' ') 

  (num: Int) =&amp;gt; num match {
    case n if n &amp;lt;= 19 =&amp;gt; a0(n-1)
    case n if n &amp;lt;= 99 =&amp;gt; if (n % 10 != 0) "%s%s".format(a1((n-20)/10), a0(n % 10 - 1)) else a1((n-20)/10)
    case n if n &amp;lt;= 999 =&amp;gt; if (n % 100 != 0) "%shundredand%s".format(to_words(n/100), to_words(n % 100)) else "%shundred".format(to_words(n/100))
    case n if n == 1000 =&amp;gt; "onethousand" 
    case _ =&amp;gt; "out of 1..1000" 
  }
}
&lt;/pre&gt;

	&lt;p&gt;W tym wypadku użyto mechanizmu zarówno obiektowego (funkcja jest obiektem) jak i funkcyjnego (pattern matching).&lt;/p&gt;


	&lt;p&gt;O Scali można sobie podyskutować na polskich kanałach &lt;span class="caps"&gt;IRC&lt;/span&gt; &lt;a href="irc://irc.eu.freenode.net/ruby.pl"&gt;#ruby.pl&lt;/a&gt; i (nowo powstałym)  &lt;a href="irc://irc.eu.freenode.net/scala.pl"&gt;#scala.pl&lt;/a&gt; (oczywiście anglojęzyczny kanał &lt;a href="irc://irc.eu.freenode.net/scala"&gt;#scala&lt;/a&gt; jest również bardzo pomocny).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=wGwd1xxLTjM:FefBeTrdUVw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=wGwd1xxLTjM:FefBeTrdUVw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=wGwd1xxLTjM:FefBeTrdUVw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=wGwd1xxLTjM:FefBeTrdUVw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 05 Apr 2009 23:24:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:80a84d51-e7e9-4510-a4d7-31b076dfa8d3</guid>
      <comments>http://blog.zabiello.com/2009/04/05/projekt-eulera-17-ruby-python-scala#comments</comments>
      <category>euler</category>
      <category>ruby</category>
      <category>scala</category>
      <category>clojure</category>
      <category>python</category>
      <category>fp</category>
      <category>oop</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/wGwd1xxLTjM/projekt-eulera-17-ruby-python-scala</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/04/05/projekt-eulera-17-ruby-python-scala</feedburner:origLink></item>
    <item>
      <title>Scala - język przyszłości</title>
      <description>&lt;p&gt;&lt;a href="http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming"&gt;Kiedy zapytano Jamesa Goslinga&lt;/a&gt; (twórcę Javy) o to, który z języków programowania współpracujących z &lt;span class="caps"&gt;JVM&lt;/span&gt; (wirtualną maszyną Javy) by użył &lt;em&gt;teraz&lt;/em&gt;, pomijając samą Javę, odpowiedź była zaskakująco szybka i bardzo jasna &amp;#8211; &lt;a href="http://scala-lang.org"&gt;&lt;strong&gt;Scala&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Nazwa &amp;#8220;Scala&amp;#8221; pochodzi od &amp;#8220;&lt;strong&gt;Sca&lt;/strong&gt;lable &lt;strong&gt;la&lt;/strong&gt;nguage&amp;#8221; (język skalowalny). Język ten nadaje się równie dobrze do krótkich, zwartych skryptów jak i do tworzenia wydajnych, ogromnych, bezpiecznych systemów sieciowych. W swych założeniach Scala nawiązuje do minimalizmu składni Lispa i Smalltalka (większość rzeczy oparta jest na bibliotekach a nie na składni) dzięki czemu język ten praktycznie nie ma ograniczeń rozwoju i doskonale się skaluje (w miarę potrzeb można tworzyć nowe typy i całe nowe struktury wyglądające jak nowa składnia języka).&lt;/p&gt;


	&lt;p&gt;Scala jest językiem kompilowanym do bytecodu &lt;span class="caps"&gt;JVM&lt;/span&gt; dzięki czemu potrafi się integrować w sposób praktycznie przezroczysty, z całą platformą Javy (istnieje co prawda implementacja Scali dla platformy .NET ale jest jeszcze niedojrzała). W Scali mamy też wygodną konsolę do interaktywnego testowania kodu (tak jak to jest w Pythonie i Ruby). W Scali każda wartość jest obiektem, każda funkcja zwraca wartość. Zatem każda funkcja też jest obiektem (first class object). Funkcje są też obiektami wyższego rzędu (higher order kinds), można je zagnieżdżać, przekazywać w parametrach, a nawet stosować mechanizm dziedziczenia.&lt;/p&gt;


	&lt;h2&gt;Java jako platforma i jako język&lt;/h2&gt;


	&lt;p&gt;Słowo &amp;#8220;Java&amp;#8221; oznacza z jednej strony język programowania, z drugiej platformę &lt;span class="caps"&gt;JVM&lt;/span&gt;. Sam język Java jest co prawda prosty, ale też dosyć toporny. Nic dziwnego, że pada wiele słów krytyki pod jego adresem. Co innego platforma Javy. &lt;span class="caps"&gt;JVM&lt;/span&gt; jest dopracowana, stabilna i szybka (ze swoim &lt;a href="http://en.wikipedia.org/wiki/HotSpot"&gt;HotSpotem&lt;/a&gt; potrafi pobić &lt;a href="http://www.stefankrause.net/wp/?p=6"&gt;kod napisany w języku C&lt;/a&gt;). Biblioteki są dojrzałe i używane masowo w biznesie i instytucjach finansowych. Każda nowość błyskawicznie znajduje swoje odzwierciedleniew Javie (ilość projektów w Javie wielokrotnie przewyższa to, co jest dostępne dla platformy .NET). Platforma Javy mocno prze do przodu i zwiększa stale swoją pozycję. Wydaje się tylko, że sam język nie za bardzo nadąża za tymi zmianami.&lt;/p&gt;


	&lt;p&gt;Gdy Microsoft &amp;#8220;wyskoczył&amp;#8221; ze swoją koncepcją .NET umożliwiającą tworzenie aplikacji na tą platformę w kilku językach a nie &amp;#8220;jedynym prawidłowym&amp;#8221;, można było odebrać to jako prztyczek w nos dla starej doktryny lansowanej kiedyś w środowisku Javy (jako jednego języka do wszystkiego). W rzeczy samej, patrząc dziś, Microsoft ze swymi językami zgodnymi z &lt;span class="caps"&gt;CLR&lt;/span&gt; niczym specjalnym nie zachwyca. Po pierwsze, istnieje dziś już ok. &lt;a href="http://www.is-research.de/info/vmlanguages/"&gt;240 różnych języków zgodnych z platformą Javy&lt;/a&gt; (jakieś 5x tyle co dla &lt;span class="caps"&gt;CLR&lt;/span&gt;). Javowe implementacje powstały nawet do języków dynamicznie typowanych (&lt;a href="http://groovy.codehaus.org"&gt;Groovy&lt;/a&gt;) oraz takich jak Python (&lt;a href="http://www.jython.org/Project/"&gt;Jython&lt;/a&gt;), Ruby (&lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;), JavaScript (&lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt;) czy &lt;span class="caps"&gt;PHP&lt;/span&gt; (&lt;a href="http://www.caucho.com/resin-3.0/quercus/"&gt;Quercus&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;Po drugie, w przeciwieństwie do .NET, Java jest prawdziwie &lt;strong&gt;multiplatformowa&lt;/strong&gt; (istnieje co prawda projekt Mono, ale wciąż odstaje jakością od windowsowego .NET). Mówiąc krótko, platforma Javy trzyma się mocno. Ale sam język jest przestarzały i wszyscy się zastanawiają nad tym, co by mogło go zastąpić. Moim zdaniem, coraz więcej wskazuje, że tym językiem może być &lt;strong&gt;Scala&lt;/strong&gt;. (Swoją drogą język Java tak całkiem to pewnie nigdy nie zniknie. Raczej zredukuje się do miana assemblera &lt;span class="caps"&gt;XXI&lt;/span&gt; wieku. Zresztą już dziś tak wielu myśli o Javie, jako o assemblerze dla &lt;span class="caps"&gt;JVM&lt;/span&gt;)&lt;/p&gt;


	&lt;h2&gt;Scala jako pure &lt;span class="caps"&gt;OOP&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;Scala jest językiem obiektowym w stopniu większym niż Java. W Scali nie ma sztucznego podziału na obiekty i typy prymitywne (int, float, string). Każda wartość jest w Scali pełnym obiektem (choć pod spodem kompilator Scali, tam gdzie się da, sam dokonuje inteligentnych konwersji na javowe prymitywy).&lt;/p&gt;


	&lt;p&gt;Każdy operator jest też metodą. Np. zapis &lt;code&gt;1 + 2&lt;/code&gt; odpowiada dokładnie temu samemu co &lt;code&gt;(1).+(2)&lt;/code&gt;. Innymi słowy obiekt &amp;#8220;1&amp;#8221; używa tu metody &amp;#8221;+&amp;#8221; operującej na parametrze będącym obiektem &amp;#8220;2&amp;#8221;. A to, że można opuścić nawiasy związane jest z tzw. &lt;strong&gt;notacją operatorową&lt;/strong&gt; jaka jest możliwa Scali. O ile Ruby pozwala opuszczać nawiasy w niektórych sytuacjach (w definicji i wywołaniu metody), to Scala pozwala na opuszczanie ich w wypadku każdej metody pomiędzy dwoma wyrażeniami. W efekcie Scala pozwala na pisanie testów &lt;span class="caps"&gt;BDD&lt;/span&gt; &lt;a href="http://code.google.com/p/specs/"&gt;przypomijących jeszcze bardziej język naturalny&lt;/a&gt; niż &lt;a href="http://rspec.info"&gt;RSpec&lt;/a&gt; do Ruby&amp;#8217;ego (też &lt;a href="http://code.google.com/p/scalaz/"&gt;scalaz&lt;/a&gt;, &lt;a href="http://www.artima.com/scalatest/"&gt;scalatest&lt;/a&gt;). Także tworzenie nowych języków specjalnego zastosowania, tzw. &lt;span class="caps"&gt;DSL&lt;/span&gt;&amp;#8217;i, dzięki notacji operatorowej &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=251945"&gt;wyglądają w Scali ładniej niż w Ruby&lt;/a&gt;. W ramach żartu pokazującego elastyczność składni Scali napisano nawet &lt;a href="http://blog.fogus.me/2009/03/26/baysick-a-scala-dsl-implementing-basic/"&gt;interpreter języka &lt;span class="caps"&gt;BASIC&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;W Scali, w przeciwieństwie do Javy, nie ma też statycznych metod ani zmiennych (żałosne jest to, że tak nieobiektowe konstrukcje w ogóle wprowadzono do &lt;span class="caps"&gt;PHP&lt;/span&gt;). Zamiast nich Scala używa singletonów i metod klasowych. Oczywistą przewagą takiego podejścia jest m.in. możliwość dziedziczenia.&lt;/p&gt;


	&lt;p&gt;Podczas gdy Ruby i Python trzymają definicje metod klasowych i instancji razem, Scala trzyma je zgrupowane oddzielnie.&lt;/p&gt;


&lt;pre class="brush:python"&gt;
# Python:
class C(Object):
    def metoda_instancji(self):
        return "Jestem metodą instancji" 
    @classmethod
    def metoda_klasowa(cls):
        return "Jestem metodą klasową" 
print C.metoda_klasowa()
print C().metoda_instancji
&lt;/pre&gt;

&lt;pre class="brush:ruby"&gt;
# Ruby:
class C
  def self.metoda_klasowa
    "Jestem metodą klasową" 
  end
  def metoda_instancji
    "Jestem metodą instancji" 
  end                       
end
puts C.metoda_klasowa
puts C.new.metoda_instancji
&lt;/pre&gt;

&lt;pre class="brush:scala"&gt;
# Scala
class C {
  def metoda_instancji = 
    "Jestem metodą instancji"    
}          
object C {
  def metoda_klasowa = 
    "Jestem metodą klasową" 
} 
println((new C).metoda_instancji)
println(C.metoda_klasowa)         
&lt;/pre&gt;

	&lt;h3&gt;Scala jako język statycznie typowany z inteligentną inferencją typów&lt;/h3&gt;


	&lt;p&gt;Scala jest językiem &lt;strong&gt;statycznie typowanym&lt;/strong&gt;. Z pewnością ucieszy to tych, co nie chcą pisać tony dodatkowych testów jednostkowych. Statyczna kontrola typów zapewnia większą kontrolę nad kodem. Można się zdziwić, jakim cudem przedstawiony wyżej kod działa, skoro nie ma w nim żadnej deklaracji typów. Właściwie to powyższa deklaracja klas i singletonu formalnie wygląda tak&lt;/p&gt;


&lt;pre class="brush:scala"&gt;
class C {
  def metoda_instancji(): String = 
    return "Jestem metodą instancji";
}          
object C {
  def metoda_klasowa(): String = 
    return "Jestem metodą klasową";
} 
&lt;/pre&gt;

	&lt;p&gt;Jednak nie trzeba pisać tak rozwleklego kodu. Scala posiada wyrafinowany mechanizm &lt;strong&gt;inferencji typów&lt;/strong&gt; pozwalający na ograniczenie niepotrzebnego deklarowania typów w wypadkach kiedy kompilator jest w stanie to sobie samemu wywnioskować (podobną inferencję typów stosują inne języki, np. Haskell).&lt;/p&gt;


	&lt;p&gt;W Scali także (podobnie jak w Ruby czy JavaScript) końcowe średniki zamykające wyrażenie można pominąć,  nawiasy dla metod bez parametrowych są opcjonalne i nie trzeba używać komendy &lt;code&gt;return&lt;/code&gt; aby zwrócić wartość z metody. W Scali (podobnie jak w Ruby) zawsze zwracana jest ostatnia wartość wyrażenia.&lt;/p&gt;


	&lt;p&gt;Scala, podobnie jak Java i Ruby, nie posiada dziedziczenia wielobazowego. W przeciwieństwie do Javy, Scala nie posiada interfejsów. I bardzo dobrze, bo ich przydatność jest wysoce wątpliwa (oczywiście do &lt;span class="caps"&gt;PHP5&lt;/span&gt; dodano bezmyślnie te nieszczęsne interfejsy). Ich główną wadą jest to, że nie mogą posiadać żadnej implementacji ani deklaracji zmiennych. Z kolei klasy abstrakcyjne w Javie mogą posiadać częściową implementację, ale nie można dziedziczyć po wielu klasach abstrakcyjnych tylko po interfejsach które nie mają żadnej implementacji. Bardzo niewygodne. Scala rozwiązuje ten problem za pomocą traits. Traits działają podobnie do modułów w Ruby. Nie mają konstruktorow ani nie można stworzyć ich instancji więc odpada efekt konfliktu kolejności konstruktorów. Traits mogą jednak podlegać dziedziczeniu, mogą mieć częściową lub pełną implementację metod, oraz mogą posiadać zadeklarowane zmienne. I każda klasa może dziedziczyć po kilku traitsach. Proste i wygodne.&lt;/p&gt;


	&lt;h3&gt;Niejawne konwersje (implicit conversion)&lt;/h3&gt;


	&lt;p&gt;Idea niejawnych konwersji nie jest w zasadzie niczym nowa. Występuje już w języku C. Gdy dodawane są dwie zmienne o typach &lt;code&gt;short&lt;/code&gt; i &lt;code&gt;long&lt;/code&gt; to ta pierwsza zostaje domyślnie przekształcona do &lt;code&gt;long&lt;/code&gt;. Nie trzeba wykonywać żadnego jawnego rzutowania typu.&lt;/p&gt;


	&lt;p&gt;Scala idzie dalej. Za pomocą mechanizmu implicit conversions potrafi uzyskać efekty podobne jak w Ruby, ale bardziej bezpieczne. Zobaczmy jednak wpierw jak to się robi Ruby (który wykorzystuje swoją koncepcję &lt;a href="http://blog.zabiello.com/2006/03/04/dynamika-otwartych-klas-ruby-vs-python"&gt;otwartych klas&lt;/a&gt;).&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
class Integer
  def kb
    self * 1024
  end     
  def mb
    self * 1024 * kb
  end  
end                   

class String 
  def welcome
    "Hello " + self
  end
end

puts 10.kb # =&amp;gt; 10240
puts 10.mb # =&amp;gt; 10485760
puts "Jarek".welcome # =&amp;gt; Hello Jarek
&lt;/pre&gt;           

	&lt;p&gt;Co prawda Ruby potrafi &amp;#8220;zamrozić&amp;#8221; swoje obiekty uniemożliwiając ich modyfikację&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
Fixnum.freeze

class Integer
  def kb
    self * 1024
  end
end   
# =&amp;gt; TypeError: can't modify frozen class                     
&lt;/pre&gt;           

	&lt;p&gt;ale technika ta (zwana też trochę niepoprawnie jako &amp;#8220;monkey patching&amp;#8221;) jest używana dosyć powszechnie w Ruby. Główną jej wadą jest to, że takie zmiany w klasach są &lt;strong&gt;globalne&lt;/strong&gt; i to może prowadzić do różnych nieporozumień w innych częściach kodu.&lt;/p&gt;


	&lt;p&gt;Scala nie ma tego problemu. Pozwala na uzyskanie podobnych efektów bez konieczności globalnych zmian w obiekcie. Zamiast otwierania klas, Scala dodaje definicje niejawnych konwersji. Jeśli wywołujemy metodę obiektu której on nie posiada, Scala patrzy na leksykalny kontekst definicji dostępnych konwersji dla danego typu (jak pamietamy, Scala jest językiem statycznie typowanym). Jeśli znajdzie sygnaturę metody taką jak nazwa wywoływanej metody, użyje jej tak jakby należała do obiektu.&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
class StrConvert(s: String) {
  def welcome = "Hello " + s
}                         

class IntConvert(x: Int) {
   def kb = 1024 * x
   def mb = x * 1024 * kb
}                    

implicit def str_convert(s: String) =  new StrConvert(s)
implicit def int_convert(i: Int) =  new IntConvert(i)

println(10.kb)
println(2 mb)
println("Jarek" welcome)
&lt;/pre&gt;           

	&lt;p&gt;Kropki w wywołaniach metod są oczywiście w Scali opcjonalne ze względu na notację operatorową.&lt;/p&gt;


	&lt;p&gt;Niejawne konwersje Scali przydają się w wypadku korzystania z cudzego kodu. Nie musimy (tak jak w Ruby) ingerować i zmieniać cudzych bibliotek. Zamiast tego wystarczy dodać lokalne definicje niejawnych konwersji typów. Przykładem toporności i ograniczeń Javy jest konieczność korzystania z innej składni do operacji na typach &lt;code&gt;BigInteger&lt;/code&gt;. Jeśli początkowo pisaliśmy kod używający zwykłych typów &lt;code&gt;int&lt;/code&gt; to w wypadku kiedy musi on operować na większych liczbach, czeka nas niezła refaktoryzacja kodu a kod mógłby wyglądać mniej więcej tak jak poniższy kod (przykład dotyczy składni Scali w ktorej też można pisać po &amp;#8220;javowemu&amp;#8221;)&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;                        
import java.math.BigInteger 

def factorial(x: BigInteger): BigInteger = 
 if (x == BigInteger.ZERO) 
   BigInteger.ONE 
 else 
   x.multiply(factorial(x.subtract(BigInteger.ONE)))      
&lt;/pre&gt;           

	&lt;p&gt;Dzięki możliwościom implicit conversion, znacznie wygodniej jest pisać tak:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
def factorial(x: BigInt): BigInt = 
 if (x == 0) 1 else x * factorial(x - 1) 
&lt;/pre&gt;

	&lt;p&gt;Warto zwrócić uwagę, że to nie jest jakaś dodana nowa składnia do Scali. Wrapper do BigInt jest stworzony w bibliotece. Nie trzeba żadnego przebudowania kodu Scali tak, jak to musi być uczynione w innych językach.&lt;/p&gt;


	&lt;h2&gt;Scala jako język funkcyjny (FP)&lt;/h2&gt;


	&lt;p&gt;Mam wrażenie, że programowanie funkcyjne przeżywa jakiś swój renesans. Od jakiegoś czasu więcej słychać o &lt;a href="http://erlang.org/"&gt;Erlangu&lt;/a&gt;, &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; (świetny dialekt Lispa w Javie), &lt;a href="http://www.haskell.org/"&gt;Haskellu&lt;/a&gt; czy &lt;a href="http://www.infoq.com/news/2009/03/F-Sharp-Don-Syme"&gt;F#&lt;/a&gt;. Zalety programania funkcyjnego w stosunku do programowania imperatywnego są znane. Przede wszystkim, brak zmiennych i brak efektów ubocznych. Odpadają problemy związane z synchronizacją wątków, semaforami i blokowaniem dostępu do wspólnych obszarów pamięci. Kod pisany funkcyjnie znacznie łatwiej jest też testować. Funkcja niczym ma tylko jedno wejście i jedno wyjście. Nic innego ukradkiem nie zmieni. Programowanie funkcyjne jest też prostsze, choć osoby spaczone latami spędzonymi na programowaniu imperatywnym, mogą mieć na początku pewne problemy z przestawieniem sposobu myślenia. Np. w typowo funkcyjnym podejściu nie ma w ogóle pętli w programie. Zastępuje ją rekursja (która nie przepełnia stosu, jest to tzw. &lt;a href="http://oldfashionedsoftware.com/2008/09/27/tail-recursion-basics-in-scala/"&gt;tail recursion&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;Przykład różnic w podejściu imperatywnym oraz funkcyjnego dla Ruby&amp;#8217;ego i Scali.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Ruby:&lt;/strong&gt;&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;
# Podejście imperatywne:

class Imper
  attr_accessor :x, :y
  def initialize(x,y)
    @x, @y = x, y
  end     
  def move_by(dx, dy)
    @x += dx
    @y += dy
  end
  def show
    puts "x:#{x}, y:#{y}" 
  end
end                                                                

x = Imper.new(1,2)
x.move_by(3,4)
x.show

# To samo funkcyjnie:

class Func
  attr_reader :x, :y
  def initialize(x,y)
    @x, @y = x, y
  end     
  def move_by(dx, dy)
    Func.new(@x+dx, @y+dy)
  end
  def show
    puts "x:#{x}, y:#{y}" 
  end
end

x = Func.new(1,2)
x = x.move_by(3,4)
x.show        

# lub to samo, ale bez tworzenie zmiennych:

Func.new(1,2).move_by(3,4).show
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Scala:&lt;/strong&gt;&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
// Kod w stylu imperatywnym:

class Imper(x: Int, y: Int) {
  var iks: Int = x
  var igrek: Int = y           
  def move_by(dx: Int, dy: Int) {
    iks += dx
    igrek += dy
  }
  def show {
    println(iks,igrek)
  }
}                 
val p = new Imper(1,2)
p.move_by(3,4)
p.show

// i to samo funkcyjnie:

class Func(x: Int, y: Int) {
  val iks: Int = x
  val igrek: Int = y           
  def move_by(dx: Int, dy: Int) = new Func(iks+dx, igrek+dy)
  def show {
    println(iks,igrek)
  }
}                 
(new Func(1,2)).move_by(3,4).show
&lt;/pre&gt;

	&lt;p&gt;Obiekty deklarowane jako &lt;code&gt;val&lt;/code&gt; są niemutowalne, nie można zmienić ich wartości (odpowiadają javowej deklaracji &lt;code&gt;final&lt;/code&gt;). Z kolei deklaracja &lt;code&gt;var&lt;/code&gt; oznacza zmienne mutowalne, mogące zmienić swoją wartość.&lt;/p&gt;


	&lt;p&gt;Kod pisany funkcyjnie, może być znacznie krótszy, prostszy i tym samym mniej podatny na błędy. Zobaczmy, jak bardzo można zredukować w Scali kod napisany w stylu imperatywnym do funkcyjnego (przykład z książki &amp;#8220;Programming in Scala&amp;#8221;)&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
def printArgs(args: Array[String]): Unit = { 
  var i = 0 
  while (i &amp;lt; args.length) { 
    println(args(i)) 
    i += 1 
  } 
}
&lt;/pre&gt;

	&lt;p&gt;Pozbywamy się zmiennej var:&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
def printArgs(args: Array[String]): Unit = { 
  for (arg &amp;lt;- args) 
    println(arg) 
} 
&lt;/pre&gt;

	&lt;p&gt;To samo, inaczej wyrażone:&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
def printArgs(args: Array[String]): Unit = { 
  args.foreach(println) 
} 
&lt;/pre&gt;

	&lt;p&gt;Metoda nie jest jeszcze &amp;#8220;czysto&amp;#8221; funkcyjna bo posiada efekt uboczny w postaci drukowania wartości w funkcji &lt;code&gt;println&lt;/code&gt;. Pozbywamy się więc i jej.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
def formatArgs(args: Array[String]) = args.mkString("\n") 
&lt;/pre&gt;

	&lt;p&gt;Wywołanie:&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
println(formatArgs(args))
&lt;/pre&gt;

	&lt;h3&gt;Warunki zwracające wynik&lt;/h3&gt;


	&lt;p&gt;W Scali &lt;strong&gt;warunki logiczne także zwracają wartość&lt;/strong&gt;. Weźmy na przykład kwestię operatora trynarnego. W wielu językach można spotkać (odziedziczoną po C) następującą składnię:&lt;/p&gt;


&lt;pre class="brush:cpp"&gt;                          
wynik = warunek ? wyrazenie1 : wyrazenie2
&lt;/pre&gt;

	&lt;p&gt;Przez wiele lat w Pythonie trzeba było pisać w taki sposób:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;                          
if warunek:
    wynik = wyrazenie1
else:
    wynik = wyrazenie2
&lt;/pre&gt;

	&lt;p&gt;Pod naciskiem społeczności, Guido van Rossum dodał w końcu odpowiednik takiej konstrukcji i teraz można pisać tak:&lt;/p&gt;


&lt;pre class="brush:ruby"&gt;                          
wynik = wyrazenie1 if warunek else wyrazenie2
&lt;/pre&gt;

	&lt;p&gt;Tymczasem w Scali taki problem jest zupełnie sztuczny. Skoro warunek zwraca wynik, to nie trzeba wymyślać żadnej nowej składni naśladującej język C. Wystarczy po prostu napisać:&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
val wynik = if (warunek) wyrazenie1 else wyrazenie2
&lt;/pre&gt;

	&lt;p&gt;Ogólnie, cała Scala promuje podejście funkcyjne, ale nie zmusza do niego. Scala nie stosuje oddzielnych nazw dla wersji mutowalnej i niemutowalnej. Dzięki temu unika się niepotrzebnego refactoringu kodu w wypadku potrzeby zmiany jednej wersji na drugą.&lt;/p&gt;


	&lt;p&gt;&lt;img src="/images/articles/scala-lang.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Domyślnie typy są niemutowalne.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
scala&amp;gt; val x = Map[Int, String]() 
# =&amp;gt; x: scala.collection.immutable.Map[Int,String] = Map()
&lt;/pre&gt;

	&lt;p&gt;Aby mieć tym mutowalny, trzeba to jawnie wskazać.&lt;/p&gt;


&lt;pre class="brush:scala"&gt;                          
scala&amp;gt; import scala.collection.mutable.Map
scala&amp;gt; val x = Map[Int, String]()         
# =&amp;gt; x: scala.collection.mutable.Map[Int,String] = Map()
&lt;/pre&gt;

	&lt;h2&gt;Lift &amp;#8211; komponentowy framework w Scali&lt;/h2&gt;


	&lt;p&gt;Mówiąc o Scali nie sposób nie wspomnieć o świetnym frameworku webowym jakim jest &lt;a href="http://liftweb.net/"&gt;Lift&lt;/a&gt;. Framework ten inspirowany jest różnymi frameworkami (głównie &lt;a href="http://wicket.apache.org/"&gt;Wicket&amp;#8217;em&lt;/a&gt; ale też  Django, Rails czy smalltalkowym Seaside). Lift jest przede wszystkim frameworkiem &lt;strong&gt;komponentowym&lt;/strong&gt; (odcina się tu od klasycznego modelu &lt;span class="caps"&gt;MVC&lt;/span&gt; promowanego przez Rails). Podejście komponentowe ma przewagę nad &lt;span class="caps"&gt;MVC&lt;/span&gt;, dużo lepiej się nadaje do złożonych aplikacji (innym przykładem dobrego podejścia komponentowego jest pythonowy &lt;span class="caps"&gt;CMS&lt;/span&gt; &amp;#8211; &lt;a href="http://plone.org"&gt;Plone&lt;/a&gt;.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://github.com/tjweir/liftbook/tree"&gt;Lift Book&lt;/a&gt; &amp;#8211; darmowa, dostępna online (najnowsza wersja &lt;span class="caps"&gt;PDF&lt;/span&gt; jest na dole strony: &lt;a href="http://groups.google.com/group/the-lift-book"&gt;http://groups.google.com/group/the-lift-book&lt;/a&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.apress.com/book/view/1430224215"&gt;Exploring Lift: Scala-based Web Framework&lt;/a&gt; &amp;#8211; książka (dostępna jeszcze w wersji roboczej)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.infoq.com/interviews/Lift-Scala-David-Pollak"&gt;David Pollak On Lift Framework and Scala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.infoq.com/news/2008/02/integrating-flex-blazeds-scala"&gt;Derek Wischusen on Integrating Flex, BlazeDS and Scala/Lift&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Inne frameworki:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://code.google.com/p/sweetscala/"&gt;SweetScala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt; &lt;a href="http://github.com/alandipert/step/tree/master"&gt;Step&lt;/a&gt; &amp;#8211; wzorowany na &lt;a href="http://www.sinatrarb.com/"&gt;Sinatrze&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://code.google.com/p/sweetscala/"&gt;SweetScala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://github.com/pk11/pinky"&gt;Pinky&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://code.google.com/p/webflavor/"&gt;Webflavor&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Podsumowując.&lt;/h2&gt;


	&lt;p&gt;Scala to nowoczesny język będący hybrydą pure &lt;span class="caps"&gt;OOP&lt;/span&gt; i FP, statycznie typowany ale z inteligentną inferencją typów, o bardzo elastycznej składni i kompilowana do bytecodu &lt;span class="caps"&gt;JVM&lt;/span&gt;. Dzięki zaawansowanej inferencji typów i implicit conversions nie odczuwa się narzutu związanego z faktem że Scala jest statycznie typowana (a dostaje zalety ściślejszej kontroli kodu). Scala nie ma operatorów, operatory są zwykłymi metodami definiowanymi w bibliotekach.&lt;/p&gt;


	&lt;p&gt;Jednak tym co jest największym atutem Scali to jej &lt;strong&gt;minimalizm składniowy&lt;/strong&gt;. Scala umożliwia &lt;strong&gt;tworzenie nowych typów i struktur językowych bez konieczności zmian w samej zasadniczej składni języka&lt;/strong&gt;. To oznacza, źe podobnie jak Lisp, Scala nie ma praktycznie żadnych ograniczeń w rozwoju. Tym samym Scala jest w stanie przetrwać różne tendencje i upodobania składniowe i &amp;#8220;przeskalować&amp;#8221; się do nowych potrzeb.&lt;/p&gt;


	&lt;p&gt;Scalę używa już gdzieś parę banków w UK. Na Scalę &lt;a href="http://gojko.net/2009/03/16/qcon-london-2009-upgrading-twitter-without-service-disruptions/"&gt;niedawno przeszedł Twitter&lt;/a&gt;, ma wkrótce przejść też &lt;a href="http://github.com"&gt;Github&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Linki&lt;/h2&gt;


	&lt;ul&gt;
	&lt;li&gt; &lt;a href="http://www.scala-lang.org/"&gt;&lt;strong&gt;Scala&lt;/strong&gt; &amp;#8211; strona domowa&lt;/a&gt;          &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.artima.com/scalazine"&gt;&lt;strong&gt;Scalizine (a magazine for the Scala programming communitty)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.erudis.pl/pl/node/154"&gt;Podstawy język Scala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.infoq.com/news/2008/03/liftweb"&gt;David Pollak on lift and Scala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://stuq.nl/weblog/2008-11-24/scala-basics-what-is-scala"&gt;Scala basics: What is Scala?&lt;/a&gt;  &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://stuq.nl/weblog/2009-02-04/download-the-basic-and-wicket-scala-talk-materials"&gt;Basic and Wicket Scala talk materials&lt;/a&gt;                                                                                                                &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.artima.com/scalazine/articles/steps.html"&gt;First Steps to Scala&lt;/a&gt;         &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blog.jaoo.dk/2009/03/09/an-introduction-to-the-scala-programming-language-by-bill-venners/"&gt;An introduction to the Scala programming language&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://scala.sygneca.com/"&gt;Scala Wiki&lt;/a&gt;  &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.nabble.com/Scala-Programming-Language-f20934.html" title="forum"&gt;Scala Programming Language&lt;/a&gt;   &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees"&gt;Scala for Java Refugees&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blogs.sun.com/sundararajan/entry/scala_for_java_programmers"&gt;Scala for Java programmers&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://wiki.netbeans.org/Scala"&gt;Scala Plugins for NetBeans&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blogtrader.net/dcaoyuan/entry/scala_netbeans_maven_and_yes"&gt;Scala, NetBeans, Maven, and yes, Lift now&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.parleys.com/display/PARLEYS/Home#talk=27131945;slide=1;title=The%20Feel%20Of%20Scala"&gt;The Feel of Scala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://scala-blogs.org/"&gt;Agregator blogów o Scali&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://groups.google.com/group/scala-melb/web/videos-and-podcasts-about-scala?pli=1"&gt;Online Books, Videos &amp;#38; Podcasts about Scala&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Kanały &lt;span class="caps"&gt;IRC&lt;/span&gt;: &lt;a href="irc://irc.eu.freenode.net/scala"&gt;#scala&lt;/a&gt;, &lt;a href="irc://irc.eu.freenode.net/scala.pl"&gt;#scala.pl&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/01rXrI6xelE&amp;#38;hl=pl&amp;#38;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/01rXrI6xelE&amp;#38;hl=pl&amp;#38;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;object width="474" height="443"&gt;&lt;param name="movie" value="http://www.parleys.com/download/attachments/5443/parleysshare.swf?pageId=27131945"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="pageId" value="27131945"&gt;&lt;/param&gt;&lt;embed src="http://www.parleys.com/download/attachments/5443/parleysshare.swf?pageId=27131945" type="application/x-shockwave-flash" allowfullscreen="true" width="474" height="443"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=SGsc67svmiI:O8ryVGwld6s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=SGsc67svmiI:O8ryVGwld6s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=SGsc67svmiI:O8ryVGwld6s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=SGsc67svmiI:O8ryVGwld6s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 28 Mar 2009 07:17:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:dd9235ca-5dc2-4833-8da7-813184820a77</guid>
      <comments>http://blog.zabiello.com/2009/03/28/scala-lang#comments</comments>
      <category>scala</category>
      <category>java</category>
      <category>jruby</category>
      <category>ruby</category>
      <category>clojure</category>
      <category>lisp</category>
      <category>fp</category>
      <category>oop</category>
      <category>django</category>
      <category>rails</category>
      <category>wicket</category>
      <category>python</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/SGsc67svmiI/scala-lang</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/03/28/scala-lang</feedburner:origLink></item>
    <item>
      <title>Maglev - w tym roku?</title>
      <description>&lt;p&gt;Po &lt;a href="http://blog.zabiello.com/2008/06/14/maglev"&gt;początkowym szumie&lt;/a&gt; wokół Magleva, sprawa na jakiś czas przycichła i wiele osób powątpiewało czy jego twórcom uda się spełnić to co zapowiadali. Gdyby im się udało, Ruby uzyskałby fantastyczną platformę. Dojrzałą i szybką (rozwijana od ponad 20 lat i sprawdzoną w zastosowaniach komercyjnych) wirtualną maszynę Smalltalka  z wbudowanym mechanizmem wydajnej, przezroczystej, transakcyjnej persistent memory (nie wiem jak to oddać po polsku, a każdym razie rozwiązanie wygodniejsze nawet od obiektowej bazy danych, coś w stylu javowej &lt;a href="http://www.terracotta.org/"&gt;Terracoty&lt;/a&gt;). Aktualnie kod Maglev&amp;#8217;a jest cały czas w fazie alpha, ale na drugi kwartał roku 2009 zapowiada jest już &lt;a href="http://maglev.gemstone.com/status/index.html"&gt;wersja beta&lt;/a&gt;. To, co cieszy to rosnąca, &lt;a href="http://maglev.gemstone.com/status/rubyspecs/MagLev-Expectations-Passed.png"&gt;coraz większa zgodność&lt;/a&gt;  Maglev&amp;#8217;a z &lt;a href="http://rubyspec.org/"&gt;Ruby Specs&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=L7SMKyVISo8:JdoLfkJeHyY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=L7SMKyVISo8:JdoLfkJeHyY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=L7SMKyVISo8:JdoLfkJeHyY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=L7SMKyVISo8:JdoLfkJeHyY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 17 Mar 2009 04:09:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:4004a602-1d1a-442d-adfd-2b2e8cd4fef4</guid>
      <comments>http://blog.zabiello.com/2009/03/17/maglev-w-tym-roku#comments</comments>
      <category>maglev</category>
      <category>ruby</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/L7SMKyVISo8/maglev-w-tym-roku</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/03/17/maglev-w-tym-roku</feedburner:origLink></item>
    <item>
      <title>Rails 2.3</title>
      <description>&lt;p&gt;W końcu się doczekaliśmy &lt;a href="http://weblog.rubyonrails.org/2009/3/16/rails-2-3-templates-engines-rack-metal-much-more"&gt;finalnej wersji Rails 2.3&lt;/a&gt; (oznaczona jest jako wersja &lt;a href="http://github.com/rails/rails/tree/v2.3.2;"&gt;2.3.2&lt;/a&gt; użytkownicy Passengera muszą sobie zrobić aktualizację &lt;a href="http://blog.phusion.nl/2009/03/13/phusion-passenger-212-final-released/"&gt;do wersji 2.1.2&lt;/a&gt;). Cieszy może wsparcie do Rack&amp;#8217;a i &lt;a href="http://guides.rubyonrails.org/2_3_release_notes.html"&gt;liczne usprawnienia frameworka&lt;/a&gt;, ale tak naprawdę to czekam raczej na następną wersję, jaką ma być Rails 3.0 (aka Merb 2.0). Ponoć na najbliższej konferencji Railsconf 2009 ma być jakaś wersja beta &lt;a href="http://github.com/rails/rails/tree/3-0-unstable"&gt;kodu źródłowego&lt;/a&gt; (w każdym razie &lt;a href="http://en.oreilly.com/rails2009/public/schedule/grid/2009-05-06"&gt;6 maja przewidziane&lt;/a&gt; są jakieś prezentacje na temat Rails 3). Mam nadzieję że stabilna wersja Rails 3 pojawi się szybko i nie będzie rozczarowaniem dla tych, co wcześniej cenili sobie prostotę i elastyczność &lt;a href="http://merbivore.com/"&gt;Merba&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=-oM18lkXV9s:tATfsKQKgpg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=-oM18lkXV9s:tATfsKQKgpg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=-oM18lkXV9s:tATfsKQKgpg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=-oM18lkXV9s:tATfsKQKgpg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 17 Mar 2009 03:48:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:fa60fdee-8681-4a45-a3f8-618a020df6b0</guid>
      <comments>http://blog.zabiello.com/2009/03/17/rails-2-3#comments</comments>
      <category>rails</category>
      <category>ruby</category>
      <category>merb</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/-oM18lkXV9s/rails-2-3</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/03/17/rails-2-3</feedburner:origLink></item>
    <item>
      <title>Dlaczego iWork'09?</title>
      <description>&lt;p&gt;Jakiś czas temu próbowałem skontaktować się z twórcami &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt; co do możliwości udostępnienia softu umożliwiającego wstawienie do sieci książki z mechanizmem zbierania komentarzy od internautów. W ten sposób dostępna jest &lt;a href="http://www.djangobook.com/"&gt;Django Book&lt;/a&gt;. Niestety nigdy nie doczekałem się jakiejkolwiek odpowiedzi. Może to i dobrze, bo jest lepsze rozwiązanie&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Przypadkiem dziś odkryłem, że wydany przez Apple pakiet &lt;a href="http://www.apple.com/pl/iwork/"&gt;iWork&amp;#8217;09&lt;/a&gt; (mający być do pewnego stopnia konkurencją dla microsoftowego pakietu Office), poza całkiem niezłym procesorem tekstu Pages, dodał &lt;a href="http://www.apple.com/pl/iwork/iwork-dot-com/"&gt;bardzo dobrą usługę&lt;/a&gt; umożliwiającą udostępnianie projektów dowolnym, zaproszonym osobom. Apple, w swoim stylu, zrobił to bardzo ładnie i prosto. Można w banalnie łatwy sposób udostępnić książkę online tylko do odczytu, z możliwością komentowania dowolnego jej fragmentu lub z możliwością załadowania jej treści w formacie iWork, &lt;span class="caps"&gt;PDF&lt;/span&gt; lub MS Word. O ile wcześniej raczej nie brałem pod uwagę pakietu iWork, to teraz, z nowym iWork&amp;#8217;09 i sieciową usługą iwork.com wszystko uległo zmianie i oczywiście z miejsca zamówiłem iWork&amp;#8217;09. :)&lt;/p&gt;


	&lt;p&gt;Tak swoją drogą, ci, co tak krytykują iPhone&amp;#8217;a lub Macintoshe, jednej rzeczy nie rozumieją &amp;#8211; siłą produktów Apple&amp;#8217;a jest nie tylko ich duża prostota i intuicja obsługi, ale świetna infrastruktura Apple&amp;#8217;a integrująca je wszystkie razem. iTunes, iPhone, AppStore, darmowy i doskonały XCode 3.x do tworzenia softu, mac.com aka me.com synchronizującym komputery, kalendarze, kontakty, zakładki  przeglądarki Safari czy iPhone&amp;#8217;a. I teraz iWork&amp;#8217;09, zintegrowany z iwork.com&amp;#8230; Te wszystkie produkty po prostu genialnie ze sobą współpracują.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=iKwBGIwEGD0:uN3C-usM3A8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=iKwBGIwEGD0:uN3C-usM3A8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=iKwBGIwEGD0:uN3C-usM3A8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=iKwBGIwEGD0:uN3C-usM3A8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Thu, 26 Feb 2009 02:42:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:14dd0e4e-1097-4603-870f-371ea0f380ee</guid>
      <comments>http://blog.zabiello.com/2009/02/26/dlaczego-iwork09#comments</comments>
      <category>apple</category>
      <category>osx</category>
      <category>edytory</category>
      <category>django</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/iKwBGIwEGD0/dlaczego-iwork09</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/02/26/dlaczego-iwork09</feedburner:origLink></item>
    <item>
      <title>Debugowanie Merba w Netbeans</title>
      <description>&lt;p&gt;Po paru godzinach walki z Netbeans, przeglądaniem źródeł, przekopywaniem list dyskusyjnych i zgłoszonym &lt;a href="http://merb.lighthouseapp.com/projects/7433/tickets/1194-broken-debugging-of-merb-in-netbeans"&gt;tickecie&lt;/a&gt;, w końcu udało mi się zmusić Merba do pracy z Netbeans. Mam też dobrą wiadomość, że Netbeans 7 (wersja trunk) &lt;a href="http://forums.netbeans.org/post-22215.html"&gt;w przyszłym tygodniu ma mieć dodane wsparcie do Merba&lt;/a&gt; (tworzenie projektów, debugowanie itp). Dla tych, co chcieliby już teraz móc debugować swoje projekty Merba w graficznym, ślicznym debugerze Netbeans, podaję instrukcję obsługi. :)&lt;/p&gt;


	&lt;p&gt;Krok 1: trzeba ściagnąć najnowszą wersję trunk ze strony &lt;a href="http://bits.netbeans.org/download/trunk/nightly/latest/"&gt;http://bits.netbeans.org/download/trunk/nightly/latest/&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Od niedawna Netbeans posiada możliwość podpięcia swojego debugera do dowolnego kodu Ruby&amp;#8217;ego za pomocą tzw. remote debugging (zobacz wpis w blogu Martin Krauskopfa z 11 listopada 2008 &lt;a href="http://blogs.sun.com/martink/category/Ruby"&gt;Remote Debugging: explore Ruby code easily&lt;/a&gt;). Właśnie tej metody użyjemy aby zmusić Netbeansa do pracy z Merbem.&lt;/p&gt;


	&lt;p&gt;Krok 2: w swoim pliku &lt;code&gt;config/init.rb&lt;/code&gt; musisz ustawić opcję wymuszającą uruchamianie Merba tak jak Rails (trzeba wyłączyć forkowanie ładowania klas):&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;use&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:fork_for_class_load&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;
  &lt;span class="comment"&gt;# ... reszta ustawień&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Krok 3: musisz mieć zainstalowany gem &amp;#8216;ruby-debug-ide&amp;#8217; i uruchomić zdalny nasłuch debuggera:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;sudo gem install ruby-debug-ide

rdebug-ide -p 7000 `which merb`&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Nie ma znaczenia jaki port ustawisz dla projektu Merba z poziomu konfiguracji projektu (prawy click na nazwę projekty -&amp;gt; Properties). Jeśli chcesz uruchomić Merba na porcie 3000 to po prostu odpal nasłuch debuggera przez podanie dodatkowych opcji:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;rdebug-ide -p 7000 `which merb` -p 3000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Krok 4: Ustaw sobie w kodzie breakpoint, następnie podepnij debugger &amp;#8220;menu -&amp;gt; Debug -&amp;gt; Attach Debugger&amp;#8230;&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&lt;img src="/images/articles/merb-debug1.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Nie używaj opcji &amp;#8220;menu -&amp;gt; Debug -&amp;gt; Debug Main Project&amp;#8221;. Nie ma ona tu znaczenia. Debugowanie odpala operacja przypisania debuggera.&lt;/p&gt;


	&lt;p&gt;&lt;img src="/images/articles/merb-debug2.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Krok 5: Otwórz przeglądarke i uruchom projekt (http://localhost:4000)&lt;/p&gt;


	&lt;p&gt;Przełącz się na Netbeans. To wszystko.&lt;/p&gt;


	&lt;p&gt;Wbrew temu co &lt;a href="http://wiki.jruby.org/wiki/Merb_debugging_with_Netbeans_6.5"&gt;piszą na Wiki&lt;/a&gt; do JRuby, nie ma potrzeby tworzenia pliku &lt;code&gt;script/server&lt;/code&gt; zawierającego skopiowaną treść skryptu &lt;code&gt;merb&lt;/code&gt;. Użytkownicy Windozy, którzy mają dostępu do komendy &lt;code&gt;which&lt;/code&gt;, zamiast tego niech wpiszą po prostu &lt;code&gt;merb&lt;/code&gt;, albo pełną ścieżkę do skryptu &lt;code&gt;merb&lt;/code&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=XWZ8BCv1uO4:WooQjeCDqNo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=XWZ8BCv1uO4:WooQjeCDqNo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?i=XWZ8BCv1uO4:WooQjeCDqNo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~ff/hipertracker?a=XWZ8BCv1uO4:WooQjeCDqNo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/hipertracker?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Thu, 22 Jan 2009 04:30:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:3268addf-00ad-4fb8-b1e5-eefc81f57742</guid>
      <comments>http://blog.zabiello.com/2009/01/22/debugowanie-merba-w-netbeans#comments</comments>
      <category>ruby</category>
      <category>merb</category>
      <category>netbeans</category>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/XWZ8BCv1uO4/debugowanie-merba-w-netbeans</link>
    <feedburner:origLink>http://blog.zabiello.com/2009/01/22/debugowanie-merba-w-netbeans</feedburner:origLink></item>
  </channel>
</rss>
