Mer om språk och Ruby TDP007 Konstruktion av datorspråk Föreläsning 2 Peter Dalenius Institutionen för datavetenskap 2014-01-21
Översikt över dagens föreläsning 1. Hur kan man bedöma ett språk? 2. Enhetstestning 3. Likhet i Ruby 4. Reguljära uttryck
1. Hur kan man bedöma ett språk? Exempel Historik Språk Verktyg Utvecklare Dokumentation 3
Hur skriver jag Hello World!? Hur ser syntaxen ut? Liknar språket något som jag redan kan? Vilka av de vanliga konstruktionerna finns och hur ser de ut? Vilka datatyper finns? Vad är omfattningen på de Språk kodbibliotek som följer med språket? Finns det någon speciell kodningsstil som används? Hur utbyggbart är språket? Kodbibliotek Språk Särskilda konstruktioner Baskonstruktioner Vad finns det för särskilda konstruktioner i det här språket som inte finns i andra språk? Finns det några särskilda sorters uppgifter som det här språket verkar lämpat för? 4
Verktyg Hur kommer jag över huvud taget igång med att skriva och testa program? Språk Är språket interpreterat eller kompilerat? Vilka utvecklingsmiljöer finns och vilket stöd ger de programmeraren? Hur funkar det med driftsättning av programvara som ska köras på riktigt? Utvecklingsmiljö Verktyg Körmiljö 5
Dokumentation Vilken information om grundspråket finns (specifikationer, läroböcker)? Vilken information om kodbibliotek finns? Hur dokumenterar jag den kod som jag skriver själv? Finns det bra utbildningsmaterial tillgängligt (ex. tutorials)? Språk Dokumentation Dokumentation Utbildningsmaterial Verktyg 6
Utvecklare Vem bestämmer hur språket ska se ut? Har språket en bred bas av aktiva utvecklare? Vilka är det som använder språket? Språk Verktyg Utvecklarcommunity Utvecklare Ägare Dokumentation 7
Historik Historik Trender Bakgrund Hur länge har språket funnits? Hur stabilt är språket? Görs det drastiska ändringar fortfarande? Finns det olika implementationer? Vad var det ursprungliga syftet med att skapa språket? Språk Talas det om språket? Vad har hänt den senaste tiden? Verktyg Utvecklare Dokumentation 8
Exempel Tillgängliga program Exempel Framgångsexempel Hur mycket används språket till verkliga projekt? Historik Språk Finns det några dokumenterade framgångsexempel? Finns det fria exempelprogram eller öppen källkod-projekt? Verktyg Utvecklare Dokumentation 9
2. Testning: Fyra nivåer Enhetstest (eng. unit testing) Varje enhet, t.ex. funktion, testas för sig. Integrationstest Test av flera enheter tillsammans. Systemtest Hela systemet testas, t.ex. säkerhet, prestanda, användbarhet. Acceptanstest Slutligt test av kunden.
Testning: Två strategier Black box test Den som utformar testerna har inte sett koden utan utgår från specifikationen. White box test Testerna baseras på analys av programkoden.
Enhetstestning Fördelar Underlättar förändring Underlättar integrationstestning Kan i viss utsträckning ersätta design och dokumentation Enhetstestning i Ruby Grundtanken är att vi paketerar testfall som kan köras automatiskt med hjälp av modulen Test::Unit Testfall är egentligen en uppsättning assertions eller förväntningar på utdata
require./faculty' require 'test/unit' Testklass Vi vill här testa funktionen faculty i filen faculty.rb. class TestFaculty < Test::Unit::TestCase def test_simple assert_equal(1, faculty(0)) assert_equal(1, faculty(1)) assert_equal(120, faculty(5)) assert_equal(2432902008176640000, faculty(20)) end end
Körning av tester Alternativ 1: Köra direkt från kommandoraden (rekommenderas) ruby test_faculty.rb Alternativ 2: Vid prompten i irb require './faculty' require './test_faculty' require 'test/unit Test::Unit::Runner.new(TestFaculty).run Resultat av körning Run options: # Running tests:. Finished tests in 0.008113s, 123.2628 tests/s 1 tests, 3 assertions, 0 failures, 0 errors, 0 skips
Några fler sätt att testa Det finns fler sätt att testa som man kan hitta i paketet Test::Unit::Assertions. Här är några exempel: assert(a<5) assert_equal(a, b) assert_not_equal(a,b) assert_nil(my_array) Testar uttrycket är sant Testar om a==b Motsatsen till ovanstående Testar om uttrycket är nil assert_nothing_thrown { do_stuff(a) } Testar att koden inte kastar några undantag assert_in_delta(a, 100.0, 0.01) Testar om a är inom intervallet Gå till www.ruby-doc.org, välj Stanard Library API, leta upp paketet test/unit och klassen Test::Unit::Assertions.
Övning Hämta filerna faculty.rb och test_faculty.rb från föregående exempel från kurswebben (sidan med föreläsningar) och kör testet. Hämta också filen some_functions.rb och utforma testfall för dessa funktioner.
3. Likhet i Ruby a == b testar om a och b är samma objekt. Flera klasser har egna definitioner av ==. Till exempel är 1 == 1.0 trots att det är olika klasser. Likhet beror alltså på klassen. För att alltid kunna jämföra objekt finns a.equal?(b) En svagare form av likhet a.eql?(b) används bl.a. av Hash för att testa likhet. a === b används bl.a. av case-satsen. Den är oftast samma som ==.
4. Reguljära uttryck Vad är poängen? Den enklaste formen av formellt språk Används oftast för att söka i textsträngar Exempel: wildcards är en enklare form grep m.fl. kommandon tar reguljära uttryck scriptspråk, t.ex. Perl Det finns några olika uppsättningar, olika kraftfulla, en del till och med mer än riktiga reguljära uttryck
Reguljära uttryck i Ruby >> /be/ =~ "To be, or not to be..." => 3 >> /o+/ =~ "Moo mooo moooo!" => 1 >> "23, 18, 45"=~/1[0-9]/ => 4 >> /\w\d/ =~ "ABC123" => 2 >> /kul/ =~ "Inget roligt här!" => nil Testa reguljära uttryck i Ruby själv på webbsidan rubular.com
Enskilda tecken Alla tecken utom \/^$.+*?()[]{} matchar sig själva. Dessa måste föregås av \ om man vill matcha dem.. matchar ett godtyckligt tecken. [characters] matchar ett av de uppräknade tecknen. [aeiouyåäö] matchar en vokal [a-za-z] matchar en (engelsk) bokstav [^characters] matchar ett tecken som inte ingår i uppräkningen Det finns genvägar för några klasser av tecken: \w matchar ett alfanumeriskt tecken \d matchar en siffra \s matchar ett white space
Sammansättning Låt a och b vara två reguljära uttryck: ab matchar de två strängarna efter varann a b matchar endera av a eller b a* matchar noll eller fler förekomster av a a+ matchar en eller fler förekomster av a a{m} matchar exakt m förekomster av a a{m,} matchar minst m förekomster av a a{m,n} matchar m till n förekomster av a
Förankring ^ och $ matchar början/slutet av en rad \A och \z matchar början/slutet av strängen \b matchar ordgränser (\B tvärtom)
Funktioner som använder regexp >> s = "The stars, like dust" => "The stars, like dust >> s.sub(/e/,'$') => "Th$ stars, like dust >> s.gsub(/[aeiouy]/,'*') => "Th* st*rs, l*k* d*st >> s.gsub(/(^, \s)\w/) { m m.upcase } => "The Stars, Like Dust >> s.split(/[\s,]+/) => ["The", "stars","like", "dust"] >> s.scan(/[aeiouy]\w/) => ["ar", "ik", "us"]
Resultat av matchning >> /[aeiouy]{2,}/ =~ "the moon is a cheese" => 5 >> [$`, $&, $'] => ["the m", "oo", "n is a cheese"] >> /(\d\d):(\d\d):(\d\d)/ =~ "Klockan är 12:35:40 nu" => 12 >> [$1, $2, $3] => ["12", "35", "40"]
Resultat av matchning >> s = "the moonis a cheese" => "the moon is a cheese" >> re = /[aeiouy]{2,}/ => /[aeiouy]{2,}/ >> md = re.match(s) => #<MatchData:0xdf65ed4> >> [md.pre_match, md[0], md.post_match] => ["the m", "oo", "n is a cheese"] >> md2 = /(\d\d):(\d\d)/.match("14:45") => #<MatchData:0xdb94f94> >> md2.captures => ["14", "45"]
Övning Hitta på ett reguljärt uttryck som matchar en svensk postadress, t.ex. 584 31 Linköping. Finns det några postorter vars namn innehåller något annat än bara vanliga bokstäver? Baka in det i en funktion som svarar sant eller falskt, givet en sträng som kanske innehåller en postadress. Gör en testklass med lämpliga testfall. Ta även med negativa tester, dvs det reguljära uttrycket får inte matcha strängar som inte är postadresser. Testa reguljära uttryck i Ruby på rubular.com
Inför första seminariet Hur kan man sätta sig in i den andra gruppens kod med begränsad tid? Läs deras utvecklarblogg! Kör deras testerna! Hur gör man en bra opposition? Om någon ska beskriva en lösning för dig, hur vill du att de ska göra? Tänk ut ett par frågor att ställa till gruppen. Utgå från frågorna som finns i anvisningarna för utvecklarbloggen. Lärde ni er något av gruppens lösning?
www.liu.se