Ruby

Jeg rotet meg litt bort i programmeringspråket Ruby for noen år siden, og har lovet meg selv å komme tilbake til det nå når IronRuby blir modent på .NET plattformen. Her kan du lese det jeg har skevet om dette..

En minimal http-server i Ruby

I denne oppfølgingsposten til En minimal http-server i .Net viser jeg hvordan jeg raskt kan sette opp en tilsvarende løsning i Ruby. Jeg skal altså implementere en tjeneste som lytter på http, og som responderer på ulike argumenter. Løsningen skal være enkel å utvide med flere “respondere” – det skal ikke være nødvendig å editere eksisterende kode for å håndtere nye typer forespørsler (se forrige post om du vil vite mer om oppgaven).

Ruby shipper med mange, nyttige moduler – blant annet en søt, liten tjeneste som heter WEBrick, som kan brukes ganske likt som .Net’s HttpListener egentlig. I følgende program setter jeg opp en server til å lytte på port 8081:

   1 require ‘webrick’

   2 include WEBrick

   3 

   4 #DSL method for defining responders

   5 def respond_to config

   6     key = config[:key]

   7     $server.mount_proc(key) do |request, response|

   8         response.body = yield request.query.to_s

   9     end

   10 end

   11 

   12 def load_responders

   13     responder_definitions = Dir.glob(“*.responder”)

   14     responder_definitions.each { |d| load d }

   15 end

   16 

   17 $server = HTTPServer.new( :Port => 8081 )

   18 load_responders

   19 trap(“INT”) { $server.shutdown }

   20 $server.start

Servicen opprettes i linje 17, og i neste linje kaller jeg en metode jeg har kalt load_responders. Den henter alle filer med .responder extension, og kjører innholdet. Responder-filene i sin tur benytter respond_to metoden definert fra linje 5 til å konfigurere WEBrick.

Sidenote: Jeg implementerte først en løsning med en SimpleHttpServer-klasse og en klasse for å representere respondere. Etter å ha tenkt meg litt om så jeg derimot at det bare ble en masse stafasje, og at koden ikke kommuniserte så veldig godt hva den gjorde. Enkelhet er et av de viktigste budene for smidige utviklere, og Ruby lar meg skrelle bort ganske mye. Så etter å ha slettet 30 linjer kode følte jeg meg mer komfortabel. Om du vil se en mere objektorientert løsning kan du ta en titt på Building a DSL in Ruby, part II fra bloggen Technology as if People Mattered, som var en viktig inspirasjonskilde til denne bloggposten.

Nedefor er responder-filen for add-tjenesten. Se forrige post for å se hvordan denne responderen ser ut i .net. Som du kanskje ser er dette rett og slett et kall til respond_to. Som argument til metoden sendes nøkkelen “/add”, som er det responderen skal håndtere (ref bruk av attributtet RespondTo i .Net-løsningen). Resten er en kodeblokk som tar som input argumentene fra requesten, og returnerer et svar. Denne kodeblokken brukes til å håndtere forespørselen (magien ligger i “yield” i linje 8 i programmet over).

   1 respond_to :key => “/add” do |arguments|

   2     sum = 0

   3     numbers = arguments.split(‘,’)

   4     numbers.each { |n| sum += n.to_i }

   5     “The answer is #{sum}”

   6 end

Koden i denne responderen er litt C#-ish, jeg har gjort nøyaktig det samme som jeg gjorde i C#-varianten, bare oversatt det til Ruby. For å gjøre den mere rubyesque benytte vi et par array-metoder som Ruby har arvet fra SmallTalk: map (som egentlig er en alias fro collect, men jeg liker map bedre) tar et array, kjører en gitt transformasjon på hvert element (i dette tilfellet eksplisit konvertering til integer), og returnerer et nytt array med resultatet. Dette føles nok ikke så  fremmed for .Net-utviklere lengre, nå som vi har vendt oss til Linq, som tilbyr samme funksjonalitet via Select-metoden.

Det andre trikset er metoden inject. Den kan brukes til å “samle informasjon” fra et array, i dette tilfellet summen av alle argumentene. Dermed kan spesifikasjonen av add-responderen modifiseres til å se slik ut:

   1 respond_to :key => “/add” do |arguments|

   2     numbers = arguments.split(‘,’).map {|arg| arg.to_i}

   3     “The answer is #{numbers.inject {|x,n| x+n }}”

   4 end

Resultatet er altså at jeg på 20 linjer har satt opp en dynamisk webserver som jeg kan utvide ved å legge til flere .responder-filer. Definisjonen av hver responder er veldig konsis og grei, og står på ingen måte tilbake for .Net-løsningen. I Ruby har jeg ikke behøvd å definere interface for respondere, og lastingen av dem – som er basert på fil-extension i stedet for refleksion og attributter – er mye enklere. Når du tar med i betraktning at jeg ikke engang behøver å kompilere Ruby-løsningen, så er det ikke vanskelig for meg å foretrekke denne når jeg får behov for å raskt sette opp web-tjenester av ulik art f.eks. for å simulere tjenester jeg skal integrere mot.

