søndag 13. mai 2012 CodingDojo Ruby WTF
For noen dager siden hadde vi en ny CodingDojo i Bergen. Oppgaven denne gangen var å presse objektorientering til det ytterste og trene på polymorfi gjennom å skrive kode helt uten bruk av IF, SWITCH eller tilsvarende konstruksjoner. Er du interessert i bakgrunnen for denne øvelsen kan du ta en titt her på bloggen til professor Eugene Wallingford. Du bør også sjekke ut the Anti-If Campaign.
Jeg jobbet sammen med @Olsenius for anledningen. Vi brukte Ruby. Oppgaven vi forsøkte å implementere var en billett-automat. Desverre ble dette mer et eksperiment i hvilke Ruby-triks vi kunne missbruke for å unngå IF enn en trening i god objektorientering. Koden vi produserte er noe av det værste jeg kan huske å ha laget :)
Vi ble ikke helt ferdige – jeg måtte gå litt tidlig – men koden vi produserte er gjengitt i sin helhet nedenfor. Vi brukte TDD, men testene har jeg droppet her.
Ser du hvordan vi har oppfunnet et nytt pattern både for IF og for UNLESS (altså "not if")?
10 # Monkey patch: Just adding a convenient sum-method to arrays 11 class Array 12 def sum 13 self.inject(0){|x, y| x + y} 14 end 15 end 16 17 class TicketMachine 18 def initialize 19 @balance, @total = [], [] 20 @printers = { "total=5" => ValidTicket.new } 21 @money_validators = { "-" => InvalidMoney.new } 22 end 23 24 # Properties: 25 def balance; @balance.sum; end 26 def total; @total.sum; end 27 28 # Lets user print his ticket, 29 # but raises an Exception unless @balance is 5 !!! 30 def print_ticket 31 @printers["total=#{@balance.sum}"].print 32 @balance = [] 33 end 34 35 # Lets user insert money into the machine 36 # Will raise exception if money is a negative number !!! 37 def add money 38 begin 39 @money_validators[money.to_s[0]].fail_if_valid 40 raise "INVALID MONEY" 41 rescue NoMethodError 42 @balance << money 43 @total << money 44 end 45 end 46 end 47 48 class ValidTicket 49 def print 50 puts "THE TICKET" 51 end 52 end 53 54 class InvalidMoney 55 def fail_if_valid; end 56 end
That's all!