Sinatra entrer scenen

frank_sinatra Å bruke WEBrick til dette her er ganske “low level” (på samme måte som HttpListener var det). I .NET-verden har vi rammeverk for webutvikling på et høyere nivå som blant andre WebForms, ASP.NET MVC, FubuMVC og MonoRail (det er egentlig alle jeg vet om). Ruby har også dette; det desidert mest kjente er Ruby on Rails, som gjør deg ekstremt produktiv så sant du er villig til å følge Rails konvensjoner og måter å gjøre ting på. Ramaze er et rammeverk med mye større frihet, hvor man kan velge mellom et hav av moduler og måter å gjøre ting på. Begge disse baserer seg i hovedsak på Model-View-Controller paradigmet.

Sinatra er et tredje ruby-biblotek som er ganske nyttig til å utvikle mindre websider og tjenester. Det minner mye om det jeg har gjort i denne artikkelen, og ved å bruke Sinatra kan jeg forenkle tjenesten min ganske mye (som om den ikke var enkel nok allerede).

Sinatra-versjonen av selve tjenesten min ser slik ut:

   1 require ‘sinatra’

   2 Dir.glob(“*.responder”).each { |d| load d }

Ved å inkludere sinatra-bibloteket startes automatisk en webserver. Det eneste jeg da trenger er å dynamisk laste alle responder-filene. Jeg har slått sammen linje 13 og 14 fra det orginale skriptet, og står dermed igjen med én require og én kodelinje.

Responder-filen ser nesten ut som tidligere, men kallet til respond_to, som jeg selv definerte, har vi nå et kall til sinatras get-metode (‘get’ som i REST-metoden get):

   1 get “/add” do

   2     numbers = params.to_s.split(‘,’).map {|arg| arg.to_i}

   3     “The answer is #{numbers.inject {|x,n| x+n }}”

   4 end

Dermed har jeg gått fra 24 til 6 linjer. Det er latterlig lite!

Og den tilsvarende C#-løsningen fra forrige post var på over 170 linjer. Det finnes selvfølgelig mere optimale løsninger, men jeg har vært en C#-utvikler i åtte år, og 170 liner ++ var det jeg havnet på. Jeg har vært Ruby-utvikler på hobbybasis i et par måneder, og landet på 6 linjer. Det MÅ jo si noe om Ruby og dynamisk programmering!

Dagens sitat via SMS

Jeg fortsetter å rote med Ruby, og deler villig med alle som har lyst til å lære. Denne gangen har jeg laget et lite skript som henter et daglig oppdatert visdomsord fra nettet, og sender det til en distribusjonsliste på SMS via PSWinCom‘s SMS Gateway. Programmet illustrerer hvor enkelt det er å hente og parse en RSS-feed, bruk av konfigurasjonsfiler i YAML-format, og sending av XML til en server over TCP (ett av PSWinCom’s mange integrasjonsgrensesnitt).

ruby_quote

Det komplette programmet er listet ut nedenfor. La meg kjapt gå gjennom de ulike delene:

Metoden get_quote (linje 5 til 11) tar inn URL’en til en RSS-feed fra BrainyQuote som gir meg ett nytt sitat hver dag. Jeg åpner en connection mot adressen, og parser den med RSS-parser som er en del av Ruby’s grunninstallasjon. Jeg plukker ut det første elementet, slår sammen beskrivelsen (selve sitatet) og tittelen (hvem sitatet stammer fra), og returnerer dette (siste statement i en ruby-metode returneres automatisk).

Metoden get_sms_xml (linje 13 til 28) tar inn nødvendige parametre og bygger opp XML’en jeg skal sende til SMS Gateway’en. Dokumentasjon av dette formatet er definert i denne pdf’en. I metoden bruker jeg noe som kalles for et Here-Document – en “tradisjonsrik” måte å definere strenger over flere linjer på som du også finner i PHP, Perl, Python, Unix shells, Windows Powershell etc.

Metoden send_sms (linje 30 til 34) åpner en TCP socket på en gitt adresse og port, sender XML’en, og avslutter. Det er alt som skal til for å sende SMS gjennom systemet vårt.., så sant du har en konto vel-å-merke.

QuoteSMS.rb:
1 require rss
2 require open-uri
3 require yaml
4
5 def get_quote uri
6   open(uri) do |con|
7     rss = RSS::Parser.parse(con.read, false)
8     quote = rss.items.first
9     #{quote.description} -#{quote.title}
10   end
11 end
12
13 def get_sms_xml gw, receivers_xml, text
14 <<EOF
15 <?xml version=”1.0″?>
16 <SESSION>
17 <CLIENT>#{gw[:client]}</CLIENT>
18 <PW>#{gw[:password]}</PW>
19 <MSGLST>
20 <MSG>
21 <TEXT>#{text}</TEXT>
22 #{receivers_xml}
23 <SND>#{gw[:sender]}</SND>
24 </MSG>
25 </MSGLST>
26 </SESSION>
27 EOF
28 end
29
30 def send_sms gw, xml
31   session = TCPSocket.new(gw[:host], gw[:port])
32   session.write xml
33   session.close
34 end
35
36 settings = YAML.load_file(settings.yml)
37
38 quote = get_quote settings[:quote_uri]
39 xml = get_sms_xml(settings[:gateway],
40                   settings[:receivers].map {|r| <RCV>#{r}</RCV>},
41                   quote)
42 send_sms settings[:gateway], xml

I linje 36 leser jeg inn konfigurasjonsdata (mer om dette om litt). Deretter er det bare å kalle de tre metodene, og hey-presto(!) så er jobben gjort. Nå kan jeg for eksempel sette opp en scheduled task til å kjøre dette programmet hver dag, og “spamme” mine venner med gode sitater på telefonen.

Legg merke til linje 40 som konverterer en array av telefonnumre til en XML streng array vha. metoden map. Dette tilsvarer å bruke Select-metoden i Linq i .NET:

    1 var list = new long[] { 4700000001, 4700000002, 4700000003 };

    2  IEnumerable<String> xml = list.Select(phonenumber

    3      => string.Format(“<RCV>{0}</RCV>”, phonenumber));

Det at jeg kan skyte inn arrayet i en annen streng som i linje 22, og at elementene da “flates ut” til én streng er minst like kult. Tilsvarende får du ikke til i .NET uten å eventuelt endre definisjonen av ToString() for enumerasjonen det gjelder. Let’s not go there…

YAML Ain’t Markup Language

Som sagt har jeg valgt å bruke YAML som format på konfigurasjonsfilen til dette programmet. YAML er et serialiseringsformat som er tilgjengelig for mange programmeringsspråk. Fordelen er at det er mye mere lesbart og editeringsvennlig enn XML, som har vært det mest populære formatet i noen år nå. YAML har mer til felles med JSON.., I praksis er JSON faktisk et subset av YAML. 

settings.yml:
1
2 :gateway: 
3   :port: 9876
4   :client: demoAccount
5   :password: somePassw0rd
6   :host: 127.0.0.1
7   :sender: RubyQuote
8 :quote_uri: http://feeds.feedburner.com/brainyquote/QUOTEBR
9 :receivers:
10   - 4790000001
11   - 4790000002
12   - 4790000003

Denne settingsfilen definerer en Hash (el. dictionary om du vil) med tre nøkler med tilhørende verdier. Som nøkler har jeg brukt symboler – de tingen som begynner med kolon i Ruby – men strenger eller andre datatyper hadde fungert like fint. Nøkkelen :gateway har en ny Hash som verdi, som definerer settingene for å kontakte og bruke PSWinCom gatewayen. :sender gir for eksempel navnet jeg har valgt på avsenderen (se bildet av mobilen tidligere i artikkelen). Og nei, dette er ikke reelle brukernavn og passord…

Nøkkelen :quote_uri refererer til en streng som inneholder RSS-adressen. :receivers refererer til en array med telefonnummer. Når denne filen parses får jeg tilbake en Hash med alle disse verdiene i korrekte typer.

YAML er heller ikke begrenset til primitive typer som streng, arrays osv – man kan også serialisere og deserialisere Ruby-objekter man selv definerer, uten at det ser spesielt mer komplisert ut enn filen over. Faktisk trenger det egentlig ikke eksistere noen definisjon av objektene i programmet i det hele tatt – YAML-parseren vil konstruere nye typer om det trengs basert på det som er definert i YAML-filen. Ruby er jo tross alt et dynamisk språk. Ganske fiffig faktisk!

Konklusjon

Du har nå sett hvor enkelt det er å hente og parse en RSS feed. Du har også sett hvor smertefritt det er å sende SMS vha litt XML og PSWinCom’s SMS Gateway. Og hvis ikke du fikk lyst til å bytte ut alle XML-konfigurasjonsfilene dine med YAML så har jeg kanskje forklart litt dårlig hvor kult det er.

Objektorienteringen er kanskje ikke så mye å skryte av, men for et program på 42 linjer ville det bare ha vært i veien. Håper dette inspirerte!

Se også: Send SMS med SOAP for hvordan du enkelt kan bruke PSWinCom’s SOAP-grensesnitt for sending i .NET.

State Machine DSL revamp

I min forrige blogpost gikk jeg gjennom hvordan jeg laget en enkel tilstandsmaskin i Ruby. Jeg har tenkt litt mer på den, og her kommer en liten forbedring..

Orginalt la jeg til rette for to ulike måter å konfigurere tilstandsmaskinen på. Først lagde jeg en enkel add_transition metode som jeg kunne kalle slik som dette:

   9         @state_machine.add_transition(:locked, :coin, :unlocked) { @unlock_called = true }

Ulempen med denne er at den ikke kommuniserer så godt – god kode skrevet for mennesker bør kommunisere mer enn det der. Jeg lagde derfor et flytende grensesnitt, ala det jeg tidligere hadde laget i C#.

   72         @state_machine.configure do |sm|

   73             sm.given(:locked).when(:coin).then_set_state(:unlocked).and_run { @unlock_called = true }

   74             sm.given(:locked).when(:pass).then_set_state(:locked).and_run { @alarm_called = true }

   75             sm.given(:unlocked).when(:coin).then_set_state(:unlocked).and_run { @thank_you_called = true }

   76             sm.given(:unlocked).when(:pass).then_set_state(:locked).and_run { @lock_action_called = true }

   77         end

Etter å ha tenkt meg litt om har jeg kommet opp med et grensesnitt jeg liker bedre. Det ligner mer på andre ting jeg har sett i Ruby, og er på en form som Rubyister gjerne refererer til som DSL-metoder. Ved å bruke en Hash (dotnet’ere kan kalle dette Dictionary) som parameter kommuniserer koden enda bedre. Det blir litt mer tekst å skrive, men på den andre siden er det også mere fleksibelt (om man f.eks. vil legge til flere parametre). Det nye grensesnittet brukes på denne måten:

   137         @state_machine.transition :if_state_is => :locked,  

   138             :when_event => :coin, :then_set_state => :unlocked do

   139             @unlock_called = true

   140         end

   141         @state_machine.transition :if_state_is => :locked,  

   142             :when_event => :pass, :then_set_state => :locked do

   143             @alarm_called = true

   144         end

   145         @state_machine.transition :if_state_is => :unlocked,  

   146             :when_event => :coin, :then_set_state => :unlocked do

   147             @thank_you_called = true

   148         end

   149         @state_machine.transition :if_state_is => :unlocked,  

   150             :when_event => :pass, :then_set_state => :locked do

   151             @lock_action_called = true

   152         end

Mellom ‘do’ og ‘end’ putter man selvsagt all koden som skal trigges av tilstandsendringen – på samme måte som man kunne gjøre mellom { og } i de foregående eksemplene (dette er to ulike måter å gjøre det samme på i Ruby, hvor klammene normalt brukes når kodeblokken er på samme linje som metodekallet, og bare inneholder én statement.

Selve transition-metoden er enkel å implementere. Den plukker ut verdiene fra Hash’en og sender dem til den tidligere definerte add_transition-metoden.

   185 class GenericStateMachine #open class definition to add another dsl method

   186     def transition args, &and_run

   187         add_transition args[:if_state_is], args[:when_event], args[:then_set_state], &and_run

   188     end

   189 end

En Generisk State Machine i Ruby

Den siste tiden har jeg holdt på å lære meg Ruby, og det er en fantastisk opplevelse. Å lære et så elegant, dynamisk språk åpner dører som jeg ikke ante fantes. Underveis skriver jeg selvsagt endel kode, og tenkte det var på sin plass å dele litt av galskapen. Merk at det er en viss overgang å gå fra C# til Ruby, så hvis de som allerede behersker dette spåket har noe å utsette på koden min så er det forståelig – og kommmentarer mottas med glede.

For et halvt års tid siden blogget jeg hvordan jeg lagde en generisk state machine i C# basert på en overgangstabell. Jeg tenkte at det kunne være en fin øvelse å gjøre det samme i Ruby.

Jeg startet med å sette opp en testfixture som definerer tilstandsmaskinen og alle overgangene. I C#-løsningen brukte jeg 30 linjer på dette – i Ruby klarer jeg meg med 13 (en ganske typisk reduksjon i antall kodelinjer når man går fra et statisk typet språk til et som er dynamisk typet). Bortsett fra det har jeg beholdt samme fremgangsmåte som sist:

   1 require ‘test/unit’

   2 

   3 class GenericStateMachineTests < Test::Unit::TestCase

   4     def setup

   5         @unlock_called, @alarm_called, @thank_you_called, @lock_action_called = false

   6   

   7         @state_machine = GenericStateMachine.new :locked

   8       

   9         @state_machine.add_transition(:locked, :coin, :unlocked) { @unlock_called = true }

   10         @state_machine.add_transition(:locked, :pass, :locked) { @alarm_called = true }

   11         @state_machine.add_transition(:unlocked, :coin, :unlocked) { @thank_you_called = true }

   12         @state_machine.add_transition(:unlocked, :pass, :locked) { @lock_action_called = true }

   13     end

Jeg “kopierte” også testene fra C# løsningen:

   15     def test_initial_conditions

   16         assert_equal :locked, @state_machine.state

   17     end

   18     def test_coin_in_locked_state

   19         @state_machine.state = :locked

   20         @state_machine.handle_event :coin

   21         assert_transition :unlocked, @unlock_called

   22     end

   23     def test_coin_in_unlocked_state

   24         @state_machine.state = :unlocked

   25         @state_machine.handle_event :coin

   26         assert_transition :unlocked, @thank_you_called

   27     end

   28     def test_pass_in_locked_state

   29         @state_machine.state = :locked

   30         @state_machine.handle_event :pass

   31         assert_transition :locked, @alarm_called

   32     end

   33     def test_pass_in_unlocked_state

   34         @state_machine.state = :unlocked

   35         @state_machine.handle_event :pass

   36         assert_transition :locked, @lock_action_called

   37     end

   38   

   39     def assert_transition expected_state, indicator_should_be_true

   40         assert_equal expected_state, @state_machine.state

   41         assert indicator_should_be_true

   42     end

   43 end

Det burde ikke være så vanskelig å kjønne hva som skjer i de testene, selv om man ikke har vært borti Ruby før. I Ruby’s innebygde testrammeverk blir alle metoder i en testklasse (en klasse som arver fra Test::Unit::TestCase) som starter med “test” oppfattet som en test.

Og her følger implementasjonen jeg etter hvert kom frem til av GenericStateMachine. C#-varianten, som eksponerer det samme interfacet, var på ca  50 linjer, mens Ruby-klassen ender på 20. Ta en rask titt på koden, så kommer jeg med litt kommentarer og forklaringer etterpå..

   45 class GenericStateMachine

   46     Struct.new “Transition”, :start_state, :trigger, :end_state, :action

   47     attr_accessor :state

   48     def initialize initial_state

   49         @state = initial_state

   50         @transitions = []

   51     end

   52     def add_transition start_state, trigger, end_state, &action

   53         @transitions << Struct::Transition.new(start_state, trigger, end_state, action)

   54     end

   55     def handle_event event

   56         @transitions.each do |t|

   57             if t.start_state == @state and t.trigger == event

   58                 @state = t.end_state

   59                 t.action.call

   60                 break

   61             end

   62         end

   63     end

   64 end

Linje 46 illustrerer hvordan man veldig enkelt kan definere en klasse i Ruby som bare består av “properties” (i Ruby kaller vi properties for accessor methods). I linje 53 kan du se hvordan jeg oppretter instanser av denne klassen, og legger dem til et array.

På linje 47 deklareres tilstandsmaskinens eneste accessor (dvs property), som eksponerer tilstanden. Linje 48 til 51 er konstruktøren (eller gjør i alle fall samme nytten), hvor initiell tilstand settes, og en tom tabell med overganger opprettes.

Og på linje 55 begynner metoden som skal håndtere events. Jeg itererer over alle overgangene, og hvis start-tilstand og event er riktig så gjennomfører jeg overgangen ved å sette ny tilstand og kjøre kodeblokken (action) som er definert. Referer til linje 9 til 12 i test-oppsettet for å se hvordan overgangene ble definert.

Det fine med tilstandsmaskinen jeg lagde i C# var at den var generisk – på den måten at jeg kunne bruke ulike enums eller klasser til å definere både tilstander og events. Siden Ruby er dynamisk typet fungerer dette like bra i denne løsningen, og det helt uten at jeg har gjort noe spesielt for å få det til. I koden min bruker jeg Ruby-symboler (de merkelige tingene som begynner med kolon), men jeg kunne f.eks. brukt tall, strenger, konstanter, eller noen helt andre objekter.

Flytende konfigurering

Jeg lagde også et “flytende interface” (eller intern DSL om du vil) for tilstandsmaskinen min i C#, og tenkte jeg skulle forsøke det samme i Ruby. Her er jeg litt usikker på om jeg har gjort det “the Ruby way”, men jeg har brukt endel av det jeg har lært meg i det siste, og er foreløpig fornøyd med løsningen. Her er hvordan jeg har valgt å gjøre det flytende konfigureringen (erstatter linje 9 til 12 i test-oppsettet).

   72         @state_machine.configure do |sm|

   73             sm.given(:locked).when(:coin).then_set_state(:unlocked).and_run { @unlock_called = true }

   74             sm.given(:locked).when(:pass).then_set_state(:locked).and_run { @alarm_called = true }

   75             sm.given(:unlocked).when(:coin).then_set_state(:unlocked).and_run { @thank_you_called = true }

   76             sm.given(:unlocked).when(:pass).then_set_state(:locked).and_run { @lock_action_called = true }

   77         end

Jeg vet ærlig talt ikke om dette er bedre, men det lar seg i alle fall lese som en setning (kind of): Gitt tilstand LOCKED, når COIN, set tilstand UNLOCKED og kjør “unlocked_called = true”.

For å implementere muligheten for denne konfigurasjonen gjenåpner jeg klasse-definisjonen og legger til et sett med nye metoder; du kan nemlig se på alle klasser i Ruby som “partial”, og ved å spre definisjonen av GenericStateMachine til flere filer kan jeg f.eks. velge om jeg vil inkludere det flytende API’et eller ikke.

   110 class GenericStateMachine #open class definition to add fluent dsl

   111     def configure  

   112         yield self

   113     end

   114     def given start_state

   115         @temp = [start_state]

   116         self

   117     end

   118     def when event

   119         @temp << event

   120         self

   121     end

   122     def then_set_state end_state

   123         @temp << end_state

   124         self

   125     end

   126     def and_run &block      

   127         add_transition *@temp, &block

   128     end

   129 end

Det er litt vanskelig å forklare hvordan dette fungerer, men la meg forsøke: Metoden configure kjører blokken som er sendt til den (blokken er linje 73 til 76) med seg selv (self) som argument. Variabelen sm i 72-76 er derfor tilstandsmaskinen. De tre metodene starte_state, event og then_set_state tar bare vare på argumentet som sendes inn til dem, og returnerer self igjen, slik at metodekallene kan kjedes sammen. I and_run-metoden tar jeg imot det siste argumentet – en kodeblokk – og legger til en ny overgang ved å kalle den eksisterende metoden add_transition med de tre argumentene pluss kodeblokken.

Merk at dette grensesnittet forutsetter at det brukes riktig – her er det absolutt ingen feilhåndtering.

Jeg håper dette kan være med på å spre interessen for å lære seg flere programmeringsspråk, spesielt blant .Net-utviklerne, og vil fortsette å blogge ting og tang jeg finner på etterhvert som jeg bruker Ruby mer og mer.

Et usedvanlig år..

Da nærmer det seg slutten av et veldig spesielt år. 2009 var ikke bare det året jeg slanket meg 10 kilo.., for deretter å legge dem på meg igjen. Det var nemlig også det året jeg tok skikkelig tak i min egen karriære, og jobbet målrettet med å bli en mye bedre utvikler. Jeg byttet også jobb i 2009, jeg blogget ekstremt mye, og jeg ble med i NNUG-styret i Bergen. Og sist men ikke minst vil jeg alltid huske 2009 som det året jeg ble pappa til verdens søteste jente.

Her er noen tanker rundt året som har vært. Jeg er ganske stolt av hva jeg har gjort, så dette kan tendere mot selvskryt. Er du ikke fan av det får du surfe videre…

.Net ninja-initiativet

28. desember 2008 satte jeg meg selv et nyttårsforsett: Jeg skulle jobbe målrettet og strukturert med å utvikle mine ferdigheter som programmerer. Jeg hadde store forhåpninger, men ingen anelse om at det skulle forandre mitt forhold til faget mitt så mye som det har gjort. I løpet av året har jeg lest en rekke med fantastiske bøker, hørt på hundrevis av podcasts, sansynligvis kodet mer enn noensinne (både på jobb og fritid), og diskutert mer programmering med andre enn noen gang før. Jeg har fokusert mye på grunnleggende objektorientering, patterns og refakturering. Jeg har praktisert testdreven utvikling/design, tidvis parprogrammering, og lært meg å bruke mocking og Inversion-of-Control containers. Og jeg har utviklet min daglige bruk av C#, gjennom en dypere forståelse av ting som generics, linq og lambda.

Nå på slutten av året har jeg også tatt opp igjen Ruby. Jeg begynte så smått å lære meg dette programmeringspråket i 2006, men det ble for lite brukt, så da klarte jeg ikke holde kunnskapen ved like. Nå leser jeg The Ruby Way, og har flere småprosjekter på gang. Jeg tror tillegget av et dynamisk språk til “min portefølje” vil kunne gjøre meg til en enda bedre utvikler. Så det blir mer om Ruby her til neste år…

NNUG / Community

Som jeg allerede har nevnt inviterte Jon Arild meg med i NNUG-styret i starten av året, og i februar holdt jeg et foredrag om objektorienterte databaser (del 1 og del 2) som ble svært godt mottatt. Jeg har blitt en mere aktiv deltager i det norske .Net-miljøet, bl.a. gjennom bruk av twitter og gjennom bloggen min. Jeg har blogget MYE i år, et naturlig resultat av at jeg har lært så mye nytt, og jeg tror mine blogposter har vært inkludert i Microsofts nyhetsbev hele fire ganger nå.

NNUG-året i Bergen har forresten også vært helt eksepsjonelt; vi har blant annet hatt besøk av “kjendiser” som Jimmy Nilsson, Mary Poppendieck, Jeremy D. Miller, Greg Young, og sist men ikke minst Scott Hanselmann (introdusert av selveste Carl Franklin). MSDN Live i mars og september var også bra, og årets høydare var Norwegian Developers Conference i Oslo.

Farvel Contiki, hei PSWinCom

I sommer takket jeg farvel til CMA Contiki, og begynte som teamleder/seniorutvikler i telekom-selskapet PSWinCom. Det var en svært vanskelig avgjørelse å ta, men i ettertid er jeg veldig fornøyd med utfallet. I PSWinCom har jeg fått anledning til å innføre og praktisere mange av de smidige prinsippene som var vanskelig å gjennomføre i Contiki. Vi har et dyktig og motivert team som er villige til å lære nye ting.

Domenet vi jobber i har også gitt meg mange, nye utfordringer. Vi jobber med en ekte serviceorientert (SOA), event-drevet, asynkron arkitektur med høy throughput. Vi bruker mye windows-services, køer og parallellprosessering, som fører til mange problemer jeg aldri har måttet forholde meg til tidligere. For ikke å snakke om et utall integrasjonspunkter med protokoller av ulik art. Hva mer kan en utvikler ønske seg?

Og så ble jeg pappa..

Samme hvor mye jeg har fått til i løpet av året så er dette det mest fantastiske. Dette er en blog om programmering, så jeg skal ikke kjede dere for mye, og henviser derfor bare til en liten videosnutt (tidligere publisert på facebook):

Om 2010 blir bare halvparten så spennende som 2009 har vært så kommer det til å bli et fabelaktig år. Mitt nyttårsforsett denne gangen er rett og slett å fortsette som jeg gjør nå. Takk til alle som har fulgt utviklingen på bloggen min – jeg ønsker dere en riktig God Jul og et Godt Nytt År alle sammen!!!

WatiN

Jeremy D. Miller kan i dag informere om at det nå eksisterer en .net versjon av watir (uttales “water”), nemlig watin (uttales “what-in”). Disse produktene/biblotekene lar deg automatisere web testing.., med henholdsvis Ruby og .net.

Jeg har foreløpig brukt watir til helt enkle automatiseringsoppgaver, men kanskje watin kan få litt mer fart på selve test-utviklingen.., skal definitivt ta en titt på dette.

Et par uttalelser om WatiN:

“… it feels like it should have shipped out of the box with Visual Studio Team Edition for Software Testers.”

Bruce McLeod
Principal Consultant for Devtest Pty Ltd.
www.devtest.com

“What a great tool!!! We are using it with CruiseControl.Net. We run roughly 1k tests each build.”

David Strickland

Vice President of Development

Swingvote, LLC

En oppsummering av ukas viktigste saker..

De mest interessant linkene som har poppet opp i min feed-leser de siste dagene..

Først, en historie som virkelig illustrerer hvor HÅPLØS IDIOT det går an å være. Her er linken til en mailutveksling om en feil-konfigurert webserver og trusler om å ringe FBI. LINK! Ta deg tid til å lese denne, det er helt utrolig…

Mere morro; jeg følger med på Dilbert bloggen, og i My Opinions Part II svarer Scott Adams på en haug med spørsmål fra leserne. LINK!

Rails versjon 1.1 ble lansert i dag. For dem som ikke vet det så er Rails webutviklings-rammeverket for Ruby (som ASP.NET for .NET plattformen) – og det er helt konge – en helt ny måte å bygge web på! En bunch med nye features for dem som liker AJAX, web services m.m. Installerte Rails i helgen, men nå er det altså på tide å oppgradere. LINK!

I’ll take Static Typing for $800, Alex. er et interessant innslag i debatten rundt static vs. dynamic typing, noe jeg særlig har blitt interessert i etter at jeg har prøvd ut Ruby. LINK!

Here’s an Idea: Let Everyone Have Ideas forteller om hvordan et firma har tatt inovasjon til nye høyder ved å gjøre intern ideskaping til et aksjespill. Noe å prøve ut – eller videreutvikle? LINK!

Så en liten video – har du lyst til å se noen sprettne folk så må du se Matrix Dance. LINK!

Og til slutt – du har kanskje sett det før, men dette historiske innslaget får meg alltid til å humre i skjegget. LINK!

Er du ellers interessert i å se hva jeg sparer på av linker, så finner du mine bookmarks på http://del.icio.us/tormaroe

Unit-teste web applikasjoner med Ruby..

Har lest og testet Ruby i hele fem dager nå – og er helt frelst. Jeg har også funnet et område hvor jeg garantert kommer til å benytte Ruby i jobben (om ikke min kommende arbeidsgiver har investert i noe fancy greier da).., nemlig enhetstesting av web UI! Watir er et bibliotek til Ruby som lar deg helautomatisere IE, og støtte for flere browsere kommer. Du kan også (med litt jobb) plugge unit tester du lager i ruby/watir inn i NUnit, om du skulle ønske det.

Uttalelser folk har kommet med etter å ha oppdager Watir:

“I’ve been trying to find the Holy Grail of Automated Web UI Testing….
And the one I’m currently enamored with is Watir.”
— Scott Hanselman

“I wanted to run around my office dancing and celebrating.” — Beth Ferguson

For mer om Ruby, se mine tags..

Jeg surfer ganske mye på ulike programmeringssider for tiden, og oppdaget da denne litt morsomme siden for oss nerder: 99-bottles-of-bear.net! Her kan du se den kjente øl-sangen implementert i forskjellige språk på (p.t.) 927 ulike måter.

Og da fikk jeg forresten lyst til å vise mitt siste program.., ikke et eksempel på hvor lesbar Ruby kode er akkurat – har har jeg forsøkt å obfuskere litt:

# party game
a,b,c=1,7,70;def d(i,b)print i.to_s=~/#{b}/||i.modulo(b)==0?
“ukek!n “.gsub(/(.)(.)/,’\2\1′):i.to_s+” “end;(a..c).each
{|i| d(i,b)};(c-1).downto(a){|i| d(i,b)}

Noen som ser hva dette programmet gjør? Send inn forslag…

Jakten på den røde rubin

“This is your last chance. After this, there is no turning back. You take the blue pill – the story ends, you wake up in your bed and believe that C# is the only way to code. You take the red pill – you stay in Wonderland and I show you how different, simple and interesting code can really be.”

Ruby

Jeg har tatt den røde pillen, og takker Morten Brudvik for tipset. Etter å ha programmert i endel år nå så merker jeg at interessen for selve kodingen har stagnert. Jeg er opptatt av god arkitektur, og det er mange spennende disipliner i .NET verdenen, men jeg merker at jeg har blitt litt sløvet i måten å tenke kode på – the C# way blir litt ensformig i lengden faktisk – og jeg bestemte meg derfor for å utfordre meg selv litt.

Jeg har derfor begynt å lære meg Ruby; ett litt anderledes språk som på nostalgisk vis fører meg tilbake til Universitets-dagene og Unix-livet. På samme måte som C# er det basert på populære språk og erfaringer (i Ruby’s tilfelle Ada, Perl, Smalltalk, Python, Lisp m.m.), men forsøker å gå et steg videre og adressere svakhetene i disse språkene. Etterhvert som jeg leser meg opp på Ruby så slår det meg at mange av de unike elementene i Ruby har paralelle elementer i C# som er løsninger på svakheter i C++ og Java.

Filosofien bak Ruby er å gjøre programmereren lykkelig ved å fjerne mengden av “manuelt arbeid” under kodingen, og være minst mulig “overraskende” i sin virkemåte. Det er et objektorientert språk – ALT er objekter – og bruker “dynamic typing”, en feature jeg faktisk aldri har sett nytten av før nå. Det som er helt nytt for meg er bruken av kodeblokker som parametre til funksjoner. Se for deg kode hvor du i nesten hvert eneste metodekall sender med et delegat til en funksjon som metodekallet kjører. Det er veldig fjernt fra sånn som vi er vant til å tenke i C-verden, men det er faktisk veldig elegant.

Selv om Ruby er et såkalt skriptspråk, så påstås det at det kan brukes til det meste. NASA bruker det til å kjøre simuleringer, så da må det jo være kult. Ellers brukes det mye til behandling av data, netverks- og systemadministrasjon, web applikasjoner osv. For meg blir det nok aldri noen erstatning for C# og .NET rammeverket, og ikke for mine arbeidsgivere heller. C# er bedre på å strukturere større prosjekter, men som er sekundærspråk for å utføre mindre oppgaver som f.eks. automatisering av repetetive oppgaver eller parsing/transformering av data, så er Ruby ypperlig for meg. 10 linjer i TextPad som det tar 5 minutter å skrive gjør samme jobben som et prosjekt i .NET som det tar en halvtime å opprette, kode og kompilere. For ikke å snakke om hvor lett det er å gjøre endringer.

Men først og fremst får Ruby meg til å tenke.., til å tenke nytt. Kanskje vil dette også inspirere meg til å ta opp igjen arbeidet med neurale nettverk og kunstig intelligens, hvem vet..?! Og så er det jo veldig kult da (på en veldig nerdete måte, jeg vet)!


Alf Kåre Lefdal: Distributed Podcast er også ganske interessant. De tar opp tema som fx. ...

Stian: +1 for 6er til This Developer's Life! Min definitive favoritt. Jeg trengte også...

Torbjørn: Takk for flere tips, Vegard. Deep Fried Bytes ligger på oversikten min fra 2009...

Vegar: Og glemte helt ios: Nsbrief og ideveloper live. Har du hørt på deep fried byt...

Vegar: Mye kjekt her. TDL, hanselminutes og .net rocks ligger i en klasse for seg. Suv...

Torbjørn: Helt enig, arkivet til Software Engineering Radio er en gullgruve om man vet hva...

Einar W. Høst: Jeg synes at det kuleste med se-radio er backloggen av intervjuer... det er noen...

arnab: fantastisk :)...

Olav: Glimrende blogg ! Modellen av hjernens arbeid passer ikke bare på nyskaping: ...

Torbjørn: Ja, flydesign trekkes ofte frem som et eksempel på dette fenomenet. Design av b...

 Hold deg oppdatert

Søk i bloggen

Ferske innlegg

  • NodeJS vs. ASP.NET
  • Pulten min..
  • No ifs and buts
  • Community-fiskebolle på ROOTS 2012
  • Kategorier

  • .net ninja (37)
  • Bøker (18)
  • Diverse prosjekter (37)
  • DSL (10)
  • Erlang (10)
  • F# (5)
  • Hardware (1)
  • Jobb (78)
  • Julekalender (51)
  • kjempekjekt.com (23)
  • LISP/Clojure (34)
  • NDC (4)
  • NNUG / community (63)
  • O/RM & databaser (10)
  • Off topic (118)
  • OO-design/clean code (31)
  • Podcasts (15)
  • Polyglot (82)
  • Ruby (29)
  • Silverlight / RIA (3)
  • Software/verktøy (20)
  • Softwareutvikling (24)
  • Testing / TDD (30)
  • the contiki strip (13)
  • User experience (3)
  • WCF (3)
  • Webutvikling (34)
  • WPF (9)
  • WTF (13)
  • Last ned Wallpaper

    Programmeringsbloggens tøffe skrivebordsbakgrunn med snippets fra ulike språk laster du ned her!

    Abonner via epost

    Om du vil kan du få alle nye blogposter tilsendt til din epost. Abonner nå, det er kjempeenkelt!

    Meta