ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2m *qm ah q a n qhb q h ? a2 `+ m+2/ /p...

130
WAST Wittgenstein Advanced Search Tools Dokumentation (Stand 01/2014) (—WORK IN PROGRESS—) Dr. Max Hadersbeck & Daniel Bruder, M.A., CIS, LMU 260 CHAPTER 34. SEMINARPLAN Tom Preston-Werner. 2013. “Semantic Versioning 2.0.0.” http://semver.org/. uscilab. 2014. “cereal Docs - Main.” http://uscilab.github.io/cereal/. visionmedia. 2014. “git-Extras.” https://github.com/visionmedia/git-extras. Volos, Lyudmyla. 2013. “Disambiguierung von Partikelverb – Konstruktio- nen Und Verbpräpositional – Konstruktionen Im Big Typescript von Ludwig Wittgenstein.”

Upload: others

Post on 09-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

WAST

WittgensteinAdvancedSearchToolsDokumentation(Stand01/2014)(—WORKINPROGRESS—)

Dr.MaxHadersbeck&DanielBruder,M.A.,CIS,LMU

260CHAPTER34.SEMINARPLAN

TomPreston-Werner.2013.“SemanticVersioning2.0.0.”http://semver.org/.

uscilab.2014.“cerealDocs-Main.”http://uscilab.github.io/cereal/.

visionmedia.2014.“git-Extras.”https://github.com/visionmedia/git-extras.

Volos,Lyudmyla.2013.“DisambiguierungvonPartikelverb–Konstruktio-nenUndVerbpräpositional–KonstruktionenImBigTypescriptvonLudwigWittgenstein.”

Page 2: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

2 259

Maurice, Gross. 1997. “The Construction of Local Grammars.” Finite-StateLanguageProcessing: 329–354.Meyers, Scott. 2005. Effective C 55 Specific Ways to Improve Your Programsand Designs. - Includes Index. Upper Saddle River NJ: Addison-Wesley.MongoDB. 2014. “MongoDB.” http://www.mongodb.org/.node. 2014. “node.Js.” http://nodejs.org/.Node API. 2014. “Addons Node.Js V0.10.25 Manual & Documentation.” http://nodejs.org/api/addons.html#addons_wrapping_c_objects.Pichler, Alois. 2010. “„Towards the New Bergen Electronic Edition“.” Wittgen-stein After His Nachlass. Edited by Nuno Venturinha: 157–172.Pichler, Alois, H.W. Krüger, D.C.P. Smith, T.M. Bruvik, A. Lindebjerg, and V.Olstad. 2009. “Wittgenstein Source Bergen Facsimile Edition (BTE).” Wittgen-stein Source. Bergen: WAB, Wittgenstein Source.R. Martinho Fernandes. 2013. “Rule of Zero @ Flaming Dangerzone.” http://flamingdangerzone.com/cxx11/2012/08/15/rule-of-zero.html.Rothhaupt, Josef G. F. 2006. “Zur Dringend Notwendigen Revision Des „Stan-dard View“ Der Genese Der ‘Philosophischen Untersuchungen’.” Gasser, Georg/ Kanzian, Christian / Runggaldier, Edmund (Hg.): Cultures: Conflict - Anal-ysis - Dialogue. Papers of the 29th International Wittgenstein Symposium 2006,Kirchberg 2006: S. 278–280.Rothhaupt, Josef G. F. 1996. “Farbthemen in Wittgensteins Gesamtnach-laß. Philologisch-Philosophische, Untersuchungen Im Längsschnitt Und inQuerschnitten.” PhD thesis, Weinheim.Schiller, Anne, Christine Thielen, and Simone Teufel. 1999. “StuttgartTübinger Tagset (STTS).” http://www.ims.uni-stuttgart.de/forschung/ressourcen/lexika/TagSets/stts-table.html.Schmid, Helmut. 1994. “Probabilistic Part-of-Speech Tagging Using DecisionTrees.” Proceedings of International Conference on New Methods in LanguageProcessing, Manchester, UK.Seebauer, Patrick. 2012. “Verbesserung Der Suche Im Wittgenstein-Nachlass.Suche in Alternierenden Texten.”Strutynska, Olga. 2012. “Nachlass von Ludwig Wittgenstein: OptimierungEines Digitalen Lexikons Und Semantische Kodierung Der Nomen. EvaluationDes Lexikons Mit Hilfe von Konkordanzanalysen.”“Substitution Failure Is Not an Error.” 2014. Wikipedia, the Free Encyclope-dia. http://en.wikipedia.org/w/index.php?title=Substitution_failure_is_not_an_error&oldid=581401656.TEI Consortium. 2009. “Guidelines for Electronic Text Encoding and Inter-change.” TEI Consortium.

Page 3: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Contents

IWAST9

1WittgensteinAdvancedSearchTools11

1.1AbstractdesKurses.........................11

1.2SoftwarearchitekturundProjektmanagementamBeispielvonWAST–theoretischeGrundlagenundpraktischeÜbungen....11

1.3Projektstruktur............................13

1.4Projektstrukturextern:beteiligteInstitutionenundPersonen..13

1.5WASTProjektstrukturintern....................13

1.6Komponenten.............................16

IIwittfind17

2wittfind19

2.1Zweck.................................20

2.2Kurzvorstellung............................20

2.3Funktionen..............................20

2.4BeschreibungderverwendetenTechnologien............20

2.5Umfang,WertundGrößederCodebase..............20

2.6Mitwirkende..............................20

2.7Import/ExportausPaper......................20

3

258CHAPTER34.SEMINARPLAN

expressjs.2014.“Express-Node.JsWebApplicationFramework.”http://expressjs.com/.Fink,Florian.2013.“ProgrammingoftheRule-BasedWf.”Gaston,Gross.1991.“LaFormd’unDictionnaireElectronique.”LADL-Report.Laboratoired’AutomatiqueDocumentaireEtLinguistique.Gerdjikov,Stefan,StoyanMihov,PetarMitankin,andKlausU.Schulz.2013.“GoodPartsFirst-aNewAlgorithmforApproximateSearchinLexicaandStringDatabases.”arXiv:1301.0722[Cs](January).http://arxiv.org/abs/1301.0722.“Git-Submodules.”2014.http://git-scm.com/book/en/Git-Tools-Submodules.Gitlabcisgroup.2014.“GitlabCisGroup/Gitlab.”GitlabCisGroup/Gitlab.Google.2014.“AngularJS—SuperheroicJavaScriptMVWFramework.”http://angularjs.org/.Gotscharek,Annette,UlrichReffle,ChristophRinglstetter,KlausU.Schulz,andAndreasNeumann.2011.“TowardsInformationRetrievalonHistori-calDocumentCollections:theRoleofMatchingProceduresandSpecialLex-ica.”InternationalJournalonDocumentAnalysisandRecognition(IJDAR)14(2):159–171.doi:10.1007/s10032-010-0132-6.http://dx.doi.org/10.1007/s10032-010-0132-6.Grassi,Marco,ChristianMorbidoni,MicheleNucci,SimoneFonda,andFrancescoPiazza.2013.“Pundit:AugmentingWEBContentsWithSeman-tics.”LiteraryandLinguisticComputing.SpecialIssue“DigitalHumanities2012:DigitalDiversity:Cultures,LanguagesandMethods”.EditedbyPaulSpence,SusanBrownandJanChristophMeister28(4)(December).Guenthner,Franz,andPetraMaier.1994.“DasCISLEXWörterbuchsystem.”CIS-Bericht-94-76.Inenaga,Shunsuke,HiromasaHoshino,AyumiShinohara,MasayukiTakeda,andSetsuoArikawa.2001.ConstructionoftheCDAWGforaTrie.Krey,Angela.2013.“SemantischeAnnotationvonAdjektivenImBigType-scriptvonLudwigWittgenstein.”Langer,Stefan,andDanielSchnorbusch(Hrsg.).2005.SemantikImLexikon.Tübingen:Narr.Lindinger,Matthias.2013.“HighlightingvonTreffernDesToolsWiTTFindImZugehörigenFaksimile.”MarcoRogers.2013.“MarcoRogers:CreatingNodeAddons,C/C++ExtensionsforFunandProfit.”http://www.youtube.com/watch?v=q1ri36UI5GA&feature=youtube_gdata_player.MartinMoene.2013.“martinmoene/Lest·GitHub.”https://github.com/martinmoene/lest.

Page 4: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

4 CONTENTS

III SIS 29

3 SIS: Symmetric Index Structures 31

3.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.2 Zweck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.3 Kurzvorstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.4 Verwendung auf der Kommandozeile . . . . . . . . . . . . . . . . 32

3.5 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

3.6 Ebenen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

IV Feedback 69

4 feedback 71

4.1 Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

4.2 Application-Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

V Weitere Komponenten 75

5 wab2cis 77

5.1 Einbindung als git-submodule . . . . . . . . . . . . . . . . . . . . 77

6 WIndex 79

7 Patrick’s Teil: Ausformulierung von Alternativen 81

VI Toolchain 83

8 gitlab 85

9 Continuous Integration 87

9.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

9.2 CI@CIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

9.3 Referenzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

Bibliographie

Abrahams, David, and David Gurtovoy. 2005. C++ Template Metapro-gramming: concepts, Tools, and Techniques from Boost and Beyond. Boston:Addison-Wesley.Alexandrescu, Andrei. 2000. Modern C++ Design: applied Generic Program-ming and Design Patterns. Boston, MA; London: Addison-Wesley.Arseny Kapoulkine. 2014a. “pugixml.” pugixml. http://pugixml.org/.———. 2014b. “zeux/Pugixml.” GitHub. https://github.com/zeux/pugixml.Blumer, A., J. Blumer, D. Haussler, R. McConnell, and A. Ehrenfeucht. 1987.“Complete Inverted Files for Efficient Text Retrieval and Analysis.” J. ACM34 (3) (July): 578–595. doi:10.1145/28869.28873. http://doi.acm.org/10.1145/28869.28873.boost.org. 2014a. “Boost Test Library.” http://www.boost.org/doc/libs/1_55_0/libs/test/doc/html/index.html.———. 2014b. “Serialization.” http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html.C++1y Standard Committee. 2014. “xdbr/Cpp-Make-Unique.” GitHub. https://github.com/xdbr/cpp-make-unique.Daniel Bruder. 2012. “SIS – Symmetric Index Structures.” PhD thesis, LMUMünchen. www.cip.ifi.lmu.de/~bruder/ma/MA/sis/MA-SIS-DB.pdf.———. 2014. “xdbr/Cmake-Module-Submodule.Cmake.” GitHub. https://github.com/xdbr/cmake-module-submodule.cmake.Daniel Bruder, Florian Fink. 2014. “xdbr/Cpp-Generic-Serialize / GitHub.”https://github.com/xdbr/cpp-generic-serialize.“Day 1 Keynote - Bjarne Stroustrup: C++11 Style.” 2012. http://www.youtube.com/watch?v=0iWb_qi2-uI&feature=youtube_gdata_player.Di Gennaro, Davide. 2012. Advanced C++ Metaprogramming. S.l.: s.n.].Emscripten Authors. 2013. “Home · Kripken/Emscripten Wiki · GitHub.”https://github.com/kripken/emscripten/wiki.

257

Page 5: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

CONTENTS5

10BuildSysteme91

10.1make..................................92

10.2cmake.................................92

10.3rake..................................96

10.4gyp...................................97

11Web99

11.1Web-Applikationen..........................99

11.2MEAN-Stack.............................102

11.3Jade..................................105

12XML107

12.1TEI..................................107

12.2XPath.................................107

13Dokumentation109

13.1pipelinemitgpp,ppp&pandoc...................109

14UnifiedDeployment113

14.1wast-infrastructure..........................113

14.2userwastd...............................116

VIITechniken119

15C++121

15.1WrappingvonCnachC++.....................121

15.2PolicybasedDesign.........................125

15.3Typetraits..............................127

15.4TemplateMetaProgrammierung..................129

15.5SFINAE................................129

15.6SilentDegredation..........................130

15.7StaticDispatching/Tagdispatch..................132

15.8Detail-Beschreibung.........................133

256CHAPTER34.SEMINARPLAN

SitzungDatumThemenHausaufgabeVorbereitungfürnächsteSitzung

409.05.2014Serialisierung:SerialisierunginC++/VerschiedeneLibrarieszurSerialisierung/Verwendungvon“cerealzurSerialisierung/ZweistufigeSerialisierunginSIS

Übung5:Serial-isierung

Web-Apps/MEAN-Stack/Techniken:Node-Wrapping

5(16.05.2014)–Betriebsausflug–

623.05.20147(30.05.2014)806.06.2014913.06.201410(20.06.2014)1127.06.20141204.07.20141311.07.2014

Table34.1:Seminarplan

Page 6: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

6 CONTENTS

15.9 Bemerkungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

15.10Wrapping von C++ nach Javacript (Node) . . . . . . . . . . . . 134

16 Serialisierung 135

16.1 Methoden zur Serialisierung . . . . . . . . . . . . . . . . . . . . . 135

16.2 Formate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

16.3 Klassische Verfahren: Binärformat und byte-layout . . . . . . . . 137

16.4 APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

17 Node Wrapping 145

17.1 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

17.2 Node Addon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

17.3 Schematische Darstellung . . . . . . . . . . . . . . . . . . . . . . 146

17.4 Demonstration . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

18 Design Patterns 155

18.1 MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

18.2 MVVM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

18.3 MV* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

18.4 (Teile aus SIS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

VIII Best Practices 157

19 Test Driven Development 159

19.1 Motivation und Vorteile . . . . . . . . . . . . . . . . . . . . . . . 159

19.2 Arten von Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160

20 Bug tracker 165

20.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

20.2 WAST-Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

21 Versionierung 171

21.1 git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

Chapter 34

Seminarplan

Sitzung Datum Themen HausaufgabeVorbereitung für nächsteSitzung

1 11.04.2014 Einführung /WAST:Projekt-Landschaft /Seminarplan /Hinweise zurDokumenta-tion

Übung 1:git

Techniken-Kapitel zumThema Wrapping von Cnach C++ / C-WrappingBeschreibung in SIS

N/A 18.04.2014 Stunde findetnicht statt

2 25.04.2014 C-Wrapping Übung 2:C-Wrapping

cmake, TDD

3 02.05.2014 Build-Systeme /Test DrivenDevelopment

Übung 3:cmake +Übung 4:cmake

Einschlägige Kapitel zuSerialisierung

255

Page 7: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

CONTENTS7

22SemanticVersioning189

22.1Versions-Schema...........................189

23Lizenzen191

23.1GNUGPL...............................192

23.2MIT..................................192

23.3CreativeCommons..........................192

23.4WTFPL................................192

24Mailingliste193

IXÜbungen195

25Übungen197

25.1Übung1:gitundKollaboration...................199

25.2Übung2:C-Wrapping........................201

25.3Übung3:cmake...........................203

25.4Übung4:TDD–TestDrivenDevelopment............205

25.5Übung5:Serialisierung.......................207

25.6Übung6:Node-Wrapping......................209

25.7Übung7:TemplateMetaProgrammierung............211

25.8Übung8:TypeTraits........................213

25.9Übung9:Web-ProgrammierungmitdemMEAN-Stack.....215

XAppendix217

26Disclaimer219

27Dank221

28Überblickstabellen223

28.1Komponenten,Maintainer,Dependencies.............223

28.2Mitwirkende..............................227

254CHAPTER33.DEFINITIONEN

SFINAESubstitutionFailureIsNotAnError

RAIIResourceAcquisitionIsInitialization

Page 8: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

8 CONTENTS

29 Workflows 231

29.1 git branching model workflow . . . . . . . . . . . . . . . . . . . . 231

29.2 Continuous Integration Workflow . . . . . . . . . . . . . . . . . . 231

29.3 WAST pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

29.4 bug tracking workflow . . . . . . . . . . . . . . . . . . . . . . . . 231

30 Hinweise 237

30.1 History Visualisierung (gource) . . . . . . . . . . . . . . . . . . . 237

31 next steps 239

31.1 E2E-Tests für Feedback, SIS, wittfind-web . . . . . . . . . . . . . 239

31.2 Integration-Tests und Projekt-Organisation . . . . . . . . . . . . 239

31.3 Integration von SIS und Feedback in wittfind-web . . . . . . . . . 239

31.4 Integration der restlichen 5000 Facsimile Seiten und Transkrip-tionen (in SIS und wf) . . . . . . . . . . . . . . . . . . . . . . . . 239

31.5 Erweiterung von WAST auf *AST: Öffnung und Aufbereitung fürandere Editionsprojekte. . . . . . . . . . . . . . . . . . . . . . . . 239

32 Ressourcen 241

32.1 UML Legende . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

32.2 Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

32.3 Kontakt, Ansprechpartner . . . . . . . . . . . . . . . . . . . . . . 243

33 Definitionen 253

34 Seminarplan 255

Bibliographie 257

Chapter 33

Definitionen

Deploy Defintion von Deploy

WAST Wittgenstein Advanced Search Tools

SPA Single Page Applicationaktuell modernste Variante von Web-Applikationenladen immer nur bestimmte Teile der Seite neu und es gibt keinen kom-pletten Refresh der Seiten

Fat Client innerhalb von MVC Applikationen deutliche Verschiebung vonBusiness-Logik vom Controller hin zum Clientkann Server-Kosten senkensiehe auch AngularJS

MVC Pattern für Applikationen: Model View Controller

AngularJS ein Web-Framework mit MVVM- bzw. MV*-Ansatzweicht bewusst den als zu starr empfundenen MVC-Ansatz auf (besondersausgeprägt bei Ruby on Rails)favorisiert Fat Client-Architektur

VCS version control system (z.B. svn)im Gegensatz zu DVCS

DVCS distributed version control system (z.B. git)im Gegensatz zu VCS

CTOR Constructor

DTOR Destructor

253

Page 9: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartI

WAST

9

252LISTOFTABLES

Page 10: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

List of Tables

3.1 Serialisierungsmöglichkeiten für DocumentIndexingAutomaton . . 58

20.1 Prioritäten bei Bugs . . . . . . . . . . . . . . . . . . . . . . . . . 167

34.1 Seminarplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

251

Page 11: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter1

WittgensteinAdvancedSearchTools

Inhalt1.1AbstractdesKurses....................111.2SoftwarearchitekturundProjektmanagementam

BeispielvonWAST–theoretischeGrundlagenundpraktischeÜbungen....................11

1.3Projektstruktur......................131.4Projektstrukturextern:beteiligteInstitutionenund

Personen..........................131.4.1DasCISunddieWittgensteinAdvancedSearchTools131.4.2WAB–WittgensteinArchiveBergen.........13

1.5WASTProjektstrukturintern..............131.5.1VerwaltenvonKomponenteninWAST........15

1.6Komponenten.......................16

1.1AbstractdesKurses

1.2SoftwarearchitekturundProjektmanage-mentamBeispielvonWAST–theoretischeGrundlagenundpraktischeÜbungen

DiesesHauptseminarerklärtGrundlagenderSoftwarearchitekturunddesProjektmanagementsamkonkretenBeispielvonWAST,denWittgenstein

11

250LISTOFFIGURES

29.1gitbranchingmodel.........................232

29.2ContinuousIntegration........................233

29.3WASTDataWorkflow........................234

29.4BugTrackingWorkflow.......................235

32.1UMLLegende:Class.........................241

32.2UMLLegende:SimpleAssociation.................242

32.3UMLLegende:Cardinality.....................242

32.4UMLLegende:DirectionalAssociation...............243

32.5UMLLegende:Aggregation.....................244

32.6UMLLegende:Composition.....................245

32.7UMLLegende:Inheritance.....................245

32.8UMLLegende:InterfaceInheritance................246

32.9UMLLegende:Dependencies....................246

32.10UMLLegende:Interface.......................247

32.11UMLLegende:ClasswithDetails..................247

Page 12: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

12 CHAPTER 1. WITTGENSTEIN ADVANCED SEARCH TOOLS

Advanced Search Tools, das am CIS in Kooperation mit dem WittgensteinArchiv in Bergen (WAB) aktiv entwickelt wird.

Dabei richtet sich der Fokus zunächst auf die Architektur dieser Plattform, unddie Erklärung der einzelnen Komponenten sowie ihres Zusammenspiels. Desweit-eren werden die Schnittstellen und die Projektinfrastruktur an diesem konretenProjekt erläutert und die Prinzipien dahinter vorgestellt.

Begleitet wird das Seminar von praktischen (kleinen) Beispiel-Übungen, diehelfen, die wesentlichen Schritte tatsächlich selbst nachzuvollziehen und mod-erne Technologien und Frameworks kennenzulernen.

Besprochen und praktisch probiert werden in diesem Seminar: die Versionsver-waltung git und das am IFI angebotene gitlab als Web-Oberfläche zur Soft-wareverwaltung sowie Kollaboration mit anderen Entwicklern; das Wrappenvon Libraries, die in C geschreiben wurden in C++; das Erweitern derselbenC-Libraries mit neuen Funktionalitäten; das Einbinden der entstandenen C++-Libraries in Javascript, und damit in einem nächsten Schritt in den Browser;die Architektur von modernen Webseiten (auch als Single Page Applications –SPA – bekannt) in Form von Server/Client-Kommunikation; die Verwendungdes sogenannten MEAN-Stacks zur Umsetzung von Single Page Applications,d.h. das Zusammenspiel von MongoDB + ExpressJS + AngularJS + NodeJS.

Erwartet werden nicht zwingend Kenntnisse in allen vorgestellten, o.g. Tech-nologien und Frameworks, dafür aber ein hohes Maß an Willen, Belastbarkeit,Spielfreude, generellen, gut-bis-sehr-guten Programmierkenntnissen und, nichtzuletzt, die spielerische Neugierde, die leidenschaftliche Software-Entwicklerantreibt (nicht zuletzt diejenigen, deren Technologien wir verwenden). Dazugehört auch das exakte Lesen von Aufgaben-Spezifikationen und Programm-Dokumentation.

Als Lohn des dicht gepackten, umfangreichen Programms des Seminars mit,z.T. bedeutenden Sprüngen von Woche zu Woche, erhält man einen praktis-chen und einen theoretischen Einblick in konkrete, existierende Frameworks undStrukturen, sowie die Antwort auf die Frage: ich habe eine Kommandozeilen-Applikation in C++ – wie kann ich diese nun in den Browser transportierenund der Welt zugänglich machen?

List of Figures

1.1 WAST Projektstruktur . . . . . . . . . . . . . . . . . . . . . . . . 14

1.2 Die Landschaft von WAST . . . . . . . . . . . . . . . . . . . . . 15

3.1 SIS Schichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

3.2 Klassenarchitektur von SIS . . . . . . . . . . . . . . . . . . . . . 39

3.3 DocumentIndexingAutomaton UML . . . . . . . . . . . . . . . . 41

3.4 DocumentIndexingAutomatonAbstract UML . . . . . . . . . . . 42

9.1 Continuous Integration . . . . . . . . . . . . . . . . . . . . . . . . 88

10.1 Autotools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

11.1 Web Apps Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

13.1 Der Typesetting Process . . . . . . . . . . . . . . . . . . . . . . . 111

15.1 Adapter Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

16.1 Beispiel für ein Byte-Layout . . . . . . . . . . . . . . . . . . . . . 138

17.1 Node Wrapping Pattern . . . . . . . . . . . . . . . . . . . . . . . 147

20.1 Bug Tracking Workflow Status . . . . . . . . . . . . . . . . . . . 168

21.1 Git overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

28.1 WAST Komponenten und Dependencies . . . . . . . . . . . . . . 228

249

Page 13: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

1.3.PROJEKTSTRUKTUR13

1.3Projektstruktur

1.4Projektstrukturextern:beteiligteInstitu-tionenundPersonen

1.4.1DasCISunddieWittgensteinAdvancedSearchTools

DieWittgensteinAdvancedSearchTools(WAST)sindeineKollektionvonver-schiedenenAnwendungendesCIS,diespezifischaufdasKorpusdesArchivsinBergen,Norwegen(WAB)entwickeltwurde.

WASTistentstandenauseinerzunehmendgewachsenenKooperationmitdemdesWABArchivsinBergen(vertretendurchAloisPichler)undMaxHadersbeck(CIS).

FürdieZusammenarbeitspielenfolgendeAspekteeinewesentlicheRolle:

•begrenztesMaterial•sehrreichhaltigaufbereitetes,sehrsauberes(kontrolliertesMaterial)

WittgensteinwiederumisteinSubteildesehemaligen(?)europäischenProjektsunterderLeitungvonPaoloD’Iorio(darunter,u.a.)

1.4.2WAB–WittgensteinArchiveBergen

1.5WASTProjektstrukturintern

DieTool-LandschaftvonWASTbestehtauszweiDingen:

a)Komponentenb)ToolsundProjektstruktur

ZudenKomponentenzählenalleDinge,die…,darunter:

•wittfind•SIS:SymmetricIndexStructures•feedback•wab2cis•WIndex

248CHAPTER32.RESSOURCEN

Page 14: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

14 CHAPTER 1. WITTGENSTEIN ADVANCED SEARCH TOOLS

Figure 1.1: WAST Projektstruktur

Zu den Tools zählen alle Dinge, die …, darunter:

• wast-infrastructure• bug tracker• Versionierung• git• wiki

Die WAST-Infrastruktur (siehe Abschnitt 14.1 ab Seite 113) erlaubt es, dendeploy-Prozess und den Versionierungs-Prozess zu abstrahieren, indem alle Kom-ponenten unter einem Dach versammelt sind.

Zum Beispiel kompiliert und startet man dann die feedback-Komponente folgen-dermaßen:

./wast build wast-feedback-app && ./wast start wast-feedback-app

Die weiteren Komponenten funktionieren dann alle gleich und es ist wesentlicheinfacher, den Überblick zu behalten.

Alle von der WAST-Infrastruktur verwalteten Komponenten findet man ganzeinfach heraus, indem man

32.3. KONTAKT, ANSPRECHPARTNER 247

Figure 32.10: UML Legende: Interface

Figure 32.11: UML Legende: Class with Details

Page 15: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

1.5.WASTPROJEKTSTRUKTURINTERN15

Figure1.2:DieLandschaftvonWAST

./wast

ohneArgumentestartet.HierbeiwerdensowohlalleKomponentenalsauchAktionenangezeigt.

1.5.1VerwaltenvonKomponenteninWAST

Komponenten-MaintainerkönnenihreKomponenteindieGruppecis(Gitlabcisgroup2014)überführenlassen–dazuistdanneineMailanThomasnotwendig(glaubeich).Vorteiledaraus:

a)dasProjektwirdimgitlabnichtmehrgegendaspersönlicheProjektlimitbeiderRBGgezählt

b)dasProjektistweniger“personenbezogen”undkannbesservonNachfol-gern“geerbt”werden

Komponenten-Maintainer,dieihreKomponenteindieWAST-Infrastrukturhinzufügenwollen,machenfolgendes:

1.Zunächst,dieKomponentealsgit-submodule[link:http://git-scm.com/book/en/Git-Tools-Submodules]adden:

[email protected]:cis/wf.gitcomponents/wf

246CHAPTER32.RESSOURCEN

Figure32.8:UMLLegende:InterfaceInheritance

Figure32.9:UMLLegende:Dependencies

Page 16: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

16 CHAPTER 1. WITTGENSTEIN ADVANCED SEARCH TOOLS

2. Am besten direkt die Remote-Bezeichnung[link: http://git-scm.com/book/en/Git-Basics-Working-with-Remotes] origin in upstream umbenennen (derEinheitlichkeit halber)git remote rename origin upstream

3. Im eigenen Projekt die wesentlichen Dateien anlegen (oder die, die manfür nötig hält):

• wast.build• wast.check• wast.start• wast.stop• wast.restart

Beispiele hierzu finden sich hier:https://gitlab.cip.ifi.lmu.de/cis/wast-feedback/tree/master

1.6 Komponenten

In den folgenden Teilen werden die wichtigsten Komponenten wittfind (Kapitel 2ab Seite 19), SIS (Kapitel 3 ab Seite 31), feedback (Kapitel 4 ab Seite 71),wab2cis (Kapitel 5 ab Seite 77) und WIndex (Kapitel 6 ab Seite 79) besprochen.

32.3. KONTAKT, ANSPRECHPARTNER 245

Figure 32.6: UML Legende: Composition

Figure 32.7: UML Legende: Inheritance

Page 17: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartII

wittfind

17

244CHAPTER32.RESSOURCEN

Figure32.5:UMLLegende:Aggregation

Page 18: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

32.3. KONTAKT, ANSPRECHPARTNER 243

Figure 32.4: UML Legende: Directional Association

• express manual

+++ END DEPRECATED +++

32.3 Kontakt, Ansprechpartner

• Max• Flo• Daniel• Patrick• Bug-Tracker• Webseite• irc

Page 19: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter2

wittfind

Inhalt2.1Zweck............................20

2.2Kurzvorstellung......................20

2.3Funktionen.........................20

2.4BeschreibungderverwendetenTechnologien.....20

2.5Umfang,WertundGrößederCodebase.......20

2.6Mitwirkende........................20

2.7Import/ExportausPaper................20

2.7.1ResourceText:TEIP5conformXML........20

2.7.2ResourceLexicon:Electronicfull-formLexicon...21

2.7.3ThefinderApplicationsuite“.............21

2.7.4Implementationaspectsof...............22

2.7.5Lemmatizedandinvertedlemmatizedword-search.23

2.7.6Word-FormSearchandPart-of-SpeechTagging...23

2.7.7SemanticLexicalClassification............24

2.7.8SentencestructureandWildcards...........26

2.7.9Rule-basedlinguisticsearchwithPart-of-SpeechTag-ging(POS-tagging)...................26

2.7.10SearchwithoutAlternatives..............27

2.7.11SearchResultLayoutwiththeFacsimile.......27

19

242CHAPTER32.RESSOURCEN

Figure32.2:UMLLegende:SimpleAssociation

Figure32.3:UMLLegende:Cardinality

Page 20: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

20 CHAPTER 2. WITTFIND

2.1 Zweck

2.2 Kurzvorstellung

2.3 Funktionen

2.4 Beschreibung der verwendeten Technologien

2.5 Umfang, Wert und Größe der Codebase

sloccount [link: http://www.dwheeler.com/sloccount/]

2.6 Mitwirkende

2.7 Import/Export aus Paper

The web-based frontend WiTTFind consists of several web programs which offeran easy to use interface to query Wittgenstein’s Nachlass and presents all searchresults as HTML-transformation of the edited text together with an excerptfrom the original facsimile of Wittgenstein’s remark. For the texts available onWittgenstein Source1, every result is linked to Wittgenstein Source as well asto the Semantic web annotation tool Pundit Grassi et al. (2013 ˆ7) (see Figure[fig:search])

2.7.1 Resource Text: TEI P5 conform XML

The XML-Transcription of Wittgenstein’s Nachlass Pichler (2010), which wasdeveloped at WAB in Bergen, annotates the texts in greatest detail. All dele-tions and substitutions etc. of Wittgenstein are annotated in the XML-texts.The latter is too detailed in order to be used by WAST and thus a new TEI P5TEI Consortium (2009) compatible and reduced XML-Format (CISWAB) wasdefined. This text format is an optimal base for the cooperation between theWittgenstein researchers and programmers in the field of computational linguis-tic. The CISWAB texts are extracted via XSLT-transformation from WAB’sXML-transcriptions of Wittgenstein’s Nachlass Pichler et al. (2009).

1http:/www.wittgensteinsource.org

Chapter 32

Ressourcen

32.1 UML Legende

Figure 32.1: UML Legende: Class

32.2 Literatur

<#startdeprecated>

• Daniel Bruder, SIS – Symmetrische Indexstrukturen, Magisterarbeit, CIS,LMU, 2012, [webadresse]

• Stroustrup• Di Gennaro• Herb Sutter• Alexandrescu• gitlab manual• git manual• git extras• node manual• angular manual

241

Page 21: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

2.7.IMPORT/EXPORTAUSPAPER21

2.7.2ResourceLexicon:Electronicfull-formLexicon

Successfultextsearchescruciallyrelyontheavailabilityofanelectronicfull-formlexicon.FortheworkonWittgenstein’sNachlass,weusedCISLEXGuenthnerandMaier(1994),oneofthebiggestelectronicGermanfull-formlexica,whichhasbeendevelopedatCISoverthelast20years.WeextractedallwordsfromthetextsavailableonWittgensteinSource,thewordinformationfromCISLEXandextendedittothespeciallexicon,calledWiTTLex.Eachword-entryinWiTTLexisformattedaccordingtotheDELAformat,definedattheLab-oratoired’AutomatiqueDocumentaireetLinguistique(LADL),ParisGaston(1991).Thelexiconentriescontaintheword’sfull-form,lemma,lexicographicalwordform,inflectionandsemanticinformation.SearchqueriestoWiTTFindcanbegrammaticallyprocessedwiththehelpofWiTTLex.Figure[fig:dic]showsashortexcerptfromthelexicon.

[H]

Advokat,Advokat.N+HUM:neMgesagt,sagen.V:OZgesamte,gesamt.ADJ+NUM:aeFxp:aeFyp:aeFzp:aeNyp:\amUxp:neFxp:neFyp:neFzp:neMyp:neNyp:nmUxpdagestanden,dastehen.V+#2glänzende,glänzend.ADJ+ER+COL+GlanzFermat,.ENFermatsche,Fermat'sch.ADJ+ENrot,rot.ADJ+COL+Grundfarberötlicher,rötlich.ADJ+COL+Zwischenfarbe+KOMP:\deFxp:geFxp:gmUxp:neMxp:neMzp

[fig:dic]

2.7.3ThefinderApplicationsuite“

Inordertoprovideextendedlinguisticsearchcapabilitiesforexplorationsfromnon-technicalandnon-linguisticbackgrounds,asuiteoftoolswasdevelopedatCISSeebauer(2012;Krey2013;Fink2013;Volos2013).Withamixtureofimplicitandexplicitconversionsweareabletoprovideadvancedlinguisticsearchcapabilitiestoresearchersfromdifferentfieldsofthehumanities.Thenextsectionprovidesabottomupoverviewontheprogramsuite“,onesectionoutofWAST,thatisusedtofindtext,i.e.tofindutterancesofWittgenstein.

Everyqueryto“isinternallytransformedtoalocal-grammar-search-graphofthesearchtermsMaurice(1997).Initssimplestformthesegraphsareachainofthesearchterms.Butingeneralsearch-graphscancontainanarbitrarynumberofloopsandbranchestoexpresscomplexsearchpatternsFink(2013).

240CHAPTER31.NEXTSTEPS

Page 22: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

22 CHAPTER 2. WITTFIND

The system uses various strategies to match tokens in the text. It is able touse i.a. string-based matching, regular expressions, semantic and morphologicalinformation from dictionaries and arbitrary annotations from the searched textitself.

In order to provide a simple interface to the user and hide much of the com-plexities involved, queries from the user are automatically converted to local-grammar-search-graphs. A simple query language enables the user to search forsequences of arbitrary length or combine tokens with boolean operators Fink(2013). Furthermore, the system applies implicit conversions on the queries togenerate more natural search results.

2.7.4 Implementation aspects of

The tool is implemented in a client-server architecture. There are three maintools involved in the processing of queries: A server-, a client- and a display-tool. The client merely takes queries from the user and applies some very basictransformation to them before sending the actual query to the server. Thesetransformations mostly convert convenient wildcard expressions to valid morecomplex regular expressions.

On the server side each query is parsed and then transformed to a local-grammar,that is applied asynchronously to the different documents the query wishes tosearch. One running server instance is able to provide parallel searches over avarious set of different documents. All results are then send back to the client.

The third tool is a simple displaying tool, that is able to output the result of thequeries in different formats2. Together these three tools provide the backendto present query results, that are further used by the WiTTFind front end topresent the final results of queries.

[H]

[tab:wfbenchmark]

Query type Median (seconds)

strict 0.082word phrase 0.080lemma-based 0.088

inverted lemma-based 0.088sentence 0.169

local grammar (particle verbs) 0.214

2At the time being, there are only two formats supported; one format for the web-service,and another format for the terminal.

Chapter 31

next steps

31.1 E2E-Tests für Feedback, SIS, wittfind-web

31.2 Integration-Tests und Projekt-Organisation

31.3 Integration von SIS und Feedback inwittfind-web

31.4 Integration der restlichen 5000 FacsimileSeiten und Transkriptionen (in SIS und wf)

31.5 Erweiterung von WAST auf *AST: Öffnungund Aufbereitung für andere Editionspro-jekte.

239

Page 23: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

2.7.IMPORT/EXPORTAUSPAPER23

Table[tab:wfbenchmark]listsaviewbenchmarkingresultsofdifferentquerytypestoaserverinstancerunningonamoderndesktopPC3.Thenumberseachshowthemedianof10differentqueriestothetextoftheBigTypescriptAllquerieswherelimitedtoamaximumof100hits4.Itshouldbenoted,thatthelasttwolinesshowtheresultsofcomplexqueries,thatgenerateveryfewhits.Thesequeriestakealotmoretimetofinish(morethantwiceaslong),sincethewholedocumenthastobeprocessedandlocalgrammarsareusedtodisambiguate.

2.7.5Lemmatizedandinvertedlemmatizedword-search

Theelectronicfull-formlexiconWiTTLexallowstoperformlemmatizedqueriestotheNachlass.Forexample,thesearchfortheworddenken(think)returnsallsentenceswhichcontainmorphologicalvariantsoftheword,likedachte,gedacht.WealsoimplementedwiththehelpofWiTTLexaninvertedlemmatizedsearchwhereweusedthelemmaofthequeriedwordtoproduceallmorphologicalvariantsofit.Theworddachteleadstothelemmadenkenagain,fromwhichallwordvariantsarederived.

2.7.6Word-FormSearchandPart-of-SpeechTagging

Inthefull-formlexicon,WiTTLex,everywordisstoredtogetherwithitslexicalwordformasitisdefinedintheGermanCISLEX(seeTable[tab:tags]).

[H]

[tab:tags]

NameTagTranslation

Nomen<N>nounAdjektiv<ADJ>adjectiveVerb<V>verb

Determinativ<DET>determinerAdverb<ADV>adverbPartikel<PART>particle

Präposition<PREP>prepositionPräposition+Artikel<PDET>preposition+article

Konjunktion<KONJ>conjunction

3Intel2.90GHzQuadcore4Onthewebthelimitissetto25forunregisteredusers.

238CHAPTER30.HINWEISE

Page 24: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

24 CHAPTER 2. WITTFIND

Name Tag Translation

Interjektion <INTJ> interjectionVerbpartikel <VPART> verb particleEigenname <EN> proper name

The finder allows for the use of word forms as placeholders for words in a query.For example, the query Die <ADJ> Farbe finds all sentences that contain the nom-inative feminine definite article Die, followed by an adjective, which precedesthe noun Farbe (colour) as in sentence ([ex:farbe]).

[ex:farbe]

[ex:farbe:q] Die <ADJ> Farbe [ex:farbe:a] Ich könnte Dir die genaue Farbe derTapete zeigen, wenn hier etwas wäre was diese Farbe hat.5

To further reduce the syntactic ambiguity of the word forms in the text, weadditionally tagged the data with the Part-of-Speech (POS) treetagger Schmid(1994). The finder permits POS-tags to be used as placeholders for the selectionof syntactic word forms, as defined in the Stuttgart-Tübingen-Tagset Schiller,Thielen, and Teufel (1999). The user can decide to search for a lexical wordform (e.g. <ADJ>) or the syntactic word-form within the sentence (e.g. [ADJ*]).

2.7.7 Semantic Lexical Classification

In WiTTLex we classified nouns Strutynska (2012) and adjectives Krey (2013)semantically. According to the work by Langer and Schnorbusch Langer and(Hrsg.) (2005) we defined eleven classes for nouns (see: Table [tab:semnoun])and eleven classes for adjectives (see: Table [tab:semadj]).

[H]

[tab:semnoun]

Name Tag Translation Occurrences

Menschen <HUM> humans 140Tiere <T> animals 96

Pflanzen <PF> plants 26Objekte <OBJ> objects 1402Ereignisse <ER> events 589

5I could show you the exact colour of the wallpaper if there was anything around that hasthis colour.

Chapter 30

Hinweise

30.1 History Visualisierung (gource)

Es ist nicht nur schön anzusehen, sondern oft auch aufschlussreich, sich dieVisualisierung der history per gource [webhinweis] anzusehen, um zu verstehenwie ein Projekt gewachsen ist

237

Page 25: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

2.7.IMPORT/EXPORTAUSPAPER25

NameTagTranslationOccurrences

Zustände<ZU>states51Eigenschaften<EIG>pproperties236Temporalia<TEMP>time49Eigennamen<EN>propernames60Numeralia<NUM>number47Diversa<SONST>other713

NameTagTranslationOccurrences

Farben<COL>colour974Numeralia<NUM>number1258Relation<REL>relation2517

Eigennamen<EN>propernames17Temporalia<TEMP>time619Evaluation<EVAL>evaluation1732Zustände<ZU>states6629

Komparativa<KOMP>compariative2080Stilistika<STIL>style1917

Eigenschaft<EIG>property382Ereignisse<ER>proppperty187

InourinvestigationsinWittgenstein’sBigTypescript(BT)6,wefoundthatthereareabout1800nounsoutofall46000wordsinthedata(see:Table[tab:semnoun]and[tab:semadj]).AlltheTagsfromtheTablescanbeusedinWiTTFind.Forexample,thequery<EN>und<EN>returnsthesentence([ex:frege])inwhichthetwopropernamesFregeschenandRussellschenarejoinedbythecoordinatingconjunctionand.

[ex:frege]

[ex:frege:q]<EN>und<EN>[ex:frege:a]UnzulänglichkeitderFregeschenundRussellschenAllgemeinheitsbezeichnung.7

6http://www.wittgensteinsource.org/Ts-213_n7ShortcomingsofthedenominationofuniversalitymadebyFregeandRussell.

236CHAPTER29.WORKFLOWS

Page 26: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

26 CHAPTER 2. WITTFIND

In cooperation with the Faculty of Philosophy, Philosophy of Science and theStudy of Religion, at the University of Munich (Rothhaupt Rothhaupt (1996)),we implemented a first semantic classification of Wittgenstein’s colour vocabu-lary together with a special HTML-interface for querying colours in the Nachlass.We found, that five different categories for colours are optimal for Wittgen-stein’s Nachlass: Grundfarbe (primary colour), Zwischenfarbe (intermediatecolour), Transparenz (transparency), Glanz (gloss) and Farbigkeit (colourness)Krey (2013). Table [tab:sem] shows the different labels for colours and thenumber of their occurrences in the text.

In the web-frontend WiTTFind, the user can select between different colourcategories (see: Table [tab:sem]), view statistics and query Wittgenstein’s Nach-lass.

2.7.8 Sentence structure and Wildcards

For the Wittgenstein researchers it is very important to take the sentence struc-ture into account. To enable users to specify the sentence structure withinqueries, we introduced sentence structuring tags in queries, such as <BOS> (thebeginning of a senctence), <EOS> (the end of a sentence) and <PUNCT> for punc-tuation characters. The wildcard operator * can be used as placeholder forarbitrary character sequences. The query: <BOS> Ich meine nur <PUNCT> * ** <PUNCT> <EOS> would return all sentences that consist of six words startingwith the sequence of three tokens Ich meine nur followed by a punctuationcharacter as in example ([ex:sage])

[ex:sage]

[ex:sage:q] <BOS> Ich meine nur <PUNCT> * * * <PUNCT> <EOS> [ex:sage:a] Ichmeine nur, was ich sage.8

[tab:sem]

|c|c|p2.0cm|c| Name & Tag & Translation & OccurrencesGrundfarbe & <Grundfarbe> & basic colour & 454Zwischenfarbe & <Zwischenfarbe> & intermediate colour & 301Transparenz & <Transparenz> & transparency & 105Glanz & <Glanz> & gloss & 2Farbigkeit & <Farbigkeit> & colourness & 29

2.7.9 Rule-based linguistic search with Part-of-SpeechTagging (POS-tagging)

To enrich the number of found verbs concerning a search query, we implementedan automatic particle-verbs detection and distinction. Particle-verbs are marked

8I only mean, what I say.

29.4. BUG TRACKING WORKFLOW 235

Figure 29.4: Bug Tracking Workflow

Page 27: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

2.7.IMPORT/EXPORTAUSPAPER27

intheirlexicalentryanddividedintoverbandparticle.IntheBigTypescriptwefoundalmost750verbswithseparatedparticles.Todisambiguatetheseparatedparticlesfromprepositions,weusePart-of-Speechtaggingandlocalgrammars.Forexample,thequerywiththeparticleverbdastehenwouldextractinstancesas:stehtklarda…inwhichtheverbparticleda,whichmayoccurinGermanseparatelyfromtheverbstehen,isrecognizedassuchandnotasapreposition(see:Figure[fig:dastehen]).

2.7.10SearchwithoutAlternatives

OnecharacteristicfeatureofWittgenstein’sNachlassis,thatWittgensteinchangedhistextsveryoftenandasaresulttheNachlassoffersalotofdifferentreadings.Toenablethefindingofremarksinallofthelatter,inabackgroundprocessofthefinderapplication,wegeneratealldifferentreadings,whichareprocessedsimultaneouslySeebauer(2012).

2.7.11SearchResultLayoutwiththeFacsimile

LudwigWittgenstein’sNachlassishighlyheterogeneous.Itconsistsofalargenumberoftexts,someofthemhandwritten,withnumerouspassageseditedfromtheauthorhimself.Theresearcherscanonlyappreciatethefoundremarkstothefullestwithallitseditions,errorsandoverallform,iftheyseenotonlytheHTML-transformationoftheedition,butaswelltheiroriginalfacsimilewhichshouldbedisplayedsimultaneouslyRothhaupt(2006).Onlythiscom-binedviewprovidesthepossibilityforcomparisonandanalysisoftheoriginalmaterial,whichcarriesthecompletesetofinformation.Inordertoimplementthislayout,itwasnecessarytoOCRallfacsimileofWittgenstein’sNachlass,ex-tractthecoordinatesofhisremarksandlinkthemtothesearchresultaccordingtotheirsiglumGotschareketal.(2011).AlltheworkwasdonewithABBYYFineReaderandadditionallydevelopedPERLprograms.ThehighlightinginthedisplayofthefacsimileisdonewithCSStechniqueswithintheHTMLPageLindinger(2013).

234CHAPTER29.WORKFLOWS

Figure29.3:WASTDataWorkflow

Page 28: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

28 CHAPTER 2. WITTFIND 29.4. BUG TRACKING WORKFLOW 233

Figure 29.2: Continuous Integration

Page 29: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartIII

SIS

29

232CHAPTER29.WORKFLOWS

Figure29.1:gitbranchingmodel

Page 30: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter 29

Workflows

29.1 git branching model workflow

In der Entwicklung der WAST-Landschaft arbeiten wir mit dem sehr bekanntenund verbreiteten git branching model von dieser Seite1 — Abbildung 29.1 aufSeite 232 fasst den git branching model workflow an dieser Stelle kurz zusam-men.

29.2 Continuous Integration Workflow

Abbildung 29.2 auf Seite 233 verdeutlicht den Workflow einer CI, für mehrInformationen siehe auch das Kapitel Continuous Integration.

29.3 WAST pipeline

Abbildung 29.3 auf Seite 234 gibt einen Überblick, wie die WAST-pipeline (inzunehmender Kombination mit dem Unified Deployment-Prozess) aussieht:

29.4 bug tracking workflow

Graphik Abbildung 29.4 auf Seite 235 fasst noch einmal als Überblick den BugTracking Workflow zusammen – für eine insgesamte Beschreibung siehe auchKapitel [Bug Tracker][].

1http://nvie.com/posts/a-successful-git-branching-model/

231

Page 31: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter3

SIS:SymmetricIndexStructures

Inhalt3.1Einführung.........................323.2Zweck............................323.3Kurzvorstellung......................323.4VerwendungaufderKommandozeile.........323.5Überblick..........................36

3.5.1Projektstruktur.....................363.5.2Schichten........................373.5.3Klassen.........................37

3.6Ebenen...........................423.6.1C++-Ebene.......................423.6.2Web-Ebene.......................613.6.3NodeAddon.......................673.6.4NächsteSchritte....................67

SIS(undseinWeb-Teil)bestehtausmehrerenSchichtenunddemineinander-greifenverschiedenerTechnologienundFrameworks.

AlledieseTeilewerdenindennächstenKapitelnbesprochen:

•DieVerwendungaufderKommandozeileabSeite32•DieSchichtenderC-,C++-undWeb-EbeneabSeite37•SpezielleTechnikenderC++-ProgrammierungabSeite42

31

230CHAPTER28.ÜBERBLICKSTABELLEN

Page 32: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

32 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

3.1 Einführung

SIS, die Symmetrischen Index Strukturen sind Endliche Automaten in Formvon SCDAWGs (Symmetric Compacted Directed Acyclic Word Graphs), welchees erlauben, Texte zu indexieren und während des Lookups Vorschläge undVervollständigungen sowohl klassisch nach-rechts als auch nach links zu geben.

Diese werden detailliert in (Daniel Bruder 2012) besproche, welches aufbaut auf(Gerdjikov et al. 2013), und dieses im Wesentlichen mit (Blumer et al. 1987)verknüpft.

Die Grundidee hinter SIS ist folgende: Man nehme zwei nicht-symmetrischeCDAWG-Automaten – in linearer Zeit und auf linearem Raum direkt, on-lineerstellt (Inenaga et al. 2001) –, und befülle einen mit einem Text in “normaler”,links-nach-rechts-Richtung (left to right, LTR), und den anderen in umgekehrterRichtung (RTL). Dann identifiziere man die identischen States dieser beidenAutomaten (Gerdjikov et al. 2013). Daraufhin annotiere man die Automatenmit den Hinweisen auf die Dokumente, für welche sie stehen ((Daniel Bruder2012))

3.2 Zweck

3.3 Kurzvorstellung

3.4 Verwendung auf der Kommandozeile

Die ausführbare Datei sis (im Verzeichnis build/bin/sis) erlaubt zwei ver-schiedene Modi: einmal zum Indexieren eines vorhandenen Korpus (sis index)und zum anderen zur Suche auf einem bestehenden Index (sis context).

Ein erster Versuch auf Kommandozeile ergibt folgendes Ergebnis:

> bin/sisThis is SIS. Please see `sis --help' for available commands and options

You can get additional help using `sis <COMMAND> --help'

Available COMMANDs are:contextindex

Und der Aufruf der Hilfe ergibt folgendes:

28.2. MITWIRKENDE 229

Komponente Teil Personen Von Bis

SIS alle 4 Schichten Daniel Bruder 01/2012 dato

Page 33: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.4.VERWENDUNGAUFDERKOMMANDOZEILE33

>bin/sis--help

sis---

Usage:sis[GENERALOPTIONS]COMMAND[COMMANDOPTIONS]...

Allowedgeneraloptions:-h[--help]showhelpmessage-v[--version]showversion--commandsshowavailablecommands-i[--input]arginputfiles

SISfunktioniertalsoähnlichwiegitmitdemHauptbefehlsisunddenUnter-Kommandosindexundcontext.

ZujedemUnterkommandogibtesnunnocheineweitereHilfe,welchediespeziellenArgumenteerklärt–hierfürsisindex:

>bin/sisindex--helpOptionsforcommand'index':-o[--output]argoutputname-f[--thefile]argfilelistinginputfiles

Undhierfürsiscontext:

>bin/siscontext--helpOptionsforcommand'context':-w[--width]arg(=10)lr-contextwidth-q[--query]argquerystring-p[--print-filename]printthefilenames

BeideSub-Kommandoserwartenalso(lautdengeneraloptions)mindestenseinInputfilemit--inputbzw.-i:

bin/sisindex-iINPUTFILEbin/siscontext-iINPUTFILE

FürdasSub-KommandoindexwirdalsInputfileentweder

a)mit-ieineAuflistungvonDateienerwartet:

•bin/sisindex-ifile1-ifile2

228CHAPTER28.ÜBERBLICKSTABELLEN

Figure28.1:WASTKomponentenundDependencies

Page 34: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

34 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

b) mit -f eine Datei, welche die Input-Dateien auflistet (falls die Input-Dateien mit -i zu viele werden):• bin/sis index -f file.list

Die Input-Dateien für sis index müssen folgendermaßen beschaffen sein:

a) entweder alle Dateien sind XML-Dateien (nach dem CISWAB-TEI-Standard)

b) alle Dateien sind plain-text-Dateien

(Um hier mehr Flexibilität anbieten zu können müssen noch mehr features füreinen Importer geschrieben werden, siehe https://gitlab.cip.ifi.lmu.de/bruder/sis3/issues/93; desweiteren werden bei plain-text Dateien die Dateinamen alsSiglum interpretiert).Solange die Importer noch nicht komplett vollendet sind, gibt es eine Zwischen-lösung, plain text Dateien herzustellen:Man kann die Testdaten aus src/features/data/Ts-213 und den Extractorunter src/features/data/Ts-213/extract.sh verwenden um plain-textDateien herzustellen.Der Extractor liefert die Dateien in das Verzeichnis work/ aus, man ist aberselbst dafür zuständig, dieses frei zu halten (also gegebenenfalls zu löschen vorder nächsten Extraktion).

> ./extract.shUsage:./extract.sh [7bit|utf8]

(results will be written to work/)(make sure you erase work/ before)

Der Extractor ist, wie gesagt, nur eine Zwischenlösung lässt sich aber verwenden.Der Befehl …

> ./extract.sh utf8

… wird plain text Dateien nach work/ extrahieren, welche sich für bin/sisindex -i file1 -i file2 verwenden lassen.Idealerweise legt man eine Datei allfiles.list o.ä. an …

> find ../src/features/data/Ts-213/work/utf8 \-type f \-iname '*.satz' \-exec echo `pwd`/{} \; \> Ts-213.allfiles.list

28.2. MITWIRKENDE 227

* [gpp](http://files.nothingisreal.com/software/gpp/gpp.html)* [ppp-typesetting-pipeline](https://github.com/typesetters/p5-App-pandoc-preprocess)

* [dot](http://www.graphviz.org/Documentation.php)/[neato](http://www.graphviz.org/pdf/neatoguide.pdf)* [rdfdot](RDF::Trine::Exporter::GraphViz)* [ditaa](http://ditaa.sourceforge.net/)

* [Image::Magick](http://www.imagemagick.org/) (image manipulation)* [rsvg-convert](http://live.gnome.org/LibRsvg)

* [yuml](https://github.com/wandernauta/yuml) (install as python module using `pip install https://github.com/wandernauta/yuml/zipball/master` or `easy_install https://github.com/wandernauta/yuml/zipball/master`)* [plantuml](http://plantuml.sourceforge.net/)

28.1.2 Links

[^wf]: <https://gitlab.cis.lmu.de/wast/wf>[^SIS-backend]: <https://gitlab.cis.lmu.de/wast/sis3/tree/master/src>[^SIS-frontend]: <https://gitlab.cis.lmu.de/wast/sis3/tree/master/web>[^wittfind-web]: <https://gitlab.cis.lmu.de/wast/wittfind-web>[^feedback]: <https://gitlab.cis.lmu.de/wast/wast-feedback>[^feedback-link]: <http://wastfeedback.cis.uni-muenchen.de/>[^e2e]: <https://gitlab.cis.lmu.de/wast/wittfind-web/tree/development/tests>[^reader]: <https://gitlab.cis.lmu.de/wast/wittfind-web/>[^cmake]: <http://www.cmake.org/>[^lest]: <https://github.com/martinmoene/lest>[^node]: <http://nodejs.org/>[^npm]: <http://nodejs.org/>[^expressjs]: <http://expressjs.com/>[^angularjs]: <https://angularjs.org/>[^bower]: <http://bower.io/>[^phantomjs]: <http://phantomjs.org/>[^casperjs]: <http://casperjs.org/>[^turn.js]: <http://www.turnjs.com/>[^doxygen]: <http://doxygen.org/>[^sis-link]: <http://sis.cis.lmu.de/>[^wf-link]: <http://wittfind.cis.lmu.de/>[^wittfind-link]: <http://wittfind.cis.lmu.de/>[^helppage]: <https://gitlab.cis.lmu.de/wast/wittfind-web>

28.1.3 Dependency Graph (experimental)

28.2 Mitwirkende

Page 35: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.4.VERWENDUNGAUFDERKOMMANDOZEILE35

…umdieseineinemStückfütternzukönnen:

>bin/sisindex-fTs-213.allfiles.list-oallfiles.index

LetztererBefehlerstellteinenIndexfüralleDateien,dieinTs-213.allfiles.listgelistetsindundlegt–wegenderzweistufigenSerialisierung(siehedaszuge-hörigeKapitel)–,zweiSerialisierungsdateienan:allfiles.indexfürdenC++-TeildesAutomatenundallfiles.index.cfürdenC-TeildesAutomaten(esseiandieserStellekurzdaraufhingewiesen,dasssichallfiles.index.cauchmitderexecutablederC-Schicht,unterbin/cautverwendenlässt,ohnedenC++-Teilzubenötigen):

>ls-lhallfiles.index*-rw-r--r--1dbruderstaff6,1M11Mär13:26allfiles.index-rw-r--r--1dbruderstaff12M11Mär13:26allfiles.index.c

NachdemalsoderIndexangelegtist,lässtsichaufdiesemSuchen–hierbeifungiertdervorhergehendeOutput(-oallfiles.index)diesmalalsInputfürbin/siscontext:

>bin/siscontext-iallfiles.index-qerstAutomatonloadedsizeis5548results.size()=599'odererinnerstDuDicha''ErinnerstDuDichd''oranerinnerstDuDich?''everifizierstDudas??''daßmanerstahnungslo''ichdocherstaufbauen;'[...]

LautderHilfezusiscontext(bin/siscontext--help)lässtsichunteranderemdieBreitederausgeschnittenenErgebnisseeinstellen(-wWIDTH):

>bin/siscontext-iallfiles.index-qerst-w20Automatonloadedsizeis5548results.size()=599'sgesagt;odererinnerstDuDichandieStim''ErinnerstDuDichdaran,daß''“WoranerinnerstDuDich?—''WieverifizierstDudas?—dannwe''nichtso,daßmanerstahnungslosist,und'

226CHAPTER28.ÜBERBLICKSTABELLEN

*[^bower]*client-seitigedependencieswerdendurch[^bower]installiert

*[^npm]*server-seitigedependencieswerdendurch[^npm]installiert

*MongoDB

28.1.1.7E2E

Component:E2EDescription:End-to-endtestsfürwittfind-web:kompletteUser-SzenariendurchspielenMaintainer:[email protected],TBDLinkexternal:---Repository:gitlab.cis.lmu.de/wast/wittfind-web/tree/development/testsDependencies:

*[^node]/[^npm]*[^casperjs]

*[^phantomjs]

28.1.1.8Reader

Component:ReaderDescription:Reader-ApplikationfürFacsimileMaintainer:[email protected](etal.?)Linkexternal:---Repository:gitlab.cis.lmu.de/wast/wittfind-web/tree/development/testsDependencies:

*PHP(Version?)*[^turn.js]*...(?)

28.1.1.9wast-doc

Component:wast-docDescription:DokumentationfürWASTMaintainer:[email protected]/TBDLinkexternal:www.cip.ifi.lmu.de/~bruder/wast/Repository:https://gitlab.cis.lmu.de/wast/wast-docDependencies:

*[make](https://www.gnu.org/software/make/manual/make.html)*[pandoc](johnmacfarlane.net/pandoc/)

Page 36: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

36 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

'rt müßte ich doch erst aufbauen; oder: von''gen: Ein Satz folgt erst aus ihm, wenn er da''ch mir vielmehr nun erst ausrechnen. '' an, die deren Sinn erst bestimmen; was nich'[...]

3.5 Überblick

Im Folgenden ein Überblick über die Projektstruktur von SIS, die Schichten,aus welchen SIS sich zusammensetzt, und die wichtigsten Klassen innerhalb vonSIS.

3.5.1 Projektstruktur

Hier ein Überblick und eine Beschreibung der wichtigsten Teile der Projektstruk-tur:

.|-- build # Out-of-source dir für cmake / Kompilierung| |-- bin # Platz für die gebildeten exeucatables| |-- lib # --- " --- libraries| `-- src # --- " --- *.o|-- cmake # cmake-module für Makefile-Generation|-- etc # Test-Daten und anderes|-- src # C++-Sources| |-- adapter # Alle Adapter-Klassen (wrappen vendor/cautomata)| | |-- VoidSequence| | `-- inenagaCDAWG| |-- features # Tests| | `-- data # Test-Daten| `-- indexer # Indexer-Klassen|-- vendor # 3rdparty libs (eingebunden als git submodules)| |-- cautomata # C-Schicht von Petar Mitankin, Sofia| |-- make_unique # wurde im C++11-Standard schlicht vergessen| |-- pugixml # XML-Modul| |-- serialization # ...| `-- testing`-- web # Web-Schicht: MEAN-Stack

|-- bower_components # Client-seitige Javascript-Bibliotheken|-- build # hier wird das node-addon gebildet|-- cpp # Hier liegen die Klassen, die src/ nach JS wrappen|-- node_modules # Server-Seitige Module|-- public # Client-Seite| |-- javascripts| `-- stylesheets|-- routes # Server-Seite: Routes`-- views # Client-Seite: Views

`-- partials

28.1. KOMPONENTEN, MAINTAINER, DEPENDENCIES 225

* git-submodules* lest

* boost* ... (?)

28.1.1.4 Alternativen-Suche

Component: "Alternativen-Suche"Description: Ausformulierung von AlternativenMaintainer: [email protected] / [email protected] / TBDLink external: wittfind.cis.lmu.deRepository: gitlab.cis.lmu.de/wast/wittfind-webDependencies:

* perl-module (?)* XML-Twig (?)* ... (?)

* ... (?)

28.1.1.5 Helppage

Component: HelppageDescription: Beispiel-Anfragen und Hilfe für wittfindMaintainer: [email protected] external: wittfind.cis.lmu.de/help.phpRepository: gitlab.cis.lmu.de/wast/wittfind-webDependencies:

* PHP (Version?)* ... (?)

* ... (?)

28.1.1.6 Feedback

Component: FeedbackDescription: Bug Reports für AussenstehendeMaintainer: [email protected], TBDLink external: wastfeedback.cis.lmu.deRepository: gitlab.cis.lmu.de/wast/wast-feedbackDependencies:

* curl* gitlab user token / "FeedbackBot"-User* MEAN-Stack

* [^node] / [^npm]* [^expressjs]* [^angularjs]

Page 37: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.5.ÜBERBLICK37

3.5.2Schichten

•Schicht1:C1

–BereitstellungvonSCDAWG-AutomatenfüreinzelneWörter/Wörterbücher

•Schicht2:C++(11)2

–ErweiterungderSCDAWGsausderC-Schicht,umdiesefürdieSucheinnerhalbvonDokumenten(stattWörtern)verwendbarzumachen

•Schicht3:Web3mit:

–Serverseite

*Nodejs+ExpressJS*nodeaddonalsWrapperderC++-Automaten(ermöglichtdasEinbindenvonC++-ObjekteninJavascriptcode)4

–Client-Seite

*AngularJS5

3.5.3Klassen

ZunächsteinÜberblick:

ImFolgendeneineKurz-Besprechungder(wichtigsten)Klassen,ihresZwecksundihrergrundlegendenEigenschaftenausderC++-Schicht,welchediestructsausderC-SchichtwrappenunddokumentindexierendeEigenschaftenzurVerfügungstellen:

3.5.3.1*Adapter

Jedem*AdapterliegteinC-Structzugrunde,vergleichedasentsprechendeKapi-telzumgrundlegendenWrapping-Pattern

1zufindeninvendor/cautomata2zufindeninsrc/3zufindeninweb/4http://nodejs.org/api/addons.html5http://angularjs.org/

224CHAPTER28.ÜBERBLICKSTABELLEN

*wf*PHP*Apache*E2E-dependencies:

*[^node]/[^npm]*[^casperjs]

*[^phantomjs]

28.1.1.3SIS

SIS-frontend

Component:SIS(frontend)Description:Maintainer:bruder.cis.lmu.deLinkexternal:sis.cis.lmu.deRepository:gitlab.cis.lmu.de/wast/sis3/tree/master/webDependencies:

*MEAN-Stack*[^node]/[^npm]*[^expressjs]*[^angularjs]*[^bower]

*client-seitigedependencieswerdendurch[^bower]installiert

*[^npm]*server-seitigedependencieswerdendurch[^npm]installiert

*MongoDB

SIS-backend

Component:SIS(backend)Description:Maintainer:[email protected]:sis.cis.lmu.deRepository:gitlab.cis.lmu.de/wast/sis3/tree/master/srcDependencies:

*`gcc>4.7`*cmake*(doxygen)*git

Page 38: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

38 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

Figure 3.1: SIS Schichten

3.5.3.2 Document

Ein sis::Document stellt die grundsätzliche Basis dessen dar, was letztendlichvon einem DocumentIndexingAutomaton verarbeitet und indexiert wird.

Es hat zwei wesentliche members:

• filename_ und• contents_

wobei filename das Siglum darstellt und contents den tatsächlichen Inhalt.

In einem Stück wie diesem etwa…

<s n="Ms-115,3[2]_1" ana="facs:Ms-115,3 abnr:7 satznr:22">“Was heißt es: ‘dieser Gegenstand ist mir<lb/> wohlbekannt?’”

</s>

entspräche:

• filename == Ms-115,3[2]_1• und contents == “Was heißt es: ‘dieser Gegenstand ist mir

wohlbekannt?’”

Chapter 28

Überblickstabellen

28.1 Komponenten, Maintainer, Dependencies

28.1.1 Komponenten, Beschreibungen, Maintainer

28.1.1.1 wf

Component: wfDescription:Maintainer: [email protected] external: wittfind.cis.lmu.deRepository: gitlab.cis.lmu.de/wast/wfDependencies:

* `gcc > 4.7`* boost

* ... (?)* cmake* (doxygen)

28.1.1.2 wittfind-web

Component: wittfind-webDescription:Maintainer: [email protected] et al.Link external: wittfind.cis.lmu.deRepository: gitlab.cis.lmu.de/wast/wittfind-webDependencies:

* git* git-submodules

223

Page 39: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.5.ÜBERBLICK39

Figure3.2:KlassenarchitekturvonSIS

222CHAPTER27.DANK

Page 40: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

40 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

Hinweise

• Document ist hinsichtlich des string-Typs templatisiert: damit lässt sichbesser mit dem unterliegenden string-Typ der C-Schicht, VoidSequenceumgehen.

• Die C-Schicht verlangt unbedingt, dass zu einem gegebenen Zeitpunkteinmal das Makro mSetEndianness() aufgerufen wird. Anonstenpassieren können sehr böse Dinge während der Serialisierung geschehen(bytes können falsch herum eingelesen werden, da die Endianness nichtrichtig definiert ist) und damit nur sehr schwer nachvollziehbare Fehlerentstehen. Daher ruft der Konstruktor von Document dieses Makro auf.

• Die contents eines Document werden aus Platzgründen nicht serialisiert.Schlussendlich sind diese Inhalte in automaton()->data_ verfügbar(welches serialisiert wird) und über entsprechende VoidSequenceAdapter::iteratorsrekonstruierbar (in Zusammenarbeit mit DocumentIndex )

3.5.3.3 DocumentCollection

DocumentCollection ist im wesentlichen eine Liste von Documents.Ihm können auch XML-Dateien als Input gegeben werden und er erstelltdaraus “virtuelle” Dokumente (durch die Methode import()), als wären dieeinzelnen Documents in tatsächlichen Dateien vorgelegen (s.o. das Beispiel mitSiglum/Contents im Kapitel Document).Die Methode import() verwendet pugixml(Arseny Kapoulkine 2014a), ein ex-ternes Modul aus dem vendor-Teil des Projekts (als git submodule von (ArsenyKapoulkine 2014b)).

3.5.3.4 DocumentIndex

Ein DocumentIndex ist eine std::map die Documents und ihre Positionen ver-waltet:

typedef Document<StringType> key_type;typedef DocumentPos<StringType> value_type;typedef std::map<key_type, value_type> docinfo_t;/// @todo rename: value_type -> mapped_type (do this everywhere)

Document und ihre DocumentPos werden im index-ing-Schritt des DocumentIndexingAutomatonangelegt:

• zu jedem Document gehört ein sinkstate im Automaten, d.h. ein Final-State

Chapter 27

Dank

• Viele• viele

– sehr– sehr– viele

221

Page 41: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.5.ÜBERBLICK41

Hinweise

•Esfindensichz.T.nochveralteteAPIsinnerhalbdieserKlasse,diefürdenVorgängervonDocumentPos,DocumentPositionsgedachtwaren.DiesewerdenStückfürStückentferntwerden,sindabermitdeprecatedgekennzeichnet.

3.5.3.5DocumentIndexingAutomaton

DerDocumentIndexingAutomaton(Abbildung3.3aufSeite41istdiekomplex-esteKlassehinsichtlichseinerMember.EristdiezentraleStelle,anderalleInformationenzusammenlaufen:

•HinzufügenvonDocumentszudenC-Automatenundentsprechendes•IndexingdieserDokumente,d.h.

–verwaltendersinkstates–undderDocuments

•RetrievalundSucheaufdenAutomaten,unddabei

–“Ausschneiden”vonpassendenErgebnissen–undAuslieferungderselbenandieClients

Figure3.3:DocumentIndexingAutomatonUML

220CHAPTER26.DISCLAIMER

Page 42: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

42 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

3.5.3.6 DocumentIndexingAutomatonAbstract

Die Basis-Klasse für DocumentIndexingAutomaton (Abbildung 3.4 auf Seite 42)

Figure 3.4: DocumentIndexingAutomatonAbstract UML

3.5.3.7 DocumentInformation

3.5.3.8 DocumentPositions

3.5.3.9 FindResult

3.5.3.10 TEIReader

3.6 Ebenen

SIS setzt sich aus mehreren Ebenen bzw. Schichten zusammen, welche im fol-genden besprochen werden:

• C-Ebene• C++-Ebene• Web-Ebene

3.6.1 C++-Ebene

• TDD: Test Driven Development [link: http://www.agiledata.org/essays/tdd.html]bzw. [link: späteres tdd kapitel]

Chapter 26

Disclaimer

Diese Dokumentation ist ein Work-in-Porgress-Produkt und daher:

a) in manchen Teilen noch nicht fertigb) in anderen Teilen schon deprecated.

Da die Dokumentation auch in einer kollaborativen Team-Arbeit erstellt undgepflegt werden soll, bitte bei Fehlern diese unbedingt korrigieren undper gitlab als Änderungen anbieten, danke!

219

Page 43: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN43

–lest(MartinMoene2013)

•make_unique(C++1yStandardCommittee2014)•GitSubmodules(“Git-Submodules”2014):gitsubmodulesincmake

(DanielBruder2014)•anderevendor-submodulesaufzählen•TemplateMeta-Programmierung6

–[TMPvorstellen]

•Serialization(siehemehrzumThemaSerialisierungallgemeinimKapi-telSerialisierungundwieSerialisierunginSISgemachtwirdimKapitelZweistufigeSerialisierung)

–cereal(uscilab2014)–[zweiSerializationModulevorstellen]–[link:cereal]–[link:boostserialization]

3.6.1.1DetaillierterWalk-throughdurchspezielleTeile

Automatentheorie:SCDAWGS,BijektiveAbbildung

Automatenkonstruktion

Dokumenterweiterung

WrappingvonC-StruktureninC++-Klassen

WarumCStrukturenWrappen?

Beispiele(CodeWalkThrough)HiereinBeispielfüreinC-Header-File,daseinstructbeschreibt.

1#ifndef_HEADER_FILE_COMPRESSED_AUTOMATON_2#define_HEADER_FILE_COMPRESSED_AUTOMATON_3

4#definemCompressedAutomatonGetStatesStored(aut)((aut)->statesTransitions->seqStored)5

6#definemCompressedAutomatonGetTransitionsStored(aut)((aut)->transitionsStart->seqStored)7

8typedefstructtCompressedAutomaton{9UINTinitialState;

10UINTSequence*statesTransitions;

6link:späteresKapitel(infussnote)

Page 44: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

44 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

11 UINTSequence * statesNumberOfTransitions;12 UINTSequence * statesEnd;13 UINTSequence * transitionsStart;14 UINTSequence * transitionsTo;15 VoidSequence * data;16 TarjanTable * tt;17 } CompressedAutomaton;18

19 extern CompressedAutomaton * CompressedAutomatonInit( UINT symbolSize );20 extern void CompressedAutomatonAddState( CompressedAutomaton * aut, UINT state );21 extern void CompressedAutomatonAddTransition( CompressedAutomaton * aut, UINT stateFrom, UINT start, UINT stateTo );22

23 // ...

Und hier die wrappende C++-Klasse mit “sauberen” Konstruktoren (CTORs)und (automatischen) Desktruktoren (DTORs)

1 /// @brief Adapter for CompressedAutomaton2 template<class StringType>3 struct CompressedAutomatonAdapter4 : virtual public CompressedAutomatonAbstract<StringType>5 {6

7 using CompressedAutomatonAbstract<StringType>::traits::string_type;8 using CompressedAutomatonAbstract<StringType>::traits::symbol_size;9

10 protected:11 using adaptee_handle =12 std::unique_ptr< CompressedAutomaton, decltype(&::CompressedAutomatonFree)>;13 adaptee_handle adaptee_;14

15 public:16 explicit CompressedAutomatonAdapter()17 : adaptee_ { ::CompressedAutomatonInit(symbol_size), &::CompressedAutomatonFree }{}18 virtual ~CompressedAutomatonAdapter() {}19

20

21 //——————————————————————————————————————————————————————————————————————————//22 // M A P P I N G I N T E R F A C E (AutomatonAbstract) //23 //——————————————————————————————————————————————————————————————————————————//24 public:25 virtual void shrink() override;26 virtual void write(FILE * fp) const override;27

28 // ....29

30 //——————————————————————————————————————————————————————————————————————————//31 // M A P P I N G I N T E R F A C E (CompressedAutomaton) //32 //——————————————————————————————————————————————————————————————————————————//33 public:34 virtual void add_state(UINT state) override;35 virtual void add_transition(UINT stateFrom, UINT start, UINT stateTo) override;

Template Meta Programmierung in C++-Automaten (Vergleicheauch das Kapitel Techniken/TMP)

Part X

Appendix

217

Page 45: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN45

WieimKapitel[Techniken/TMP]ausgeführt,erlaubtesTemplateMetaPro-grammierung,oderkurz:TMP,bestimmteEntscheidungenundBerechnungenzurCompile-Zeitauszuführen,bzw.dieseindieCompile-Zeitzuverlagern.

DaskanneinerseitserhöhteTyp-Sicherheitgewährleisten(beiwenigerCode-Aufwand),schlichtZeitersparen,oder,wieindiesemFall,dieKonstruktion,oderbesser:die“Zusammenstellung”vonKlassenübernehmen.

Konkretverstandenwerdensollunter“Zusammenstellung”indiesemFall,dassdurchdieTechnikderTMPeinekohärenteKlassegeschriebenwird,diesichjenachInstantiationunterschiedlich“verhält”.

GanzgezieltwirddieseTechnikinFormderAutomaten–kurzgesagt–,auffolgendeWeisegenutzt:

DasC-structwird,wieimvorhergehendenBeispielmiteinersymbolSizekon-struiert.DieUINTsymbolSizewirdanderswodefiniertundkann(bzw:soll)zweiunterschiedlicheunsignedint-Werteannehmen:

•1,um7-bitStringszuverarbeiten•4,umUTF-8zuverarbeiten

VergleichefolgendeCode-TeileausderC-Schicht:

1//typical.h2typedefunsignedcharU8;3typedefunsignedshortintU16;4typedefunsignedintU32;5typedefunsignedlonglongU64;6

7typedefcharS8;8typedefshortintS16;9typedefintS32;

10typedeflonglongS64;11

12typedefU32UINT;13typedefS32SINT;

undfolgendenTeilausvoidsequence.h:

1//voidSequence.h2#defineENCODING_PLAIN(0)3#defineENCODING_UTF8(1)

und–nichtzuletzt–,folgendenTeilauscompressedAutomaton.c:

1//compressedAutomaton.c2CompressedAutomaton*CompressedAutomatonInit(UINTsymbolSize){3CompressedAutomaton*aut;4

5aut=Malloc(1,sizeof(CompressedAutomaton));6aut->initialState=NO;

216CHAPTER25.ÜBUNGEN

Page 46: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

46 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

7 aut->statesTransitions = UINTSequenceInit2( 1024, 1024 );8 aut->statesNumberOfTransitions = UINTSequenceInit2( 1024, 1024 );9 aut->statesEnd = UINTSequenceInit2( 1024, 1024 );

10 aut->transitionsStart = UINTSequenceInit2( 1024, 1024 );11 aut->transitionsTo = UINTSequenceInit2( 1024, 1024 );12 aut->data = VoidSequenceInit2( symbolSize, 1024, 1024 );13 aut->tt = NULL;14 return aut;15 }

Das Problem mit diesem Code nun gestaltet sich folgendermaßen:

a) Zum einen muss der Anwender der Klasse wissen, was mit UINT symbolSizegemeint sein soll

b) Der Anwender der Klasse muss wissen, welche Werte UINT symbolSizeannehmen darf. Es ist nicht definiert, was passiert, sollte ein Anwenderden Wert 3 hineingeben

Anders ausgedrückt verstößt dieser Code gegen mehrere Richtlinien für“sauberen” Code:

a) Scott Meyers (Effective C++): Machen Sie es dem Anwender so einfachwie möglich, Ihre Klasse richtig zu verwenden und so schwer wie möglich,sie falsch zu verwenden (Meyers 2005)

b) Stroustrup (“Day 1 Keynote - Bjarne Stroustrup: C++11 Style” 2012):“Strong typing”. Als Apollo 11 (oder 13?), ein millionen- (oder milliarden-?) schweres Projekt hart abgestürzt. Warum? Weil eine Methode einenWert float übernehmen sollte, die die Verzögerungsgeschwindigkeitanzeigen sollte. Dabei war nicht klar, ob in km/h oder in meile/hangegeben sollte. Mit strong typing und Verwendung von Klassen, dieSI-Einheiten darstellen, wäre so etwas nicht passiert, da ein Objekt km/hnicht in eine Methode hineingegeben werden kann, das meile/h verlangt.Vergleiche hierzu unbedingt das Kapitel über SI-Einheiten in Stroustrups“the C++-Language” für C++11

Zurück zu unserem Code:

Um es so einfach wie möglich zu machen die Wrapper-Klassen richtig zu be-nutzen, und so schwer wie möglich, diese falsch zu benutzen (und dabei auchnoch Platz und Größe zu sparen), benutzen die Wrapper-Klassen Template-Meta-Programmierung, die folgendes erreicht:

a) Eine class CompressedAutomatonAdaptermit der Definition template<class StringType> struct CompressedAutomatonAdapterist templatisiert, wobei ein Template-Parameter erwartet wird, der:

i) entweder ein std::string istii) ein std::wstring ist

25.9. ÜBUNG 9: WEB-PROGRAMMIERUNG MIT DEM MEAN-STACK215

25.9 Übung 9: Web-Programmierung mit demMEAN-Stack

Schreiben Sie eine Komponente für LaaS, die “linguistics as a service”-Webapplikation.

Gehen Sie dazu wie folgt vor:

• clonen sie den code von https://gitlab.cip.ifi.lmu.de/bruder/claas• schauen Sie sich die Routen server.js und in lib/controllers/api.js

an, und versuchen Sie zu verstehen, was hier passiert – letztendlich werdennur Daten vom Frontend (also von der Client-Seite entgegengenommenund ein Shell-Befehl ausgeführt und die dadurch gewonnen Daten an dieClient-Seite zurückgegeben)

• schauen Sie sich einen Controller der Client-Seite an und versuchen Siezu verstehen, wie dieser die Daten an die Server-Seite gibt und die Ergeb-nisse von der Server-Seite entgegennimmt. Betrachten Sie beispielsweiseapp/scripts/controllers/tokenize.coffee

• schauen Sie sich eine View auf der Client-Seite an und versuchen Sie zuverstehen, wie die Daten entgegengenommen und die Ergebnisse von derServer-Seite präsentiert werden, z.B: app/views/partials/tokenize.jade

• Nun schreiben Sie ein kleines Modul selbst! Suchen Sie sich dabei frei aus,wwas sie umsetzen möchten, hier ein paar Ideen: uppercase, lowercase,camelCase, CamelCase to snake_case, strip, Spracherkennung,reverse, wordcount, …

Page 47: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN47

iii)odereine(egalwelche)vonstd::stringabgeleiteteKlassedarstellt

b)DabeierreichtdietemplateclassCompressedAutomatonAdapter,dass:

i)dieunterliegende,adaptierteKlasseCompressedAutomatonmitgenaudemrichtigenWertfürUINTsymbolSizeaufgerufenwird

ii)keine“falsche”Instantiierungvorgenommenwerdenkann(strongtyp-ing)

iii)mandieKlassenichtfalschverwendenkann(durchstatic_assert),bzw.schonzurCompile-ZeitübereinefalscheVerwendung(mitentsprechenderFehlermeldung)aufgeklärtwird–undderCodegarnichterstkompiliert(stattspäterohneWarnungin“undefinedbe-havior”hineinzurennen)

KonkretwirddieserreichtundumgesetztdurchfolgendenCode:

ZunächstnocheinmaldieKonstruktionderadaptiertenKlasse:

1///@briefAdapterforCompressedAutomaton2template<classStringType>3structCompressedAutomatonAdapter4:virtualpublicCompressedAutomatonAbstract<StringType>5{6

7usingCompressedAutomatonAbstract<StringType>::traits::string_type;8usingCompressedAutomatonAbstract<StringType>::traits::symbol_size;9

10protected:11usingadaptee_handle=12std::unique_ptr<CompressedAutomaton,decltype(&::CompressedAutomatonFree)>;13adaptee_handleadaptee_;14

15public:16explicitCompressedAutomatonAdapter()17:adaptee_{::CompressedAutomatonInit(symbol_size),&::CompressedAutomatonFree}{}18virtual~CompressedAutomatonAdapter(){}

Bemerkungen:

•StringTypeinZeile2istlediglichdeskriptiv,abernichtpräskritiptiv:sieistlediglichdazugeeignet,demLeserzusagen,washiererwartetwird,prüftdiesabernicht(oderkanndiesohneConcepts,dieerstinC++14kommenwerden,garnicht)

•konstruiertwirdderadaptee_miteinersymbol_size,dievonCompressedAutomatonAbstract<StringType>::traits::symbol_sizegeliefertwird

•CompressedAutomatonAbstract<StringType>wiederumisteingemein-samesInterface,dasalleAutomatenteilenwerden

HiermitalsozurBetrachtungdesInterfacesCompressedAutomatonAbstract<StringType>

214CHAPTER25.ÜBUNGEN

Page 48: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

48 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

1 /// @brief interface for CompressedAutomaton2 template<class StringType>3 struct CompressedAutomatonAbstract4 : virtual public AutomatonAbstract<StringType>5 {6

7 using AutomatonAbstract<StringType>::traits::string_type;8 using AutomatonAbstract<StringType>::traits::symbol_size;9

10 virtual UINT get_symbol_size() const = 0;11 virtual CompressedAutomaton * read( FILE * fp ) = 0;

Dinge, die man hier erkennen kann:

• Das Interface für CompressedAutomaton beruft sich auf ein noch grundle-genderes Interface: AutomatonAbstract<StringType> und “erbt” dessenclass traits

• Das Interface für CompressedAutomaton deklariert pure virtuals für alleerbenden Klassen und zeichnet sich damit durch folgendes aus:

– sie ist eine abstrakte, nicht instantieerbare Klasse– verlangt von allen erbenden Klassen, diese Methoden zu implemen-

tieren, andernfalls, bleiben diese ebenfalls abstrakt– definiert dadurch ein gemeinsames Interfaces aller erbenden (nicht-

abstrakten) Klassen, auf das man sich berufen kann.

Nun ist aber nocht nicht die Herkunft der traits geklärt.

Traits erlauben es, “kostenlos”, d.h. ohne Speicher zu belegen, Informationenin Klassen zu halten, die während der Compile-Zeit genutzt werden können.

1 namespace sis {2

3 template <class StringType>4 struct string_traits {5 public:6 typedef typename ElementSize<StringType>::type string_type;7 static constexpr unsigned symbol_size = ElementSize<string_type>::value;8 };9

10 /// @brief Defines an Automaton in general11 /// @todo rename: AutomatonAbstract -> AdaptedAutomaton (?)12 template<class StringType>13 struct AutomatonAbstract : boost::noncopyable, string_traits<StringType> {14

15 using string_type = typename string_traits<StringType>::string_type;16 static constexpr unsigned symbol_size = string_traits<StringType>::symbol_size;17

18 //——————————————————————————————————————————————————————————————————————————//19 // C T O R / D T O R //20 //——————————————————————————————————————————————————————————————————————————//21 public:22 AutomatonAbstract() { mSetEndianness() } // this is important.

25.8. ÜBUNG 8: TYPE TRAITS 213

25.8 Übung 8: Type Traits

Schreiben Sie ein type-trait, das für eine Klasse template<class T> Foo zurCompile-Zeit (!)

• feststellt, ob die Klasse mit einem std::string, std::wstring oder eineraus diesen abgeleiteten Klassen besteht

• feststellt, ob es sich um einfache oder wide-strings handelt und• eine bool-variable anbietet, die wiederum von anderen Klassen abgefragt

werden kann: bool is_wide_string

Also:

namespace trait {template<class T> mytrait {static constexpr bool is_wide_string = /*...*/;

}}

temlpate<class StringType>class MyClass {using is_wide_string = mytrait<StringType>::is_wide_string;

};

auto main() -> int { // C++11 only!MyClass<std:: string> stringclass;MyClass<std::wstring> wstringclass;

std::cout << std::boolalpha<< stringclass::is_wide_string // false<< std::endl<< wstringclass::is_wide_string // true<< std::endl;

return 0;}

Page 49: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN49

23virtual~AutomatonAbstract(){}24

25

26//——————————————————————————————————————————————————————————————————————————//27//MAPPINGINTERFACE//28//——————————————————————————————————————————————————————————————————————————//29public:30virtualvoidshrink()=0;31virtualvoidwrite(FILE*fp)const=0;32

33//...

1namespacesis{2

3///@briefmeta-classtohandleStringTypetypetraits(usingstaticassertions)4template<classT>5structElementSize{6staticconstexprboolT_is_string_type=7std::is_base_of<std::string,T>::value8||std::is_base_of<std::wstring,T>::value;9

10static_assert(T_is_string_type,11"\n\n\tYoumustinstantiatethisclassinquestionwithstd::string,"12"\n\tstd::wstring,oranyclassderivedthereof.\n"13);14

15

16typedefTtype;17typedefTstring_type;18typedeftypenameT::value_typevalue_type;19

20typedeftypenamestd::conditional<21std::is_same<std::string,T>::value,//ifStringTypeisstd::string22std::fstream,//thenstream_typeisstd::fstream23std::wfstream//elseitisstd::wfstream24>::typestream_type;25

26staticconstexprunsignedintvalue=27sizeof(typenamestring_type::value_type);28};29

30}/*sis*/

BesprechungdesCodesDieZiele,diedieser(C++11-)Codeerreicht,sindmehrere:

1)Eswirdgeprüft,obderTemplate-Paramtertemplate<classT>

a)einstd::string,b)einstd::wstringc)odereinevoneinerderbeidenKlassenabgeleiteteKlasseist

(std::is_base_of)

212CHAPTER25.ÜBUNGEN

Page 50: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

50 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

2) Diese Überprüfung findet zur Compile-Zeit (!) statt (constexpr) und dasErgebnis wird in einem bool ::value abgespeichert

3) Es werden sog. traits definiert, die wiederum an anderer Stelle abfragbarsind:

a) ElementSize<mystring>::type würde den Typ mystring zurück-geben

b) ElementSize<mystring>::string_type würde das selbe Ergebnisliefern

c) ElementSize<mystring>::value_type würde den value_type derKlasse zurückgeben mit der ElementSize instantiiert ist; im Fallevon std::string also char

4) Der wichtigste traits jedoch ist static constexpr unsigned int value:an dieser Stelle wird, je nach Instantiierung ein numerischer Wert von 1oder 4 zurückgegeben, nämlich die exakte Größe des value_types derKlasse template<class T>:

Bespiel:

a) für ElementSize<std::string>::value der Wert 1, da der value_typevon std::string ein char ist, und char (zwar plattform-abhängig) aberin den meisten Fällen die “Breite” 1 hat (also ein 1 Byte “breit” ist)

b) für ElementSize<std::wstring>::value der Wert 4, da der value_typevon std::wstring ein wchar_t ist, und wchar_t (zwar plattform-abhängig) aber in den meisten Fällen die “Breite” von 4 hat (also 4 Byte“breit” ist)

Passenderweise sind dies genau die Werte, die unser adaptierter AutomatotCompressedAutomaton in seinem Konstruktor erwartet! Allerdings kann dieAdapter-Klasse CompressedAutomatonAdapter nun nicht mehr “falsch” verwen-det werden!

Nicht zuletzt ist noch das trait stream_type interessant:

Je nachdem, ob die Automaten mit std::string oder std::wstring instanti-iert wurden, werden Ausgaben auf std::cout oder std::wcout gelenkt werdenmüssen. Um auch dieses “wegzuabstarhieren” wird – wiederum zur Compile-Zeit–, entschieden, was der passende Typ von Streams sein wird.

Hierfür bietet sich std::conditional aus dem Header <type_traits>an, das stream_type für eine Instantiierung mit std::string auf denstream_type-Typ auf std::fstream festlegt und mutatis mutandis das selbefür std::wstring erledigt.

Wenn nun eine Automaten-Klasse also Ausgaben vornehmen wird, so kann siedies abstrakt erledigen, indem Sie – in etwa – folgendes tut:

25.7. ÜBUNG 7: TEMPLATE META PROGRAMMIERUNG 211

25.7 Übung 7: Template Meta Programmierung

In dieser Übung werden Sie in die Template Meta Programmierung eingeführt.Dabei erlernen Sie, wie man Entscheidungen und – möglicherweise – sogarBerechnungen in die Compile-Zeit überführen kann.

In letzterem Falle bedeutet dies tatsächlich, dass zur Laufzeit bereits alle Berech-nungen erfolgreich erledigt wurden und keine Zeit mehr benötigen!

Schreiben Sie eine templatisierte C++-Klasse template<class T> class MyClass,die:

• einen default CTOR + DTOR hat

– (Verwenden Sie hierzu bestfalls den C++11-Weg)

• eine Methode zum hinzufügen von Elementen hat• eine Method zum Ausgeben der Anzahl von Elementen hat• eine Kollektion als Member-Variable speichern kann, und zwar wie folgt:

– Wenn die Klasse mit einem std::string oder einem std::wstringinstanziiert wurde, dann sollen diese in einem std::vector<> abge-speichert werden

– wenn die Klasse mit einem numerischenWert, also int, unsigned int,unsigned long long int, short, float, double, … instanziiertwurde, sollen diese in einem std::set<> gespeichert werden

– wenn die Klasse mit irgendeiner anderen Art instanziiert wird,soll dieses zur Compile-Zeit mit einem static_assert und einerentsprechenden Fehlermeldung abgelehnt werden.

• Wie immer haben Sie für alles selbstverständlich so gut es geht Tests zurVerfügung (die sich über einen (1!) Shell-Befehl bequem starten lassen,z.B. make && make test) – zugegeben, manche Dinge lassen sich hier nurschlecht (bis kaum testen)

Page 51: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN51

#include"ElementSize.hpp"

template<classT>classFoo{

usingstream_type=ElementSize<T>::stream_type;

stream_type&operator<<(constT&);}

SindhiermitalleAnforderungenerfüllt?

•Esistschwerergeworden,dieKlasse“falsch”zubenutzen,undleichtergeworden,sie“richtig”zubenutzen

•“StrongTyping”verhindertfalschgesetzteParameter,dabeieinemein-fachenUINToderunsignedintnichtklarist,welchekonkretenWerteandieserStelleerwartetwerden.

•DarüberhinaussinddieKlassen,dieaufdieseclassElementSizeauf-bauen,wesentlichflexibler,dasiegleichzeitigunabhänigighinsichtlichdesstream_typesoperierenkönnen.

LetztendlichalsobietetsichfolgendesSzenario:DerNutzerverwendeteineKlasseCompressedAutomatonAdapter<std::string>undbekommt–zurCompile-Zeit–diefürihn“passende”(d.h.kleinstmögliche,platzsparendste,sicherste)Klasse“zusammengebaut”undhatdabeiauchnochSicherheitfürdieVerwendunggewonnen.SollteerdieKlasse“falsch”(d.h.miteinem“nicht-string”)instantiierenwollen,würdeihmdiesbeimkompilierendurchdasstatic_assertinklusiveeinerFehlermeldungmitgeteiltwerden.ZumErlernenvonTechnikenzurTemplateMetaProgrammierung,verwendenSiebittedieÜbungen,dieimKapitel??TMPaufSeite??angegebenwerden.

TemplateMetaProgrammierung:MemberDispatchEineweitereTechnik,dieinnerhalbderSIScodebasezufindenist,isteinMemberDispatch-ingPattern.ObwohlmandasselbeZielauchüberTemplate-Spezialisierungerreichenkönnte,istesdennochratsam,diesesPatternzukennenumesimFalledesFallesauchtatsächlichzuerkennen.WiemitallenPatterns,sehendieseamAnfangkomplettunverständlichaus,kenntmansieaber,sosiehtmansofort,wasgeschieht,ohnelangenachdenkenzumüssen.Das“MemberDispatch”-Patternfunktioniertso:Angenommen,ichhabeeineTemplate-KlasseFoomiteinerMethodebar().NunmöchteichkomplettunterschiedlicheMethodenbar()ausführen,jenach-demwomitdieKlasseFooinstanziiertist–alsoz.B.alsFoo<std::string>undFoo<int>.Dermember-dispatchfunktioniertdannso:

210CHAPTER25.ÜBUNGEN

Page 52: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

52 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

1 #include <type_traits>2 #include <cassert>3

4 // C++11 Proof of concept of different implementations of5 // member methods for different types of class instances.6

7 template<class T> struct tag {};8

9 template<class T>10 struct Foo {11

12 // obviously, you can play with where you actually put these attributes13 // (at least with gcc)14 [[ dispatched_to ]]15 std::string bar(tag<std::string>) {16 return std::string{"foo"};17 }18

19 int bar(tag<int>) [[ dispatched_to ]] {20 return 5;21 }22

23 auto bar() [[ dispatcher ]]24 ->decltype(this->bar(tag<T>{})) // 'this' seems to be needed here.25 {26 return bar(tag<T>{});27 }28 };

Zur Funktionsweise des member-dispatch Es gibt eine zentrale Meth-ode auto bar() [[ dispatcher ]], welche dann einfach weiterreicht andie eigentlichen Methoden, int bar(tag<int>) [[ dispatched_to ]] oder[[ dispatched_to ]] std::string bar(tag<std::string>).

Das struct tag dient dabei lediglich einer “Markierung” und wird vom Opti-mizer im Laufe der Kompilierung entfernt.

Test Driven Development: TDD Fast die gesamte Funktionalität der SIS-Komponente wurde mit dem Verfahren des TDD, Test Driven Developmentsentwickelt.

Mehr zum Thema TDD findet sich im Kapitel TDD – Test Driven Developmentab Seite ??.Kurz zur Struktur der Tests innerhalb von SIS:

• Die tests verwenden die Bibliothek lest(Martin Moene 2013) für die tests.• Alle tests finden sich im Verzeichnis src/features• Jeder Klasse innerhalb von src/ sollte ein Test entsprechen:

– Eine Klasse Document, z.B. in Document.hpp, sollte eine Fixture undein Feature besitzen:

25.6. ÜBUNG 6: NODE-WRAPPING 209

25.6 Übung 6: Node-Wrapping

[Spezifikation]

Verwenden Sie Ihre C++-Klasse mit den Tests aus der vorangegangenen Woche

Nun schreiben Sie ein Node-Addon, das folgendes kann:

• ich kann var addon = require('myWrappedCppClass') (oder ähnlich)aufrufen

• ich kann auf Javascript-Seite addon.add(element); aufrufen und das El-ement wird in der Member-Variable der C++-Klasse abgespeichert

• ich kann mit console.log(addon.size()); die Anzahl von Elementenin der Member-Variable der C++-Klasse abfragen

• ich kann auf Javascript-Seite mit addon.elements() alle Elemente ausder C++-Klasse in ein Javascript-Array holen.

• schreiben Sie eine for-loop in Javascript, das alle Elemente auf der Shellausgibt

Hinweise:

• Verwenden Sie zur Lösung dieser Aufgabe

– die Rezepte von hier6

– schauen Sie dieses Sympathische Youtube-Video7

• Es steht Ihnen frei, “statt” Javascript Coffeescript zu verwenden.• Bonuspunkt, wenn Sie erfolgreich utf8-Strings adden und ordentlich auf

der Shell ausgeben

6Node API (2014)7Marco Rogers (2013)

Page 53: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN53

–src/features/DocumentFixture.hppundsrc/features/DocumentFeature.hpp

ZurtieferenBeschreibungvonFixturesundFeatures,siehenochmaldasKapitelTDD–TestDrivenDevelopmentabSeite??;andieserStellenursoviel:

•FixturesbeschreibensowohldieInput-DatenalsauchdieerwartetenOutput-Daten

•FeaturessindspezielleTest-Klassen/Dateien,welchedieSpezifikationderKlassebeschreiben,aufdiesiesichbeziehenunddieFixturesverwendenumdieFunktionalitätdergetestetenKlassemitdenerwartetenErgebnis-senabzugleichen

BeispielInSISfindetsicheineKlasseDocument,mitdenfolgendenFix-tures/FeaturesumdieSpezifikationzuprüfen:

#ifndefDOCUMENTFIXTURE_HPP_8JMP5XLF#defineDOCUMENTFIXTURE_HPP_8JMP5XLF

#include"sis_config.hpp"

#include<vector>#include<string>

typedefstd::stringfile_t;///@todochangethistofs::path

structDocumentFixture{

std::vector<file_t>filenames={sis_TEST_DATA_DIR"ascii/1.txt",sis_TEST_DATA_DIR"ascii/2.txt",sis_TEST_DATA_DIR"ascii/3.txt",

};

std::vector<file_t>wfilenames={sis_TEST_DATA_DIR"utf8/1.txt",sis_TEST_DATA_DIR"utf8/2.txt",sis_TEST_DATA_DIR"utf8/3.txt",

};

std::vector<std::string>contents={"DasVerstehen,dieMeinung,faelltausunsrerBetrachtungheraus.","Also:KannmanEtwasanders,alsalsSatzverstehen?","Oderaber:IstesnichtersteinSatz,wennmanesversteht."

};

std::vector<std::wstring>wcontents={L"DasVerstehen,dieMeinung,fälltausunsrerBetrachtungheraus.",L"Also:KannmanEtwasanders,alsalsSatzverstehen?Ääääh...",L"Oderaber:IstesnichterßteinSatz,wennmanesversteht."

};};

#endif/*endofincludeguard:DOCUMENTFIXTURE_HPP_8JMP5XLF*/

208CHAPTER25.ÜBUNGEN

Page 54: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

54 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

#include "sis_config.hpp"

#include "testing/lest.hpp"#include "DocumentFixture.hpp"

#include "indexer/Document.hpp"

#include <fstream>#include <locale>#include <cereal/types/vector.hpp>#include <cereal/types/string.hpp>#include <cereal/access.hpp> // For LoadAndAllocate#include <cereal/types/memory.hpp>#include <cereal/archives/binary.hpp>#include <cereal/archives/json.hpp>#include <cereal/archives/xml.hpp>

#include <cwchar>

DocumentFixture f;

const lest::test specification[] ={

"standard CTOR callable",[]{

sis::Document<std::string> d;EXPECT( d.filename() == "" );

},

"CTOR with filename", []{

sis::Document<std::string> d{ f.filenames.front() };EXPECT( d.filename() == f.filenames.front() );

},

"can serialize (automaton with added document)", []{

sis::Document<std::string> d{ f.filenames.front() };std::ofstream ofs{ "document.bin" };cereal::BinaryOutputArchive oarchive{ ofs };

oarchive( d ); // Write the data to the archive},

"can deserialize (automaton with added document)", []{

sis::Document<std::string> d{ f.filenames.front() };std::ifstream ifs{ "document.bin" };cereal::BinaryInputArchive iarchive{ ifs };

iarchive( d ); // Read the dataEXPECT( d.filename() == f.filenames.front() );EXPECT( d.contents() == f.contents. front() );

},

"can serialize (automaton without added document)", []{

25.5. ÜBUNG 5: SERIALISIERUNG 207

25.5 Übung 5: Serialisierung

Verwenden Sie ihre C++-Klasse aus der vorangegangenen Woche und schreibenSie eine Binär-Serialisierung für diese.

Zum Serialisieren können sie folgendes verwenden:

• generic_serialize3

• cereal4• boost serialization5

Erweitern Sie Ihre C++-Klasse aus der letzten Woche um folgende Methoden:

• save(const std::string & filename)• load(const std::string & filename)

…wobei die beiden Methoden (möglicherweise als static-Methoden!) die Klassejeweils auf Festplatte speichern und wieder laden.

Wie immer: schreiben Sie Tests, die Ihre Ergebnisse verifizieren und mit einemBefehl ausführbar sind. Dokumentieren Sie Ihre Vorgehensweise.

• Bonuspunkte, wenn Sie const boost::filesystem::path & path stattconst std::string & filename verwenden

• Bonuspunkte, wenn Sie neben dem Binärformat noch andere Formate un-terstützen (XML, JSON, …)

3Daniel Bruder, Florian Fink (2014)4uscilab (2014)5boost.org (2014b)

Page 55: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN55

sis::Document<std::string>d;std::ofstreamofs{"document.bin"};cereal::BinaryOutputArchiveoarchive{ofs};

oarchive(d);//Writethedatatothearchive},

"candeserialize(automatonwithoutaddeddocument)",[]{

sis::Document<std::string>d;std::ifstreamifs{"document.bin"};cereal::BinaryInputArchiveiarchive{ifs};

iarchive(d);//ReadthedataEXPECT(d.filename()=="");EXPECT(d.contents()=="");

},

"canaccesscontent",[]{

sis::Document<std::string>d{f.filenames.front()};EXPECT(d.contents()==f.contents.front());

},

"canaccesswidecontent",[]{

sis::Document<std::wstring>d{f.wfilenames.front()};

///Makesuretoproperlyimbue!EXPECT(d.contents()==f.wcontents.front());

},

"canaccesscontent(fordefaultCTOR)",[]{

sis::Document<std::string>d;EXPECT(d.contents()=="");

},

"canaccessfilename(fordefaultCTOR)",[]{

sis::Document<std::string>d;EXPECT(d.filename()=="");

},

"canaccessfilename(withgivenfilename)",[]{

sis::Document<std::string>d{f.filenames.front()};EXPECT(d.filename()==f.filenames.front());

},

"canserialize(automatonwithaddeddocument)[asstd::wstring]",[]{

sis::Document<std::wstring>d{f.wfilenames.front()};std::ofstreamofs{"document.json.w"};cereal::JSONOutputArchiveoarchive{ofs};

oarchive(d);//Writethedatatothearchive

206CHAPTER25.ÜBUNGEN

Page 56: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

56 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

},

"can deserialize (automaton with added document) [as std::wstring]", []{

sis::Document<std::wstring> d{ f.wfilenames.front() };std::ifstream ifs{ "document.json.w" };cereal::JSONInputArchive iarchive{ ifs };

iarchive( d ); // Read the data

std::wstring expected = L"Das Verstehen, die Meinung, fällt aus unsrer Betrachtung heraus.";

/// Make sure to properly imbue!std::wcout << L"[" << d.contents() << L"]" << std::endl;std::wcout << L"[" << expected << L"]" << std::endl;

EXPECT( d.filename() == f.wfilenames.front() );EXPECT( d.contents() == expected );

},

"can serialize (automaton with added document) [as std::wstring]", []{

sis::Document<std::wstring> d{ f.wfilenames.front() };std::ofstream ofs{ "document.bin" };cereal::BinaryOutputArchive oarchive{ ofs };

oarchive( d ); // Write the data to the archive},

"can deserialize (automaton with added document) [as std::wstring]", []{

sis::Document<std::wstring> d{ f.wfilenames.front() };std::ifstream ifs{ "document.bin" };cereal::BinaryInputArchive iarchive{ ifs };

iarchive( d ); // Read the data

std::wstring expected = {L"Das Verstehen, die Meinung, fällt aus unsrer Betrachtung heraus."};

/// Make sure to properly imbue!// std::wcout << L"[" << d.contents() << L"]" << std::endl;// std::wcout << L"[" << expected << L"]" << std::endl;

EXPECT( d.filename() == f.wfilenames.front() );EXPECT( d.contents() == expected );

},

};

int main() {std::setlocale(LC_ALL, "");return lest::run( specification );

}

Zweistufige Serialisierung Das Thema Serialisierung wird allgemeinbeschrieben im Kapitel Serialisierung.

25.4. ÜBUNG 4: TDD – TEST DRIVEN DEVELOPMENT 205

25.4 Übung 4: TDD – Test Driven Development

Verwenden Sie Ihre C++-Klasse und den cmake build-Prozess aus der letztenWoche und schreiben Sie Unit-Tests. Auch wenn TDD eigentlich anders herumfunktioniert (Failing Test first – implementation to make the test pass later),sollten Sie dennoch ein gutes Gefühl für Unit-Testing und TDD bekommen.Nicht zuletzt ist es zum Einstieg dann doch leichter für eine bereits existierenden(hoffentlich auch funktionierende!) Klasse, Tests zu schreiben.

Die Tests sollen folgendes erfüllen:

1) die gesamte API wird abgedeckt

2) alle erdenklichen Edge-Cases, die Ihnen einfallen werden geprüft

3) alle Tests bestehen

4) alle Tests können durch einen einfachen Shell-Befehl gestartet werden

5) (dokumentieren Sie bitte, wie die Tests zu starten sind)

6) Sie dürfen als Test-Library verwenden was Sie wollen, zwei bestimmtejedoch kann ich Ihnen besonders empfehlen:

• lest1 – diese dürfen Sie auch gerne als git submodule hinzufügen,wenn Sie das möchten, ich möchte diese nicht gesondert herunter-laden müssen, damit Schritt 5 funktioniert

• Boost-Test2 – diese dürfen Sie als installiert ansehen

• Machen Sie sich schon einmal mit der zu lesenden Literatur für nächsteWoche und, wenn möglich, bereits mit der Theorie für nächste Wochegrundlegend vertraut

• Bonus:

– Schreiben Sie ein Makefile oder ein Rakefile, das per default-Task die tests frisch kompiliert und laufen lässt [finden sie den linkzu guten Beschreibungen von Rakefiles im entsprechenden Kapiteldes Skripts]

1Martin Moene (2013)2boost.org (2014a)

Page 57: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN57

IndiesemKapitelwirddiezweistufigeSerialisierunginnerhalbvonSISbeschrieben.

WarumdieSerialisierunginnerhalbvonSISzweistufigläuftistdurchdasWrapping-Patternzuerklären:

DadieC-SchichtihreeigeneSerialisierunghat,kanndieseselbstangesprochenwerden.UmdiezusätzlichenDatenstrukturenausderC++-Schichtzuserial-isieren,istjedochnochweitereSerialisierungnotwendig.

HierbeispielenfolgendeÜberlegungeneineRolle:

•DieSerialisierungderC-SchichtspeichertundliesteinkompaktesBinär-format(mehrInformationenzuBinär-SerialiseirungundByte-LayoutinKapitelMethodenzurSerialisierung)

•DieBeibehaltungderSerialisierungderC-Schichtbietetsichaus2Grün-denbesondersan:

–dieseistbereitsimplementiertundstelltihreFunktionalitätbereitszurVerfügung

–DieentstehendeDateikannvonderexecutablederC-Schicht–un-abhängigvonallemwasinnerhalbderC++-Schichtpassiert–,gele-senundgeschriebenwerden.EineBeibehaltungdieserSerialisierunggarantiertalsoeinegewisseÜbertragbarkeitderserialisiertenDatenzwischendenSchichten

•TrotzBeibehaltungderbestehendenFunktionalitätzurSerialisierungderC-SchichtistdieEntwicklungeinereigenenSerialisierungderC++-Schichtnotwendig.

AbgesehenvondengenerellenÜberlegungenzurSerialisierungwieimKapitelMethodenzurSerialisierungbeschrieben,bietensichzurSerialisierungineinBinärformatvorallemfolgendeOptionenan:

•boostserialization:eineStandardbibliothekfürC++,kann(virtuelleundpolymorphe)Klassenhierarchienspeichernundladen,hatextras,dieeserlaubenrawpointerzu(de)serialisieren,dieDokumentationunddieVer-wendungsindallerdingsnichtdieeinfachsten

•cereal(uscilab2014).Einemoderne,schlankeBibliothek,dievorallemaufC++11featuresderTemplateMetaProgrammierungsetzt.DieDoku-mentationistleichterzuverdauenalsdievonBoostSerializationunddieAPIleichterzubedienenundinvorhandeneStruktureneinzubauen

•cpp-generic-serialize(DanielBruder,FlorianFink2014):einekleineBibliothek,diedasBinär-Speichernund-ladenfürSTL-Containererleichtert,ebenfallsumgesetztdurchdieNutzungvonTemplateMetaProgrammierung.Erlaubtvorallemdasdetaillierteheraus-schreibenundeinlesenvoneinzelnenElementeneinesContainers,wennnicht

204CHAPTER25.ÜBUNGEN

Page 58: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

58 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

ganze Klassen-hierarchien serialisiert sondern nur einzelne Elemente oderContainer einer Klasse serialiseirt werden sollen.

Im Falle von SIS fiel die Wahl auf cereal, da die Funktionalität den Bedürfnissenentspricht und die Verwendung als einfach bezeichnet werden kann.

Im besonderen Falle von SIS hinsichtlich des Wrappings und der Beibehaltungder Serialisierungs-Funktionalität der C-Schicht ist jedoch im besonderenzu beachten, dass die C++-Sicht beim Speichern die Serialisierung der C-Schicht anstoßen muss und beim Laden die Ergebnisse der C-Deserialisierungentsprechend berücksichtigen (und möglicherweise in die Klassenhierarchieentsprechend integrieren muss).

Hierzu stehen für einen generischen(!) template<AutomatonType> structDocumentIndexingAutomaton<AutomatonType<StringType>> folgendeSchnittstellen zur Verfügung:

template <class F = std::ofstream, class A = cereal::BinaryOutputArchive>void save(std::string & fn /* fs::path & p */);

template <class F = std::ifstream, class A = cereal::BinaryInputArchive>staticDocumentIndexingAutomaton<AutomatonType>load(std::string & fn);

Mit diesen Methoden lassen sich alle Kombinationen der folgenden Dimensionenvon DocumentIndexingAutomaton speichern und lesen:

Automaten StringType Formate Ziele

SCDAWGAdapter std::string JSON std::fstream,CDAWGAdapter std::wstring XML d.h. std::cout,CompressedAutomatonAdapter Binär std::ofstream (Datei), …

Table 3.1: Serialisierungsmöglichkeiten für DocumentIndexingAutomaton

Um zu verdeutlichen, wie die (De-)Serialisierung und dabei das Anstoßen derSerialisierungsfunktionen der C-Schicht funktioniert, hier die Implementierung:

1 namespace sis {2

3 /*****************************************************************************/4 template <class AutomatonType>

25.3. ÜBUNG 3: CMAKE 203

25.3 Übung 3: cmake

Verwenden Sie ihre Klasse aus der vorhergehenden Woche und schreiben SieMakefiles im cmake-Format diese.

Das cmake-file CMakeLists.txt soll dabei folgendes unterstützen:

• es werden zwei libraries gebaut cstructlib und cppstructlib, wobeidiese jeweils die beiden Klassen der letzten Woche enthalten

• main.cpp kann gebaut werden• die beiden o.g. libraries werden ordentlich zu main.cpp hinzugelinkt• die beiden o.g. libraries können einzeln gebaut werden: cmake .. &&

make cppstructlib• es werden out-of-source-builds unterstützt

Page 59: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN59

5template<classFileType,classArchiveType>6inline7void8DocumentIndexingAutomaton<AutomatonType>::9save(std::string&fn/*fs::path&p*/)

10{11FileTypeofs{fn};12ArchiveTypeoarchive{ofs};13

14index();15automaton_->save(fn+".c");//Writeautomatoninformationtoarchive16oarchive(*this);//Writethedocumentdatatothearchive17}18

19

20/*****************************************************************************/21template<classAutomatonType>22template<classFileType,classArchiveType>23inline24DocumentIndexingAutomaton<AutomatonType>25DocumentIndexingAutomaton<AutomatonType>::26load(std::string&fn)27{28FileTypeifs{fn};29ArchiveTypeiarchive{ifs};30

31autoaut=Factory::create<AutomatonType>();32aut->load(fn+".c");33

34DocumentIndexingAutomaton<AutomatonType>a;35iarchive(a);36//a.automaton_=std::shared_ptr<AutomatonAbstract<typenameAutomatonType::string_type>>(aut);37a.automaton_=aut;38for(auto&index:*(a.index_)){39index.second.set_voidsequence(a.automaton()->data());40}41returnstd::move(a);42}43

44/*....*/

ZurVerdeutlichungderKombinations-MöglichkeitenhiereinAuszugausdendazugehörigenTests:

1"CanwritetodiskinJSONformattostd::ofstream",[]2{

202CHAPTER25.ÜBUNGEN

Page 60: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

60 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

3 std::cout << "saving to json" << std::endl;4 refresh_indexer();5 idx->save<std::ofstream,cereal::JSONOutputArchive>(f.filename.json);6 },7

8 "Can read back from disk in JSON format from std::ofstream", []9 {

10 std::cout << "loading from json" << std::endl;11 auto index_load = sis::DocumentIndexingAutomaton<sis::SCDAWGAdapter<std::string>>::load<std::ifstream,cereal::JSONInputArchive>(f.filename.json);12 },13

14 "Can write to disk in binary format to std::ofstream", []15 {16 std::cout << "saving to binary" << std::endl;17 refresh_indexer();18 idx->save<std::ofstream,cereal::BinaryOutputArchive>(f.filename.binary);19 },20

21 "Can read back from disk in binary format from std::ofstream", []22 {23 std::cout << "loading from binary" << std::endl;24 auto index_load = sis::DocumentIndexingAutomaton<sis::SCDAWGAdapter<std::string>>::load<std::ifstream,cereal::BinaryInputArchive>(f.filename.binary);25 // assert(aut.automaton_ != nullptr);26 },27

28 "Can write to disk in binary format to std::ofstream (with default template arguments)", []29 {30 refresh_indexer();31 idx->save<>(f.filename.binary);32 },33

34 "Can read back from disk in binary format from std::ofstream (with default template arguments)", []35 {36 auto aut = sis::DocumentIndexingAutomaton<sis::SCDAWGAdapter<std::string>>::load<>(f.filename.binary);37 // assert(aut.automaton_ != nullptr);38 },39

40 "Can write to disk in binary format to std::ofstream (with default template arguments -- and without using `<>')", []41 {42 refresh_indexer();43 idx->save(f.filename.binary);44 },45

46 /* ... */

25.2. ÜBUNG 2: C-WRAPPING 201

25.2 Übung 2: C-Wrapping

Schreiben Sie eine C++-Klasse, die die volle Funkionalität des folgenden C-struct wrapped und abbildet (inklusive der Unterscheidung private/public Meth-ode), mit vollen Konstruktoren und Destruktoren, die das C-Struct automatischallokieren und de-allokieren

Das C-struct halt folgende Spezifikation:

typedef struct tWordList {std::vector<std::string> words_;

} WordList;

// CTOR / DTORextern WordList * WordListInit();extern void WordListFree(WordList*);

// "public methods"extern void WordListAdd(WordList*, const char*);extern int WordListSize(WordList*);

// "private methods"static std::string WordListUpgradeWord(WordList*, const char*);

Schreiben Sie zunächst eine C++-Klasse, die:

• Einen Konstruktor und einen Destruktor enthält• einen (smart-)pointer auf das zu wrappende C-Struct hält• das C-struct im Konstruktor allokiert und im Desktruktor de-allokiert• alle public und private Methoden des C-Structs unterstützt und dabei• jeweils diese anspricht, anstatt selbst etwas zu machen

Page 61: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN61

DieAPIvoncerealUmeinBeispielvonderAPIvoncerealzugeben,hiereinAusschnittausDocumentIndexingAutomaton.Dabeigehtesimwesentlichendarum,einemember-Methodetemplate<classArchive>voidserialize(Archive&archive)fürdieKlassezudefinierenunddiesermitzuteilen,welchemember-Variablenserialisiertwerdensollen:

1

2template<classAutomatonType>3structDocumentIndexingAutomaton4{5

6/*....typedefsfürdiemember-TypenAutomatonAbstract_t,etc...*/7

8AutomatonAbstract_tautomaton_=nullptr;9std::unique_ptr<DocumentCollection_t>documents_=nullptr;

10std::unique_ptr<DocumentIndex_t>index_=nullptr;11std::map<UINT,std::vector<Document_t>>states_=nullptr;12FindResult_tresults_=nullptr;13size_ttotal_length_={0};14boolindexed_=false;15string_typequery_;16

17template<classArchive>voidserialize(Archive&archive){18archive(19CEREAL_NVP(documents_),20CEREAL_NVP(index_),21CEREAL_NVP(states_),22CEREAL_NVP(indexed_)23);24}

HinzuweisenistnochaufCEREAL_NVP:hiermitwirdfestgelegt,dass,wennnachjsonoderXMLserialisiertwird,dieDateninderSerialisierungbenanntwerden(NVP=namedvaluepair).

3.6.2Web-Ebene

IndiesemKapitelwerdendiewesentlichenBausteinederWeb-EbenevonSISbesprochen.DerWeb-TeilistimwesentlicheneineSPA(SingePageApp)undbauthierbeiweitestgehendaufdensogenanntenMEAN-Stack7auf,lässtaberu.a.dieDatenbankweg,dadieDatenvondenAutomateninSISgeliefertwerden.

7dasKürzelfürMongoDB+Express+Angular+Node,verlgeichehierzuauchdasnächsteKapitelunddasKapitel[Teilbesprechungen][]undseineUnterkapitel[DerMEAN-Stack][]und[Web-Applikationen,Basics][]

200CHAPTER25.ÜBUNGEN

•push-enSieIhrenneuentagsnachorigin

•BietenSieeinenpull-requestzumupstream-Repositoryan(dasRepository,dassSieamAnfangge-clone-dhatten)undbittenSieumÜbernahmeihres“Patches”

•Bonus:

–wennSiesichohnePasswortmitsshaufdencip-Rechnerneinloggenwollen,dannfügenSieihrenPublic-Keydortzu~/.sshhinzu,en-twederperHand,odermitssh-copy-id(IhreDistributionliefertdiesesmöglicherweiseschonmit,oderSiekönnenessichbequemin-stallierenwennSiemöchten)

•Bonus:

–clonenSiedasrepositoryaufdenCIP-Rechner,arbeitenSievonRe-motezuHause,ändernSieeineDateiab,undpushendieseinsgitlab.

•SSH-Bonus:

–legenSieeineDatei~/.ssh/configanundermöglichenSieessichdadurchsshcipstattsshnutzer@cip.ifi.lmu.desagenzukön-nen,umsicherfolgreichandencip-Rechnerneinzuloggen

•Remote-Working-Bonus:

–machenSiesichmitscreen,tmuxoderbyobu(alsFrontendfüreinesdervorgestelltenvertraut)undermöglichenSieessichdadurch,Terminal-Sessionsaufdencip-rechnernlaufenlassenzukönnenundzudiesenspäterzurückkehrenzukönnen.

•Bonus:

–arbeitenSiemitautosshoderdemPerl-ModulApp::asshundver-suchenSie,einepermanenteVerbindungzudencip-Rechnernhaltenzukönnen(schaltenSiedafürIhrInternetab-undwieder-an,undguckenSie,obdieVerbindungautomatischwiederhergestelltwird)

Page 62: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

62 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

3.6.2.1 Wesentliche Technologien und ihr Zweck

• Node: stellt den (eigenen) Webserver dar• Express: Ein Web-Framework für Node• Angular: Client-seitige Logik• Jade: HTML-Templating Engine• Bootstrap: Client-seitiges CSS und mehr• Bootstrap UI: Client-seitige UI-Module (Dropdowns, etc.)• v8: Javascript-Engine in C++

Für Detail-Besprechungen dieser Technologien siehe auch das eigene Buch“Teilbesprechungen”.

3.6.2.2 Überblick

Wie im Kapitel Wesentliche Technologien und ihr Zweck angedeutet handelt essich bei der Web-Schicht um eine SPA in Form des MEAN-Stack.

Dabei spielt der Node-Webserver eine wesentliche Rolle. Mit Express, dem Web-Framework für node lassen sich routen definieren und Antworten an den Clientzurücksenden (vergleiche hierzu Abbildung 11.1 auf Seite 100).

Das Zusammenspiel von Node und den C++-Automaten von SIS funktioniertnun auf folgende Art und Weise:

Im Ordner web/ befindet sich eine weitere Schicht, welche die nun in C++ vor-liegenden Automaten derart wrapped, dass diese direkt in Javascript verwendetwerden können:

1 ## --[ app.coffee ]-- ##2

3 # import4 indexer = require './build/Release/sis'5 log.info('index imported', {})6

7 # deserialize8 indexerObj = indexer.load '../etc/allfiles'9 log.info('index loaded', {})

10

11 # size12 size = indexerObj.size()13 log.info('index size', {size: size})14

15

16 ## --[ query.coffee ]-- ##

25.1. ÜBUNG 1: GIT UND KOLLABORATION 199

25.1 Übung 1: git und Kollaboration

• aktivieren Sie den für Sie von der IFI bereitgestellten gitlab-Account beirz.ifi.lmu.de

– Stellen Sie dabei sicher, dass ihre (???) weitergeleitet werden,oder klicken Sie den Aktivierungslink, der an ihre cip.ifi-Adressegeschickt wurde, durch Verwendung von webmail2.cip.ifi.lmu.de oderwebmail.cip.ifi.lmu.de, wenn Sie der festen Meinung waren, dassSie ihre Mails zwar weiterleiten würden, aber unverständlicherweisekeine bekommen haben

• generieren sie ssh-Keys (mit oder ohne Passphrase), und legen Sie ihrenPublic(!)-Key an der dafür vorgesehenen Stelle in gitlab ab (im Notfalllesen Sie Dokumentation! Einmal: ‘generate ssh keys’ und die gitlab-Dokumentation: ssh keys adden.)

• nun loggen Sie sich in gitlab ein

– und forken sie das bisher dort eingestellte Kursmaterial in ein eigenesrepository

– clonen Sie dieses Repository auf ihren Rechner (von dem aus Sieihren Public-Key erstellt und hochgeladen haben)

• Installieren Sie die git-extras auf Ihrem und/oder den cip-Rechnern (dannwie [hier] beschrieben). Dieser Schritt ist empfohlen aber nicht zwingend:alles was die git-extras machen, lässt sich mit git alleine auch machen.

• Kreieren Sie einen branch in dem ge-clone-ten repository

• Kreieren Sie ein Verzeichnis mit ihrem cip-ifi-Namen

• Schreiben Sie eine Datei im Markdown-Format in ihrem Ordner, in doku-mentieren Sie in dieser ihre bisher geleisteten Schritte – so dass andere vonIhnen lernen könnten und klar ist, was Sie getan haben – es steht Ihnendabei selbstverständlich frei, hierfür pandoc zu verwenden und damit zuspielen

• push-en Sie ihren Branch nach origin

• Wechseln Sie zu ihrem master-branch zurück und mergen Sie ihren erstell-ten Branch dort hinein (mit einem Kommentar der in etwa sagt, ‘mergebranch Foo’)

• tag-gen Sie Ihr ge-merge-tes Changeset mit einer semantischen Version-snummber ihrer Wahl (c.f. das Kapitel über semantisches Verionieren;also in etwa 0.1.0 oder v0.1.0)

• push-en Sie Ihren neuen Master-Branch nach origin

Page 63: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN63

17#query18found=app.get('indexer').find(query,width)

Konkretbedeutetdies,dassdasC++-ObjektandieserStelleinJavascriptnutzbargemachtwordenist,undzwarals“node-addon”überv8!

DieErklärung,wiediesbewerkstelligtwerdenkann,folgtindiesemKapitel.

3.6.2.3ZweckdesWrapping

SelbstverständlichstelltsichdieFrage,warumüberhauptmanC++-Objektesowrappensollte,dassmanmitdieseninjavascriptarbeitenkann.DieAntwortlautet

a)weilmaneskann!b)weilesVorteilebeiderGeschwindigkeitliefert:

DieÜberlegungist,nur1xzudeserialisieren.

3.6.2.4Installation,KompilierungundBenutzungderWeb-Schicht

ZunächsteinmalaberzumLauffähig-machenderWeb-Componente(auchhiergilt:bittevergleichenSieauchdieeinschlägigenKapitelin[Teilbesprechun-gen][]).

ImNormalfallsolltederKompilierungs-undInstallationsprozessfürdieWeb-Komponentedurchdencmake-Workflowautomatischübernommenwerden,den-nochandieserStelleeinpaarHinweiseimSpeziellenundzumVorgangallge-mein.

Dercmake-WorkflowbildetdieWeb-Komponente(ausZeitgründen)nicht(!)perdefaultundmussgesondertaktiviertwerden:

17if($ENV{sis_BUILD_WEB_COMPONENT})18set(sis_BUILD_WEB_COMPONENTON)19else()20set(sis_BUILD_WEB_COMPONENTOFF)21endif()

Dasheisst,esgibtzweiMöglichkeiten,denBuildderWeb-Komponenteanzus-tossen:

a)dendefaultinderoberstenCMakeLists.txt-Dateiauszutauschen,oder

198CHAPTER25.ÜBUNGEN

–VergleichenSiehierzuauchdielinks[link]und[link]

•Facebookundemailsindzwargutundnett,aberdamitSielernen,wiemansichoptimalHilfeholenkann,probierenSieIRCaus.DiesesProtokollistzwarschonälteralsdasWWW,abernochimmer“hängen”hierdieEn-twicklerderSoftwaredieSiebenutzen“ab”.MachenSiesichmitIRCunddendortherrschendenUmgangsformenvertraut.(Hinweis:effektivFra-genzustellenkannhierbedeuten,alleAnredenwie“Hallo”…“ichhabeeinProblem”…“kannmirjemandhelfen”wegzulassenundseinekonkrete(!)Fragedirektzustellen,ohnejemandenbesondershervorzuheben).Ver-wendenSiehierzueinenbeliebigenIRC-Client.DesweiterenhabenwireineneigenenIRC-ChatroomfürdiesenKurs:[irc.ifi.lmu.de?]

Page 64: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

64 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

b) eine environment-Variable auf ON zu setzen, womit der “volle” cmake-Befehl folgendermaßen aussieht:sis/build> SIS_BUILD_WEB_COMPONENT=ON cmake ..

(Der cmake-Befehl wird entsprechend eine Ausgabe liefern, die bestätigt oderverneint, ob die Web-Komponente gebaut wird):

[...]-- [WEB COMPONENT]-- Will NOT build web component[...]

bzw.

[...]-- [WEB COMPONENT]-- Will build web component[...]

Die Teile der Build-Kette für die Web-Komponente, die cmake automatischanstößt, umfassen:

• das Installieren der server-seitigen Dependencies• das Installieren der client-seitigen Dependencies• das Builden des node addon

server-seitige Dependencies installieren die server-seitigen Dependencieswerden in node immer mit dem node package manager npm installiert. Dieserliest die Datei package.json im obersten Verzeichnis aus und installiert diedort aufgeführten Dependencies (und rekursiv deren Sub-Dependencies).

sis/web> npm install

Hinweis: npm installiert seine projekt-spezifischen Pakete nach node_modules/.

client-seitige Dependencies installieren Die client-seitigen Dependencieswerden mit bower installiert. bower kümmert sich ebenfalls um das Auflösen vonAbhängigkeiten von Javascript-Paketen – nur eben, im Gegensatz zu npmˆ–, fürdie Client-Seite, also den Browser.

sis/web> bower install

Chapter 25

Übungen

Inhalt25.1Übung 1: git und Kollaboration . . . . . . . . . . . . 19925.2Übung 2: C-Wrapping . . . . . . . . . . . . . . . . . . 20125.3Übung 3: cmake . . . . . . . . . . . . . . . . . . . . . . 20325.4Übung 4: TDD – Test Driven Development . . . . . 20525.5Übung 5: Serialisierung . . . . . . . . . . . . . . . . . 20725.6Übung 6: Node-Wrapping . . . . . . . . . . . . . . . . 20925.7Übung 7: Template Meta Programmierung . . . . . 21125.8Übung 8: Type Traits . . . . . . . . . . . . . . . . . . 21325.9Übung 9: Web-Programmierung mit dem MEAN-

Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

Grundlegendes zu den Übungen:

• helfen Sie sich gegenseitig aber lernen Sie für sich selbst!

Warum:

• ohnehin kann ich nicht kontrollieren, ob Sie sich gegenseitig bei den Auf-gaben helfen (oder nicht)

• ohnehin sind die Abgaben der Übungen für den Dozenten lediglich einHinweis auf Ihren Lernerfolg

• ohnehin ist Ihr Lernerfolg langfristig gesehen nur für Sie selbst interessant• ohnehin ist jeder bei der Komplexität der Programmier-Materie perma-

nent auf die Hilfe von anderen angewiesen – zu lernen wie man sich gegen-seitig effektiv helfen kann, ist ein ganz ganz wichtiger, nicht zu unter-schätzender Teil! Nicht zuletzt gehört dazu auch, sich effektiv helfen zulassen, d.h. Fragen zu konkretisieren, Beispiele auf ein Minimum zu re-duzieren, etc.

197

Page 65: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN65

Hinweis:bowerinstalliertseineprojekt-spezifischenPaketenachbower_components/oderapp/bower_components/

VergleicheauchnocheinmaldieBeschreibungderProjektstrukturimKapitelProjektstruktur!

nodeaddonbuildenNichtzuletztmussnochdasnodeaddonkompiliertwerden,dassdieC++-ObjekteinJavascriptzurVerfügungstellt.Dafürwirdklassischerweisenode-gyp8alsBuild-Toolverwendet.

node-gypliestdieDateibinding.gypausundorientiertdaranseinenbuild-Prozess.

node-gypumfasstwiederummehreresub-befehle,imwesentlichenaberreichtein…

web/sis>node-gyprebuild

…um(implizit)einnode-gypbuildanzustossen.

binding.gypEineminimalebinding.gyp-Dateisiehtfolgendermaßenaus:

{"targets":[{"target_name":"hello","sources":["hello.cc"]

}]

}

AndieserStellesollendiewichtigstenAusschnittederbinding.gypvonSISinallerKürzebesprochenwerden:

{'targets':[{

'target_name':'sis','sources':[

'cpp/sis.cpp','cpp/DocumentIndexingAutomaton.cpp'

8gypstehtfür“GenerateYourProject”undwurdevonGooglefürdenBuild-ProzessvonChromeentwickelt:umdieKomplexitätdessenzuermessen,vergleiche:“LifeOfAChromiumDeveloper”aufhttp://dev.chromium.org/Home

Page 66: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

66 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

],'include_dirs': [

'/usr/include','<!@(echo `pwd`/../src/)','<!@(echo `pwd`/../vendor)','<!@(echo `pwd`/../vendor/serialization/include)','<!@(echo `pwd`/../vendor/make_unique)','<!@(echo `pwd`/../vendor/pugixml/src)'

],# global flags go here# `cflags_cc!` is supposed to mean: remove these flags'cflags_cc!': [ '-fno-rtti' ], # '-fno-exceptions'# `cflags_cc` is supposed to mean: add these flags

'cflags_cc': [ '-fPIC', '-std=c++11', '-fexceptions', '-Wall', '-Wextra', '-Wno-attributes', '-Wno-pointer-arith' ],'conditions': [

/* [......] */

Zu beachten sind folgende Punkte:

• include_dirs verlangt vollständige Pfade, daher der “Hack” über diecommandline

• cflags_cc! nimmt vorhandene Compiler-Flags weg• cflags_cc fügt Compiler-Flags an die bereits vorhandenen hinzu

Hinweise

• Hinweis für Server omega bzw. 64-bit-Systeme: Omega hat 2 verschiedeneVerzeichnisse, in denen libs liegen können: /usr/lib und /usr/lib64! ImFalle von fehlenden shared-objects auch dort suchen. Beim Build-Prozess

• Hinweis für spezielle Compiler: um SIS kompilieren zu können ist einGNU gcc Compiler >= 4.7.0 nötig. Ein solcher ist zwar möglicherweiseinstalliert, aber mit einem Namenssuffix versehen, d.h. liegt als g++-4.8oder ähnlich vor. Daher unbedingt den Standard-Compiler des akutellenSystems genauer unter die Lupe nehmen:

i) which gcc; gcc --version;ii) einen anderen compiler suchen – dabei die “einschlägigen” Pfade

durchsuchen, z.B.: ls /usr/bin/g++*iii) Diesen speziellen compiler nötigenfalls noch node-gyp “un-

terzuschmuggeln”: um den Compiler zu ermitteln, liest node-gyp dieENV-Variable CXX aus. Diese lässt sich am besten gleich auf denvollen Pfad von gcc setzen, der Befehl lautet also ungefähr:

Part IX

Übungen

195

Page 67: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

3.6.EBENEN67

CXX=whichg++-4.8node-gyprebuild

•Manchmalkannesvorkommen,dassbeimStartdesnodeServersdiesharedobjectsausdemnodewrappingnichtgefundenwerden;dahilftesdieVariableLD_LIBRARY_PATHentsprechendanzupassen:LD_LIBRARY_PATH=/srv/www/sis/sis3/build/lib:$LD_LIBRARY_PATHcoffeeapp.coffee

WebServerstartenumdenWeb-Serverzustarten,reichtesmitnodedieentsprechendejavascript-Dateizustarten.

DafürSIScoffeescriptstattjavascriptverwendetwird,stattdessendenserveralsomitdemBefehlcoffeestattnodestarten:coffeeapp.coffee.

DeployMitdeno.g.HinweisenimGepäcklässtsichdieApplikationnunauchaufdenServerdeployen(beachtehierzubitteauchdasKapitel[Derausführendeuserwastd][]).

UmimFalleeinesCrashsdenWeb-Serversofortwiederneuzustarten(spezielldiesesAddonmitseinerzugrundliegendenC-SchichitistsehrgefährdetfürSEG-FAULTs…),lässtsichdasnode-moduleforever9verwenden.SiehedieDateiweb/wast.startfürnähereDetails.

3.6.3NodeAddon

3.6.4NächsteSchritte

•AlternativzueinemNode-AddongibtesdieMöglichkeit,durchdieVerwendungvonemscripten(EmscriptenAuthors2013),C++nachJavascriptzukompilieren.AllerdingsmüsstendabeidiekomplettenIndex-DateienindenBrowserdesClientübertragenwerden,weshalbhiernurderHinweisaufemscriptengegebenwerdensoll.

9http://node-modules.com/search?q=forever

194CHAPTER24.MAILINGLISTE

•antwort-oben-zitat-unten?

•linkvonstefan

•linkzumailing-list-best-practicesbzwimportvondort

Page 68: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

68 CHAPTER 3. SIS: SYMMETRIC INDEX STRUCTURES

Chapter 24

Mailingliste

• Die Mailinglisten sind:

– wast-list – die allgemeine Mailingliste für WAST* https://lists.ifi.lmu.de/mailman/admin/wast-list

– wast-kurs – Mailingliste für den WAST-Kurs von Max und Daniel(SoSe 2014)* https://lists.ifi.lmu.de/mailman/admin/wast-kurs

• Die Mailinglisten laufen über die IFI: https://lists.ifi.lmu.de/

• wann kommt sie zum einsatz?

• wofür?

• wer ist drauf?

• Überlegungen:

• externe mailingliste für norweger, etc.

• interne für developer

• dort:

– announces für neue releases– diskussion intern

• Verweis auf best-practices / netiquette:

• thread-sortiertes antworten (warum: wieso soll es meine aufgabe sein, einealte mail rauszusuchen?, wie soll jemand im archiv die antwort finden?)

• warum? archivierbar, nachvollziehbar, multiplexing fähig

193

Page 69: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartIV

Feedback

69

192CHAPTER23.LIZENZEN

23.1GNUGPL

23.1.1GNUGPLv2

23.1.2GNUGPLv3

23.1.3GNULGPL

23.1.4GPL-Compaitibility

23.1.5AfferoGPL

23.1.6GPLv2Loophole

23.2MIT

23.3CreativeCommons

23.3.1CC-Bausteine

23.3.2NC-BY-SA

23.3.3NC-BY…

23.4WTFPL

Page 70: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter 23

Lizenzen

Inhalt23.1GNU GPL . . . . . . . . . . . . . . . . . . . . . . . . . 192

23.1.1 GNU GPLv2 . . . . . . . . . . . . . . . . . . . . . . 19223.1.2 GNU GPLv3 . . . . . . . . . . . . . . . . . . . . . . 19223.1.3 GNU LGPL . . . . . . . . . . . . . . . . . . . . . . . 19223.1.4 GPL-Compaitibility . . . . . . . . . . . . . . . . . . 19223.1.5 Affero GPL . . . . . . . . . . . . . . . . . . . . . . . 19223.1.6 GPLv2 Loophole . . . . . . . . . . . . . . . . . . . . 192

23.2MIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19223.3Creative Commons . . . . . . . . . . . . . . . . . . . . 192

23.3.1 CC-Bausteine . . . . . . . . . . . . . . . . . . . . . . 19223.3.2 NC-BY-SA . . . . . . . . . . . . . . . . . . . . . . . 19223.3.3 NC-BY … . . . . . . . . . . . . . . . . . . . . . . . . 192

23.4WTFPL . . . . . . . . . . . . . . . . . . . . . . . . . . . 192

Bei allen Entwicklungen – sowohl im kommerziellen wie auch in der “PublicDomain” –, ist die Frage nach Lizenzen als sehr wichtig einzustufen.Die Geschichte der “Open Source”- und “Free/Libre Software”-Lizenzen istsehr interessant und in erster Linie hier nachzulesen [Lessig, Lessig, Stallman,Moody].Kurz gesagt mussten sich die “Hacker” auch in Lizenzmodelle einarbeiten unddiese “hacken” um ihre Software zu schützen, daher die vielen verschiedenen,z.T. sich widersprechenden und komplizierten Lizenzmodelle.Im folgenden ein Kurzüberblick über die meistverwendeten Lizenzen und derenCharaktersitika – dies aber vollständig “ohne Gewähr”, um bei Entwicklungeninnerhalb von WAST die richtige Lizenz wählen zu können.[Lizenz-Wizard auch verlinken]

191

Page 71: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter4

feedback

Inhalt4.1Aufbau............................72

4.1.1Dateistruktur......................724.2Application-Logic.....................72

DieApplikationFeedback1dientalsWeb-Front-endfürdasreportingvonbugs,featurerequestsundalleranderenDinge,dierelevantsindfürdenBugtrackerunddiedahinterliegendenKonzepteder“BugTrackingBestPractices”.

Bugsundfeaturerequestssubmittenzukönnenkanninteressantseinfür

•Philosophen•Interessierte•dieKomponenten-Verwalterselbst•generallalle,dienichtgitlabverwendenwollen(oderkönnen)

AlsWeb-ApplikationistFeedbackkonzipiert,dagenerelljeder,dereinenBugimBugTrackereintragenmöchte,eineRegistrierungaufderWeb-Oberflächedesgitlab2benötigenwürde,diesesabereinezuhoheHürdedarstelltundBugRe-porteraufgrunddesAufwandsdavonabhaltenkönnte,wichtigeInformationenbereitzustellen.

DarüberhinausgarantiertFeedbackeinegeordeneteWeise,inderBugsabgelegtwerden,indemesbugsautomatischnachKomponentenundMaintainernsortiert(durchtags)direktindieBug-Listeeinträgt.

1https://gitlab.cis.uni-muenchen.de/wast/wast-feedback2http://gitlab.cis.lmu.de

71

190CHAPTER22.SEMANTICVERSIONING

ImobengegebenenBeispielhatsichXmitv14.02aufdieVersionvonWASTzumZeitpunktFebruar2014bezogen.DieVersionvonNovember2015wirdalso15.11sein.DabeiisteinmonatlicherRelease-Cyclegegeben.

Wiegesagt,diesistdieVersionierungnachaußen,d.h.imZusammenspielallerKomponenten.InderVersionierungnachinnensolltesichjedederKomponen-tenselbstjedochamBestenamSchemadesSemanticVersioningorientieren.

DementsprechendkanneinReleaseunddieVersiondesselbengenauerunterteiltwerden:

Beispiel:

•Release14.02könntenämlichindiesemSinneeineZusammenstellungderfolgendenKomponentengewesensein:

–WAB-Transkription2.3.1–wittfind-Komponente4.2.3–sis-Komponente3.9.1–…

22.1.2SemanticVersioning

ImwewsentlichenverstehtmanuntersemanticversioningeineVersionsangabemitfolgendemFormat:Major.Minor.Patch.

DabeistehenMajor-Versionenfür(z.T.)untereinandernicht-kompatibleAPIsodergroßeVeränderungen/VerbesserungenamCode,bzw.VerweisenaufwesentlicheEntwicklungsschritteimCode.

DieZahlunterMinorbezeichnetdenaktuellenEntwicklungsstanddesCodes.IndenmeistenFällenwerdenalsMinorungeradeZahlenverwendetumanzudeuten,dassdieseineEntwickler-Versionist,und,nachdemdieseEntwick-lungeinesbestimmtenFeatures(oderähnlichem)abgeschlossenist,diesedannumeinshochgezähltzueinergeradenZahl.

NichtzuletztwirdPatchbeibugfixeshochgezählt.

Vergleichez.B.

•Perl,Version5.19.4(Perl5,Weiterentwicklungvon5.18(alsEntwicklerver-sion),patch-level4)

•nodejs,Version0.10.20(Nochnichtals1.0.0-fähiganerkanntes,d.h.nochnichtkomplettstabilisiertes,dennochfortgeschrittenesProjektineiner0.10-er-“stableversion”mitpatch-level20)

MehrInformationenzuSematicVersioningfindensichbeihttp://semver.org/(TomPreston-Werner2013)

Page 72: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

72 CHAPTER 4. FEEDBACK

4.1 Aufbau

Der Aufbau von Feedback gestaltet sich in Form ein MEAN-Stack Web-Applikation, welche das Frontend und Backend bildet.

Im Backend wird im wesentlichen die API des Gitlab genutzt, um Bugs eintzu-tragen.

Um mit der API von Gitlab sprechen zu können bedarf eines eines sogenan-nten “Private Token” zur Authentifizierung. Hierfür wurde ein gesonderterUser (“FeedbackBot”) angelegt, dessen Token verwendet wird, um Bugs zusubmitten (dieses geheimzuhaltende Token wird auf der Serverseite bereitge-halten und nicht in das Frontend, zum Client übertragen). Um innerhalb vonWittgenstein-Issues3 bugs submitten zu können, muss FeedbackBot selbstver-ständlich als Member im Projekt vorhanden sein.

4.1.1 Dateistruktur

.|-- Makefile # targets zum starten, stoppen, restart|-- README.md|-- bower.json # ini-file für client-seitige dependencies|-- bower_components # Ordner für client-seitige dependencies|-- database # MongoDB-Anbindung|-- node_modules # Ordner für Server-seitige dependencies|-- npm-shrinkwrap.json # ini-file für server-seitige dependencies (unwichtig)|-- package.json # ini-file für server-seitige dependencies (wichtig)|-- public # client-seitiger Applikationsteil: Application-Logic (AngularJS)|-- routes.js # Server-seitige Routes|-- views # client-seitiger Teil: Views (Jade)`-- wast-feedback-server.js # Der Web-Server selbst (node)

4.2 Application-Logic

Der operationale Ablauf der Web-Applikation gestaltet sich folgendermaßen:

1. User geht auf2. Er ist noch nicht eingeloggt (wittgenstein-issues soll nicht von Bots ges-

pammed werden)3. User logged sich ein (CIS/lmu)4. User füllt Formular aus:

a. Das Formular wird permanent auf Vollständigkeit geprüft (ansonstenwird live eine Warnung/Hilfe angezeigt)

3https://gitlab.cis.uni-muenchen.de/wast/wittgenstein-issues/issues

Chapter 22

Semantic Versioning

Inhalt22.1Versions-Schema . . . . . . . . . . . . . . . . . . . . . . 189

22.1.1 Ubuntu-Schema . . . . . . . . . . . . . . . . . . . . . 18922.1.2 Semantic Versioning . . . . . . . . . . . . . . . . . . 190

Die Versionierung (in Zusammenarbeit mit der gemeinsamen Bug Verwaltung)garantiert Referenzierbarkeit hinsichtlich der Zitierbarkeit für die Philosophie(und darüber hinaus).

Beispiel:

• Der Philosoph X schreibt einen Aufsatz und benutzt die Transkription ausNorwegen.

• Er behauptet Y in seinem Artikel und referenziert sauber seine Quelle. Inetwa: WAST, v14.02

• Der Artikel wird veröffentlicht, und später wird entdeckt, dass X’s Be-hauptung Y ungültig ist, da die Transkription einen Fehler enthielt

• Nun hat X aber Y unter Voraussetzung der Version 14.02 behauptet undkann nicht die Verantwortung für den Transkriptions-Fehler übernehmen.

22.1 Versions-Schema

22.1.1 Ubuntu-Schema

Das Versionsschema von WAST orientiert sich nach außen am Versions-Schemavon Ubuntu. Dabei wrid die Versionsnummer zusammengesetzt aus derJahreszahl und dem Monat des Releases.

189

Page 73: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

4.2.APPLICATION-LOGIC73

b.UserbeschreibtseinenBuggenau(nachdenRegelndesWAST-Workflow:wie/wann/woerscheintdieserFehler,wiekannmanihnreproduzieren,etc.)undhinterlässtseineemail-Adresse:dadurchkanneramEndeeinesresolvetenBugsverify-enobderBuginseinemSinnegelöstwurde

5.UserschicktFormularab:

a.einPOST-RequestaufeinebestimmteServer-RoutewirdmitdenDatendesFormularsgetätigt

b.DerWeb-ServerhateinebestimmteLogikimplementiert,waspassierensoll,wennereinenPOST-RequestaufdieserRouteentgegennimmt:

c.DerWeb-ServernimmtdenprivatenTokendesFeedbackBotundschicktmiteinemcurl-RequesteineBugsubmissionandieAPIvongitlab.

d.DerServersagtderClient-Seite,obererfolgreichmitdergitlab-APIsprechenkonnte

e.DieClient-SeitegibtdemUsereineRückmeldung,obderBugerfol-greicheingetragenwerdenkonnte.

6.DemUserstehtesfrei,einenweiterenBug-Reportzusenden(alsozurückzu1.)oderfertigzusein.

Hinweis:FüreinegenauereBeschreibungvonClient-Seite/Server-SeitesiehedasKapitelWeb-Applikationen,füreineBeschreibungdereinzelnenKomponentensiehedasKapitelMEAN-StackundfüreineBeschreibungderApplikations-LogikhinsichtlichController,View,etc.,vergleichedasKapitelDesignPatterns.

188CHAPTER21.VERSIONIERUNG

#[Ingitlabisteinissueimbugtrackereröffnet]pltk@master$gitbugissue-66pltk@bug/issue-66$[hackhack...]pltk@bug/issue-66$[letztercommit]pltk@bug/issue-66$gitcheckoutmasterpltk@master$gitfeaturefinishissue-66

Page 74: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

74 CHAPTER 4. FEEDBACK 21.1. GIT 187

21.1.3 git-extras

git-extras (visionmedia 2014) geben viele nützliche (neue) Kommandos zu denStandard git-Kommandos hinzu.

Dadurch kürzen sie einige Wege ab, oder erleichtern andere, routine-mäßigeAufgaben.

Da sie aber mit Hilfe der von git selbst zur Verfügung gestellten Kommandosimplementiert sind, könnte man selbstverständlich alles auch ohne git-extrasmachen.

Dennoch können die git-extras als eine sinnvolle Empfehlung betrachtet werden.

21.1.3.1 Installation auf CIP-Rechnern

Um die git-extras auf den CIP-Rechnern zu installieren kann man folgendesVerfahren nutzen:

git clone https://github.com/visionmedia/git-extrascd git-extrasmake DESTDIR=$HOME PREFIX="" install

Ich empfehle sehr, die git-extras9 zu verwenden und schlage folgendes Branching-Model vor:

• Der master branch wird nur für fertiggestellte Funktionalität verwendet• gearbeitet wird auf dev/feature/bug und refactor branches• dann merges oder pull requests• zuletzt ein release

Mit git-extras ist das wirklich einfach: Anstatt selbst einen Branch anzulegen,auf diesen zu wechseln, dort zu arbeiten, dann diesen Branch in den master-Branch zu mergen, bietet sich u.a. folgender Workflow an:

pltk@master$ git feature lemmatizerpltk@feature/lemmatizer$ [hack hack (möglichst kleine Commits bitte!)]pltk@feature/lemmatizer$ git commit -am 'last commit'pltk@feature/lemmatizer$ git checkout masterpltk@master$ git feature finish lemmatizer

Bei Bug-Fixes schlage ich folgendes Modell vor:9https://github.com/visionmedia/git-extras

Page 75: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartV

WeitereKomponenten

75

186CHAPTER21.VERSIONIERUNG

5.dendev-branchlöschen(sonstentstehtbaldChaos!)

>gitbranch-ddevDeletedbranchdev(was46b34ab).

ZuguterletztwollenwirdieErgebnisseaufeinremote-repositorypushen.

Dafürcheckenwirerstmalobremoteseingetragensind:

>gitremote-v[keinoutput]

Dahertragenwirunsereersteremote-Adresseeinundnennensieorigin:

>gitremoteaddoriginname@machine:path/to/bare/repository.git>gitremote-voriginname@machine:path/to/bare/repository.git(fetch)originname@machine:path/to/bare/repository.git(push)

…dabeifunktionierendieAngabenfürremote-repositoriesgenauwiebeimssh-Protokoll:

•name@machinefürdenZugang•gefolgtvoneienmDoppelpunkt:•gefolgtvomPfadzumrepositorypath/to/bare/repository.git•(indiesemFalldeutetderrepository-Namerepository.gitan,dassdies

einsog.git“bare”repositoryist,dazuanandererStellemehr).

WenndasVerzeichnisexistiertunddiePfadangabestimmt,lässtsichnunaufdiesesrepositorypushen:

>gitpushoriginmaster

Hierbeipushenwirunserenbranchmasteraufdasremote-repositorymitdemNamenorigin.

Äquivalentdazuistderpull,d.h.Änderungen(diewomöglichvonanderen)indasremote-repositoryge-push-twordensind,abzuholen:

>gitpulloriginmaster

Page 76: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

21.1. GIT 185

# (use "git add <file>..." to include in what will be committed)## var/nothing added to commit but untracked files present (use "git add" to track)

2. den dev-branch mergen

> git merge devUpdating 9112df6..46b34abFast-forward.gitignore | 1 +eos.pl | 15 +++++++++++++++eos.t | 4 ++++3 files changed, 20 insertions(+)create mode 100644 .gitignorecreate mode 100755 eos.plcreate mode 100644 eos.t

3. Die vorhandenen Dateien prüfen

> ls -1READMEeos.pleos.tvar

4. Den log prüfen

> git --no-pager log --graph* commit 46b34ab61c7f23ed6d4fbb2baf7dca468bbfb07d| Author: NAME <EMAIL>| Date: DATE|| add first version of eos + test data|* commit 1f986bd9d98e04aa5ea73a68ea9cbf83a736da7a| Author: NAME <EMAIL>| Date: DATE|| add gitignore|* commit 9112df662257116774d946cb5482116263cbc511

Author: NAME <EMAIL>Date: DATE

add documentation

Page 77: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter5

wab2cis

Inhalt5.1Einbindungalsgit-submodule..............77

VerwendungvonTEI,[sieheauchSonderkapitelTEI]

5.1Einbindungalsgit-submodule

ZurVerwendungvongit,sieheKapitelgitsubmodules.

77

184CHAPTER21.VERSIONIERUNG

InteressantwirdnunfolgendesExperiment:WirlassenunsganzgewöhnlichvondershelldenInhaltdesVerzeichnissesanzeigen,wechselndannindenmaster-branchundschauenunsdenVerzeichnisinhalterneutanundvergleichenbeideErgebnisse.

>gitbranch*dev

master

>ls-1READMEeos.pleos.tvar

>gitcheckoutmasterSwitchedtobranch'master'>ls-1READMEvar

>gitcheckoutdevSwitchedtobranch'dev'>ls-1READMEeos.pleos.tvar

DasErgebnisistdurchausausverblüffendzubezeichnen:githattatsächlichaufFile-System-Ebene(!)dieDateien“ausgetauscht”unddasVerzeichniskomplettverändert.

AlsnächstesnunwollenwirdieEntwicklungunsereseoshierbeendenunddendev-branchnunindenmaster-branchzurück-mergen.Dafürwerdenwirfolgendestun:

1.Aufdenmasterbranchwechseln

>gitcheckoutmasterSwitchedtobranch'master'

>gitstatus#Onbranchmaster#Untrackedfiles:

Page 78: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

78 CHAPTER 5. WAB2CIS 21.1. GIT 183

git hat schon die Datei .gitignore ausgewertet und zeigt das Verzeichnis vargar nicht mehr als potentiell-hinzuzufügende Datei an!Um schöne kleine commits zu haben (die man im Notfall später leichter “zurück-spielen” kann), werden wir die fehlenden Dateien nur Stück für Stück zum repos-itory adden:

> git add .gitignore

> git commit -am 'add gitignore'[dev 1f986bd] add gitignore1 file changed, 1 insertion(+)create mode 100644 .gitignore

> git status# On branch dev# Untracked files:# (use "git add <file>..." to include in what will be committed)## eos.pl# eos.tnothing added to commit but untracked files present (use "git add" to track)

> git add eos.*

> git commit -am 'add first version of eos + test data'[dev 46b34ab] add first version of eos + test data2 files changed, 19 insertions(+)create mode 100755 eos.plcreate mode 100644 eos.t

> git status# On branch devnothing to commit (working directory clean)

Nun können wir bereits die kurze History unseres repository anschauen, z.B. indiesem Format:

> git log --oneline --decorate --graph* 46b34ab (HEAD, dev) add first version of eos + test data* 1f986bd add gitignore* 9112df6 (master) add documentation

…und sehen hierbei die Bezeichnungen für die jeweiligen branches auf denen dieÄnderungen gemacht wurden, und den aktuellen HEAD.

Page 79: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter6

WIndex

79

182CHAPTER21.VERSIONIERUNG

>chmodu+xeos.pl

UndlegennocheinVerzeichnisfürErgebnissevonunterschiedlichenTestläufenan–dieseErgebnisseunddasgesamtezugehörigeVerzeichniswerdenwirabernichtinunserencommitshabenwollenundignorieren:

>mkdirvar

>cateos.t|./eos.pl>var/res.1

DieAusgabevongitstatusistmittlerweilealsoschonvertraut:

>gitstatus#Onbranchdev#Untrackedfiles:#(use"gitadd<file>..."toincludeinwhatwillbecommitted)##eos.pl#eos.t#var/

gitteiltunsalsomit,dasseszweiDateienundeinVerzeichnisinunseremProjektgibt,dassesnochnichtkennt,diewiraberpergitaddzuunsererVersionskontrollehinzufügenkönnen.

DawirdasVerzeichnisfürZwischenergebnisse,abernichttrackenundlieberignorierenwollen,tunwirfolgendes:wirlegeneineDatei.gitignorean,diealleDateienundVerzeichnisselistet,diegitignorierensollundfügendieseindasrepositoryhinzu.

echovar/>>.gitignore

NunzeigtgitstatusfoldenesinteressantesErgebnis:

gitstatus#Onbranchdev#Untrackedfiles:#(use"gitadd<file>..."toincludeinwhatwillbecommitted)##.gitignore#eos.pl#eos.t

Page 80: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

80 CHAPTER 6. WINDEX 21.1. GIT 181

…was bedeutet, dass es einen branch namens dev gibt, der aktuelle branch abernoch auf master steht. Das wollen wir ändern:

> git checkout devSwitched to branch 'dev'

Wie erwartet, haben wir in den branch dev gewechselt und können dies auchüberprüfen:

> git branch* dev

master

Hier also können wir neue Funktionalität entwickeln, ohne die Hauptentwick-lungslinie zu beeinträchtigen.

Legen wir also als nächstes unsere ersten Dateien des Satzendeerkenners an, mitfolgenden Inhalten:

> cat eos.pl#!/usr/bin/env perl -0 -ps/((((Mr|[[:upper:]]|\d+)\. # Ausnahmen: Abkürzungen etc.|.+? # alles andere (non-greedy,

# d.h. 1. nicht [.!?] gefolgt von SPACE + Großbuchstabe)# 2. keine Abkürzung

)+? # eine Folge von Abkürzungen oder "alles"[.!?](?=\s+[[:upper:]]) # EOS))

/$1<EOS>/gx;EOS

> cat eos.tEin Satz? Hier auch! Am 19. August 1972 schläftMr. G. W. Spencer. Hier beginnt ein Satz. In derOettingenstr. 67 stehen Computer.Perl arbeitet hier zeilenweise, Sätze dürfen nicht über Zeilen gehen.TXT

Als nächstes machen wir das Programm ausführbar:

Page 81: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter7

Patrick’sTeil:AusformulierungvonAlternativen

81

180CHAPTER21.VERSIONIERUNG

AlsnächsteswollenwirinderEntwicklungunseresSatzende-Erkennersfort-fahrenunddabeieinesvongit’swichtigstenfeaturesnutzen,dasbranching,d.h.wirzweigenvonderHauptentwicklungslinieweg,umeineneueFunktional-itätzuentwickelnundwerdendiese,sobaldsiefertigist,wiederindieHaupten-twicklungsliniezurückführen(mergen).gitistimVergleichzusvnsehrsparsambeimAnlegenvonneuenbranchesundfördertdasAnlegenundmergenvonbranchessehr.

Alsersteswollenwireinmalgucken,obesdennvielleichtzufälligschonbranchesgibt:

>gitbranch*master

Offensichtlichgibtesderzeitnureinenbranch,undzwardenbranchmaster.

Vorsicht!GitzeigtindiesemFallnurunserelokalenbranchesan,nichtaberpotentiellebranchesdieaufservernliegen!Bisherhabenwirnochkeinesog.remotes(alsoentfernterepositories,wiezumBeispielein“Zentral-”Repository)eingetragen,aberumpotentiell“entfernte”branchesanzeigenzulassen,brauchenwirfolgendenSwitch:

>githelpbranch[...]-a,--all

Listbothremote-trackingbranchesandlocalbranches.[...]

DaaberkeineremotesexistierenwirddasErgebnisvongitbranch-aalsodasselbeergebenwiegitbranch(nurlokalebranchesanzeigen):

>gitbranch-a*master

NunalsosollendlicheinbranchfürdieEntwicklungmitdemNamendevan-gelegtwerden:

>gitbranchdev

Einerneutercheck,welchebranchesexistieren,zeigt:

>gitbranchdev*master

Page 82: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

82CHAPTER 7. PATRICK’S TEIL: AUSFORMULIERUNG VON ALTERNATIVEN 21.1. GIT 179

commit 9112df662257116774d946cb5482116263cbc511Author: AUTORENNAME <EMAILADRESSE></emailadresse>Date: DATUM

add documentation

Anders als svn hat git keine “klaren” Revisions-Nummern wie r1 etc., sondernstatt dessen 40-stellige SHA-Summen für jeden commit.

Dies hat mehrere Vorteile (vergleiche Daten-Sicherheit[ˆsiehe oben, und hier[[link einfügen]]]), aber auch einen entscheidenden Nachteil: sie sind menschlichschlecht lesbar.

Es gibt mehrere Möglichkeiten, sich nicht diese 40-stelligen Nummern merken zumüssen, um, z.B. um mit jemand anderen über eine bestimmte Revision redenzu können.

Hierzu gibt es verschiedene Strategien, die git anbietet, z.B.: Abkürzen derSHA-Summe auf wenige Stellen (solange der damit gemeinte commit eindeutigbleibt). In der Regel einigt man sich auf die ersten 6 Stellen wenn man übereinen konkreten commit sprechen will, in diesem Fall also:

9112df

Nebenbemerkung für Interessierte: Es gibt einen sogenannten git plumbing com-mand (sozusagen ein Kommando um mit git selbst zu arbeiten, das aber gewöhn-lich nicht im Alltag gebraucht wird (dies wären die porcelain commands)), dasanzeigt, was git aus einer solchen abgekürzten Revisions-Nummer herausliest:

> git rev-parse 9112df9112df662257116774d946cb5482116263cbc511

Eine weitere Strategie, Revisionsnummern menschlich zugänglicher zu machen,besteht darin, Aliases zu verwenden.

Dies kann geschehen durch:

1. das Alias HEAD, HEADˆ, HEADˆˆ um jeweils auf den letzten, vorletzten, vor-vor-letzten commit zu referenzieren

2. oder durch die Aliase HEAD@{1}, HEAD@{2} um auf die selben commits zureferenzieren

3. durch tags: später werden wir sehen, wie man bestimmte Revisionen ex-plizit “benennen” kann durch git tag. So könnte man also einen ganzbestimmten 40-stelligen commit als v1.2.3 taggen und somit genau dasgleiche meinen.

Page 83: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartVI

Toolchain

83

178CHAPTER21.VERSIONIERUNG

>gitaddREADME

MitdiesemBefehlwurdedieDateiabernochnichtendgültigindasrepositoryaufgenommen:vielmehrwurdedieDateiindiesog.stagingarea(InAbbil-dung21.1aufSeite176“Index”genannt)übernommenundwirdbeimnächstencommitendgültigindasrepositoryaufgenommenwerden.EinweitererVergleichdesvorherigenStatusmitdemjetzigenStatusverdeut-lichtdies:

>gitstatus

…liefertunsnunfolgendenOutput:

#Onbranchmaster##Initialcommit##Changestobecommitted:#(use"gitrm--cached<file>..."tounstage)##newfile:README#

DadiesdieeinzigeÄnderungist,diewirindiesemChangesetausführenwollen(iwrkönntenauchnochweitereDateienaddenunderstdanncommiten),machenwireinencommit:

>gitcommit-am'adddocumentation'

Nunwird…

>gitstatus

…folgendesmelden:

#Onbranchmasternothingtocommit(workingdirectoryclean)

d.h.wirbefindenunseinem“clean-state”,d.h.alleaktuellenÄnderungensindbekanntundessindkeineweiterenÄnderungenanirgendwelchenDateienunseresrepositoryvorgenommenworden.UmdieseletzterenÄnderungenzuverfolgenbetrachtenwiralsnächstesdenOutputvongitlog:

Page 84: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

21.1. GIT 177

> git commit -am 'initial commit'

Dabei stellen die (kombinierten) Kommandozeilen Switches folgendes dar:

-a Füge alle git bereits bekannten Dateien zum commit hinzu (bisher habenwir solche noch nicht, aber gewöhnlich wird immer ein git commit -a -mverwendet werden)

-m MESSAGE die commit message, welche in den log eingetragen wird

Als nächstes werden wir gleich unsere erste Datei in das repository einfügen,wollen davor aber noch kurz den aktuellen status des repository betrachten:

> git status

Hierauf wird git etwa folgendes antworten (je nach Spracheinstellung):

# On branch master## Initial commit## Untracked files:# (use "git add <file>..." to include in what will be committed)## READMEnothing added to commit but untracked files present (use "git add" to track)

Was dies im einzelnen bedeutet:

0. Wir befinden uns auf dem branch master (mehr zum Thema branching,s.u.)

1. Das repository ist noch vollständig “initial”, d.h. es wurden noch keineDateien hinzugefügt

2. Es gibt “untracked files”, also Dateien, die im Verzeichnis liegen, git abernicht bekannt sind. Diese Dateien können git auf zweierlei Arten bekanntsein0. Sie wurden dem repository hinzugefügt durch git add1. git wurde mitgeteilt diese Dateien im repository-Pfad zu ignorieren

(mit Hilfe der Datei .gitignore)3. wie die Dateien hinzugefügt werden können, sagt git auch gleich: durch

git add und zählt die ihm unbekannten Dateien auf (in diesem Falllediglich die Datei README).

Nun also zum Hinzufügen der ersten Datei:

Page 85: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter8

gitlab

ImRahmenderEntwicklungvonWASTspieltdasselbst-gehostetegitlabdesCISuntereineganzentscheidendeRolle.

ZudenwesentlichenAufgaben,dieübergitlablaufen,zählt:

•dasZusammenfließendereinzelnenKomponenten•dieVersionierungmitgit•damitdieCode-Verwaltung•AccessControl:nichtjederdarfallesjederzeitverändern•KommunikationinnerhalbdesTeamsüberCode-spezifischeBelange•BugTracking(repositorywittgenstein-issues)•Code-Review:

a)codereviewvoncodedereinenbugfixdarstellt(vergleiche[BugTrackingWorkflow][]unddort:status:verify)

b)vonneuemcodedercommitedwird:mitgitlablassensichanderecodebaseseinfach“passiv”verfolgenundbequemHinweiseundKom-mentareaufZeilenebenegeben.

•nichtzuletztistdasgitlabderzentraleAnkerfürdieContinuousIntegra-tion.

85

176CHAPTER21.VERSIONIERUNG

Figure21.1:Gitoverview

Page 86: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

86 CHAPTER 8. GITLAB 21.1. GIT 175

21.1.2.1 Überblick

Im Gegensatz zu svn gibt es bei git mehr Ebenen als nur “local repository” und“upstream repository”.

Abbildung 21.1 auf Seite 176 gibt ein Überblick7 über die unterschiedlichenEbenen und die Interaktion zwischen denselben:

21.1.2.2 Beispiel: Szenario 1: ein eigenes repository erstellen

Nachdem man seinen Namen und seine email-Adresse in git konfiguriert hat,kann man bereits beginnen, produktiv zu arbeiten.8

Nehmen wir als Beispiel ein Projekt genannt eos, das Satzende-Erkennung be-handeln soll.

Als erstes legen wir ein Verzeichnis an, in dem das Programm entwickelt werdensoll.

> mkdir eos && cd $_

Nun legen wir eine Datei README an, welche die wesentlichen Punkte des repos-itories erläutert:

> cat <<HERE >READMEeos---

an end-of-sentence recognizerHERE

Nun machen wir aus dem reinen Verzeichnis ein repository…

> git init

In diesem Befehl wird git ein (verstecktes) Verzeichnis .git in unserem Projektanlegen, also in eos/.git, in welchem es das repository verwaltet.

Als nächstes machen wir sogleich den ersten commit, um unserem repositoryeine “Geschichte” zu geben – ab hier beginnt nun also die Versionierung unseresProjekts:

7diese Graphik ist inspiriert von http://www.ndpsoftware.com/git-cheatsheet.html unddort interkativ mit Erklärungen zu den jeweiligen Ebenen und Interaktionen verfügbar

8Zu diesem Punkt ist u.a. diese Hilfe sehr gut geeignet: https://help.github.com/articles/set-up-git#set-up-git

Page 87: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter9

ContinuousIntegration

Inhalt9.1Definition..........................879.2CI@CIS...........................899.3Referenzen.........................89

9.1Definition

UnterContinuousIntegration(CI)verstehtman:

ContinuousIntegrationisasoftwaredevelopmentpracticewheremembersofateamintegratetheirworkfrequently,usuallyeachpersonintegratesatleastdaily-leadingtomultipleintegrationsperday.Eachintegrationisverifiedbyanautomatedbuild(includ-ingtest)todetectintegrationerrorsasquicklyaspossible.Manyteamsfindthatthisapproachleadstosignificantlyreducedintegra-tionproblemsandallowsateamtodevelopcohesivesoftwaremorerapidly.ThisarticleisaquickoverviewofContinuousIntegrationsummarizingthetechniqueanditscurrentusage.1

Abbildung9.1aufSeite88verdeutlichtdenWorkfloweinerCI.

1http://www.martinfowler.com/articles/continuousIntegration.html

87

174CHAPTER21.VERSIONIERUNG

whenafilewasrenamed,addedordeletedetc)Gitdoesn’texplicitlytrackthisinformationinanywayatall.Itinsteadtrackscontentwithinarepository.BywalkingtherepositoryhistoryGitcanrecon-structwhathappenedtoaparticularfile,butthisisanextrapolationfromthedataratherthansomethingexplicitlyencoded.Thisisaradicaldeparturethatmeansthatwhenyoudosomethinglikecuttingamethodfromonefileandpastingitintoanotherthenthehistoryofthemethodgoesalongwithit(thinksvnblame).ThisisexplainedbyLinusTorvaldsinthispost;seealsothisseparatepostontrackingrenames.Firstoff,let’sjustpositthat“files”donotmatter.Theonlythingthatmattersishow“content”movedinthetree.Ok?IfIcopyafunctionfromonefiletoanother,theperfectSCMwillnoticethat,andshowitasadiffthatremovesitfromonefileandaddsittoanother,andisstillabletotrackauthorshippastthemove.5

21.1.1.5Lowbarriertoparticipation

NichtzuletzterlaubtesgitaufeinfachsteWeiseeineigenesvollständig-funktionierendescode-repositoryaufzusetzen.BeisvnwirdfürdiesenSchritteinservermitlaufendemsvnbenötigt–undistdamitzumeistaneinenAdministratorgebunden,z.B.umeinneuesrepositoryzuerstellen.

Eineinfachesgitinit--barereichtaus,umeinvollständigesgitrepositoryanzulegen,aufwelchesmanseineÄnderungenpushenundmitanderenkolla-borierenkann.ImEndeffektistdiesbereitseinkleiner“gitserver”–wennmansowill:

ItisincrediblyeasytostartmanagingcodewithGit.UnlikeSub-versionthereisnoneedtosetuparepositoryona(possiblyremote)serverbeforestartingtowork.GitisevensimplerthanSVK,be-causewhatwouldnormallybeconsidereda“workingcopy”actuallybecomesa(distributed)repositoryitself,containingboththe“work-ingcopy”andallofthehistoryoftherepository6

21.1.2gitbasics

UmschnellermitgitarbeitenzukönnenwerdenimfolgendendiewesentlichenerstenSchrittedetaillierterklärtunderläutert.AufjedenFallwirdempfohlen,weitereLiteraturzudiesenThemenzukonsultieren.

5https://wincent.com/wiki/Git_advantages6https://wincent.com/wiki/Git_advantages

Page 88: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

88 CHAPTER 9. CONTINUOUS INTEGRATION

Figure 9.1: Continuous Integration

21.1. GIT 173

try new ideas without worrying about having to plan how and whenthey are going to merge it in or share it with others.There are ways to accomplish some of this with other systems, butthe work involved is much more difficult and error-prone. Git makesthis process incredibly easy and it changes the way most developerswork when they learn it.2

21.1.1.2 effizient, klein und schnell

Small and Fast Git is fast. With Git, nearly all operations areperformed locally, giving it a huge speed advantage on centralizedsystems that constantly have to communicate with a server some-where.Git was built to work on the Linux kernel, meaning that it has hadto effectively handle large repositories from day one. Git is writtenin C, reducing the overhead of runtimes associated with higher-levellanguages. Speed and performance has been a primary design goalof the Git from the start.3

21.1.1.3 verteilt

Distributed One of the nicest features of any Distributed SCM, Gitincluded, is that it’s distributed. This means that instead of doinga “checkout” of the current tip of the source code, you do a “clone”of the entire repository.Multiple Backups This means that even if you’re using a central-ized workflow, every user essentially has a full backup of the mainserver. Each of these copies could be pushed up to replace the mainserver in the event of a crash or corruption. In effect, there is nosingle point of failure with Git unless there is only a single copy ofthe repository.Any Workflow Because of Git’s distributed nature and superbbranching system, an almost endless number of workflows can beimplemented with relative ease.4

21.1.1.4 Content-tracking rather than file-tracking

Whereas every other version control system in the world tracks filehistory (when lines were added to a file, when lines were removed,

2http://www.git-scm.com/about/branching-and-merging3http://www.git-scm.com/about/small-and-fast4http://www.git-scm.com/about/distributed

Page 89: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

9.2.CI@CIS89

9.2CI@CIS

DieWebseitefürdieCIamCISfindetsichunterhttps://gitlabci.cis.lmu.de/2.

InnerhalbderCIlassensichdannProjekte,dieimgitlabverfügbarsind,zuautomatisiertenTestshinzufügen.

Dafürgibtmanimwesentlichenan,wiedieSoftwarezutestenistunderhältdannnachjedempushvonÄnderungeninseinRepositoryautomatischdiesesgetestet.

DamitergibtsicheineguteRückversicherung–undnichtzuletzteinegutnachaußenhinsichtbareFrom,dasssämtlicheSoftwaresichineinem“ship-baren”,alsogesundenZustandbefindet.DasschafftVertrauenundistauchinnerhalbdesTeamshöchstpraktisch.

EineausführlicheAnleitungwiedieCIzubenutzenistfindetmanhier:https://gitlab.cis.lmu.de/schweter/cis-ci/tree/master(erreichbarüberhttps://gitlab.cis.lmu.de/public).

DerMaintainerderCIistStefanSchweter([email protected])unddieCIumfasstderzeitetwa4virtuelleMaschinen(einbunterMixausDebian,Ubuntu,Suse,etc.)welchezufälligausgewähltwerdenunddieTestsausführen.Damitwirdsogarnocheinbisschen“Smoke-Testing”verhaltenemuliertundsichergestellt,dassdieinnerhalbvonWASTentwickelteSoftwareauchaufan-derenBetriebssysteminstallierbaristunddieTestsbestehen.

9.3Referenzen

DasThemaCIhängtengzusammenmitdenThemen:

•TestDrivenDevelopment•gitlab•Versionierung•[UnitTests]•IntegrationTests•BuildSysteme

2unbedingthttpsverwenden,sonstkannessein,dassmanvonhttpnichtweitergeleitetwirdaufhttps!

172CHAPTER21.VERSIONIERUNG

DiesenentscheidendenUnterschiedzubegreifenkanndurchauseinenMomentbrauchenunddieUmstellung,bismansichingitwirklich“zuHause”fühlt,kanneinenMomentdauern.

TrotzallemaberhatgitdieEntwickler-WeltimSturmerobertunddasausgutenGründen.

DieKombinationausgitundgitlabalsonline-Kollaborations-OberflächebieteteineMengeanüberzeugendenVorteilenfürdiegemeinsameEntwicklungvonSoftware,wieimfolgendenkurzdargestelltwerdensoll.

21.1.1Vorteilevongit

21.1.1.1branchingundmerging

Dasfreie“gitBook”1schreibtdazu:

TheGitfeaturethatreallymakesitstandapartfromnearlyeveryotherSCMoutthereisitsbranchingmodel.Gitallowsandencouragesyoutohavemultiplelocalbranchesthatcanbeentirelyindependentofeachother.Thecreation,merging,anddeletionofthoselinesofdevelopmenttakesseconds.Thismeansthatyoucandothingslike:FrictionlessContextSwitching.Createabranchtotryoutanidea,commitafewtimes,switchbacktowhereyoubranchedfrom,applyapatch,switchbacktowhereyouareexperimenting,andmergeitin.Role-BasedCodelines.Haveabranchthatalwayscontainsonlywhatgoestoproduction,anotherthatyoumergeworkintofortest-ing,andseveralsmalleronesfordaytodaywork.FeatureBasedWorkflow.Createnewbranchesforeachnewfeatureyou’reworkingonsoyoucanseamlesslyswitchbackandforthbetweenthem,thendeleteeachbranchwhenthatfeaturegetsmergedintoyourmainline.DisposableExperimentation.Createabranchtoexperimentin,realizeit’snotgoingtowork,andjustdeleteit-abandoningthework—withnobodyelseeverseeingit(evenifyou’vepushedotherbranchesinthemeantime).Notably,whenyoupushtoaremoterepository,youdonothavetopushallofyourbranches.Youcanchoosetosharejustoneofyourbranches,afewofthem,orallofthem.Thistendstofreepeopleto

1http://www.git-scm.com/book

Page 90: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

90 CHAPTER 9. CONTINUOUS INTEGRATION

Chapter 21

Versionierung

Inhalt21.1 git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

21.1.1 Vorteile von git . . . . . . . . . . . . . . . . . . . . . 17221.1.2 git basics . . . . . . . . . . . . . . . . . . . . . . . . . 17421.1.3 git-extras . . . . . . . . . . . . . . . . . . . . . . . . 187

In praktisch jedem Software-Projekt ist Versionskontrolle unerlässlich um Sicher-heit zu garantieren und Übersichtlichkeit zu wahren.

Hinsichtlich der Auswahl von Versionskontrollsystemen gibt es eine Vielzahl vonProdukten, die sich verwenden lassen:

• cvs• svn• mercurial• bitkeeper• git

21.1 git

Die meisten Teile der WAST-Landschaft sind mit git versioniert da dieses Sys-tem die meisten Vorteile bietet.

Als beliebteste Versionskontrollsysteme sind natürlich svn und git zu erwäh-nen. git ist ein “version control system (vcs)” wie svn, bzw. ein source controlmanagement System (scm), mit dem entscheidenden Unterschied, dass es imGegensatz zu svn ein verteiltes (distributed) vcs ist.

171

Page 91: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter10

BuildSysteme

Inhalt10.1make.............................9210.2cmake............................92

10.2.1Motivation........................9210.2.2vs.autotools(autotool-hell)..............9310.2.3out-of-source-builds...................9310.2.4Wichtigeoptionenfürcmake..............9310.2.5Beispiel.........................95

10.3rake.............................9610.4gyp..............................97

MakefilesunddasdazugehörigeProgrammmakewerdeninderSoftware-EntwicklungseitjeheralsBuild-Systemeverwendet.Build-SystemebeschreibenjedeneinzlnenSchritteinesBuild-ProzessesundführendieseaufintelligenteArtundWeisesoaus,dassmöglichstwenigeSchritteausreichen,umeinenfunktionierendenbuildzugarantieren.DaBuild-ProzessebeigrößerenProjekteneinigeZeitbeanspruchenkönnen(mehrereStundensindhiernichtausgeschlossen)undesbeimdebuggensehrunpraktischwäre,nachjederÄnderungeinenkomplettenBuild-Prozessabzuwarten,machtmansichandieserStellesowohlEigenschaftenvonCundC++(Object-Files,TrennungvonHeaderundImplementationinunter-schiedlicheDateien,sharedundstaticlibs,…)alsauchdasintelligenteVorgehenvonMakefileszuNutze,umdieentsprechendenWarte-Zeitenabzukürzen.MakefilesbildenstetseinenPfadvonAbhängigkeiten,welcheschrittweiseaufzulösen/abzuarbeitensind,umzumnächstenZielkommenzukönnen.Dabeidienendiesog.targetsalsdieZieleunddieDefinitiondiesertargetsalsdiezuabsolvierendenSchritte(häufig“recipes”genannt).

91

170CHAPTER20.BUGTRACKER

Page 92: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

92 CHAPTER 10. BUILD SYSTEME

Hinzu kommt, dass sich die Bearbeitungszeiten der Dateien nutzen lassen, umfestszustellen, ob – zum Beispiel – ein Object-File neu gebildet werden musss,oder nicht.

10.1 make

make ist, wie bereits erwähnt, der Platzhirsch und der Standard unter den Build-Systemen. Allerdings können Makefiles schnell komplex und unübersichtlichwerden, weshalb man sog. “Makefile-Generatoren”, wie z.B. cmake oder gypverwendet, um sich die entsprechenden Makefiles generieren zu lassen und diesenicht selbst schreiben und verwalten zu müssen.

Bis zu einer gewissen Größe und für eine breite Palette von Aufgaben lassen sichMakefiles ganz hervorragend und gewinnbringend einsetzen – nicht zuletzt, dasie auf so gut wie jedem System vorhanden sind.1

Eine Einführung zu GNU make findet sich unter https://www.gnu.org/software/make/manual/make.pdf; vergleiche u.a. auch das Makefile zumErstellen dieser Dokumentation.

10.2 cmake

cmake2 ist ein Betriebssystem-unabhängiger Makefile-Generator für C- undC++-Projekte. Das heisst, man benutzt cmake, um ein Makefile zu generieren.cmake kann als “Industriestandard” für C- und C++-Projekte betrachtetwerden.

Der Workflow mit cmake funktioniert also folgendermaßen:

cmake DIRmake

Dazu verteilt man (mindestens eine) CMakeLists.txt-Datei (potentiell rekur-siv) im Projekt, welche die Deklarationen zu Targets, Libraries, etc. enthält undteilt cmake durch die Angabe DIR mit, wo sich diese Datei befindet. Danachwird ein Makefile zur Verfügung stehen, welches man mit make aufrufen kann.

10.2.1 Motivation

cmake zu verwenden bringt mehrere Vorteile:1Dieses Skript zum Beispiel wird ebenfalls durch ein Makefile gesteuert: dazu gehören

neben dem Typesetten auch das Hochladen auf den webspace und andere Aufgaben.2http://www.cmake.org/

20.2. WAST-WORKFLOW 169

den referenzierten Bugs dieses automatisch von gitlab eingetragen: ‘this bugwas mentioned in bug XY’. Dies ist ziemlich praktisch.

Page 93: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

10.2.CMAKE93

a)dieSyntaxvoncmakeisteinfacheralsdievon“klassischen”Makefilesb)dadurch,dassdieCMakeLists.txt-Dateienrekursivaufeinanderaufbauen

undjeweilsangeeignetenStellenimProjektuntergebrachtwerden,bleibendiesestetsübersichtlich

10.2.2vs.autotools(autotool-hell)

cmakewirdvorallemdeshalbgerneverwendet,weilder“klassische”autotools-Wegsehrumständlich,fehleranfälligundschlicht“altbacken”seinkann–siehehierzudenAblaufgraph“Autotools”,welcherdenautotools-Wegnachzeichnet.

autotoolsfasstwiederumdenbisdahinverwendetenWegunddiedazubenötigtentoolszusammen,diebenutztwurdenumMakefilesgenerierenzulassen.Denautotools-Wegerkenntmanimmerdaran,dasseineSoftwareden“klasssischenDreischritt”./configure&&make&&makeinstallverwendet.

10.2.3out-of-source-builds

Klassischerweiseverwendetmanbeicmakeinsog.“out-of-sourcebuilds”.Ein-fachgesagt,heisstdiesnur,dassmanseinenBuildnichtdirektindersourcemacht,sonderndafüreineigenesVerzeichnis(meistbuild/)anlegt,undfortanvondortarbeitet.

Damitvermeidetmandas“Vermüllen”dessource-directoriesmitObject-FilesunddergleichenundhältsodieQuellenstetssauber.

DerWorkflowistalso:

~/project/foo>mkdir-pbuild&&cd$_#Hierliegtu.a.src/mitdenQuellenund(mindestens)einerCMakeLists.txt~/project/foo/build>cmake..#`..`istübergeordnetesVerzeichnis!~/project/foo/build>make#build-fileswerdenout-of-sourceangelegt!

10.2.4Wichtigeoptionenfürcmake

DiebeidenwitchtigstenOptionenfürcmakesind:

•-DCMAKE_CXX_COMPILER=/opt/local/bin/g++#VerwendespeziellenCompiler•-DCMAKE_BUILD_TYPE=Debug#Buildtypefestlegen(andereSwitchesfürden

Compiler)

Diesegibtmancmakemit,dasdannentsprechenddieMakefilesgeneriert:

cmake-DCMAKE_CXX_COMPILER=/Users/dbruder/bin/g++-DCMAKE_BUILD_TYPE=Debug..

168CHAPTER20.BUGTRACKER

Figure20.1:BugTrackingWorkflowStatus

Page 94: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

94 CHAPTER 10. BUILD SYSTEME

Figure 10.1: Autotools

20.2. WAST-WORKFLOW 167

Priorität Label Charakterisierung Beschreibung

1 P1 Showstopper. Muss sofort behoben werden.Kritischer Bug.

2 P2 Wichtiger Bug. Sollte ebenfalls schnellstmöglichbehoben werden. Wichtiger Bug.

3 P3 Durchauswichtiger Bug.

Durchaus wichtiger Bug, aber nichtunbedingt wesentlich solange nochP1 und P2 Bugs vorliegen. Könnenauch Feature Requests sein, die dannzumeist zu P4-Bugs werden.

4 P4 Nicht so wichtigerBug.

Meist “Nice To Have” FeatureRequests oder wird häufig vergebenfür “Next Release/Milestone”, d.h.dieses Feature wird wohl erst imnächsten Milestone umgesetztwerden.

Table 20.1: Prioritäten bei Bugs

20.2.3 Workflow

Der Workflow orientiert sich an folgendem Modell: Der Bug geht durch ver-schiedene Phasen, die unterschiedliche Bedeutung haben. Diese werden immerper tag signalisiert. So können andere ablesen, dass jemand an einem bug ar-beitet. Abbildung 20.1 fasst dies zusammen.

20.2.4 Spezialität: Umbrella-Bug

Wenn es mehrere “related” Bugs zu einem größeren Thema gibt, so bietet essich an einen umbrella-Bug zu definieren, der alle diese verstreuten, kleinerenBugs zusammenfasst und miteinander referenziert. Die wird am Einfachsten sogehandhabt, dass:

• der umbrella-Bug bekommt einen tag ‘umbrella’• der umbrella bug bekommt eine Bezeichnung/Beschreibung ‘umbrella bug’• der umbrella bug referenziert die die related-bugs, indem er tags bekommt

mit den bug-id’s der related bugs, also, z.B. ‘#19, #22, #53’. Damit wäreklar, dass der umbrella-bug die bugs mit den Nummern 19, 22 und 53zusammenfasst

Wenn man in der Beschreibung des Umbrella Bugs eine kleine Beschreibunganlegt, die sagt ‘this is an umbrella bug for bugs #19, #22, #53’, so wird in

Page 95: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

10.2.CMAKE95

10.2.5Beispiel

HiereinAuszugausdenCMakeLists.txt-DateiendesProjektssis:

project(sis)cmake_minimum_required(VERSION2.8.3)set(sis_AUTHORS"\"DanielBruder<[email protected]>\"")

set(sis_NAME"\"SIS\"")set(sis_SUBNAME"\"SymmetricIndexStructures\"")set(sis_FULLNAME"\"SIS--SymmetricIndexStructures\"")

#versionnumbers:lassensichgutindoxygenetcverwendenset(sis_VERSION_MAJOR3)set(sis_VERSION_MINOR8)set(sis_VERSION_PATCH0)

set(CMAKE_INSTALL_PREFIX/usr/local)set(FIND_LIBRARY_USE_LIB64_PATHS)

#dieseVariablenkönnenaufderCommandlinemit-Dgesetztwerdenset(sis_BUILD_TESTSON)set(sis_TEST_STATIC_ASSERTIONS0)#0=='OFF'/0=='ON'set(GIT_SUBMODULES_CHECKOUT_QUIETON)

set(CONF_DIR${PROJECT_SOURCE_DIR}/cmake)

include(${CONF_DIR}/config.cmake)include(${CONF_DIR}/compilerdetect.cmake)include(${CONF_DIR}/processorcount.cmake)include(${CONF_DIR}/buildflags.cmake)include(${CONF_DIR}/doxygen.cmake)include(${CONF_DIR}/boost.cmake)include(${CONF_DIR}/ctest.cmake)include(${CONF_DIR}/cpack.cmake)include(${CONF_DIR}/host.cmake)include(${CONF_DIR}/checklocale.cmake)include(${CONF_DIR}/submodules.cmake)include(${CONF_DIR}/githooks.cmake)include(${CONF_DIR}/nodewrap.cmake)

add_subdirectory(src/)add_subdirectory(src/features)add_subdirectory(vendor/)add_subdirectory(web/)

ImVerzeichnissrc/findetsichfolgendescmake-file:

#DieseVerzeichnissemit-IandenCompileralsSuchpfademitgebeninclude_directories(${CMAKE_SOURCE_DIR}/src/)

166CHAPTER20.BUGTRACKER

•Vererbbarkeit:WennsichdieZusammensetzungderTeamsändert,kön-nennachfolgendeEntwicklersichschnellundklareinenÜberblicküberdieausstehendenProblemeundbisherigenLösungenverschaffen.

20.2WAST-Workflow

ImfolgendeneineBeschreibungderKonventionenundVorgänge,wiebugsin-nerhalbvonWASTgehandhabtwerdensollen.

20.2.1Konventionen

Bugssollenordentlichdokumentiertwerdenundgetaggedwerden.Taggenerlaubtes,dieoffenenbugszusortieren,filternunddamitbesserimÜberblickbehaltenzukönnen.Ordentlichdokumentierenbedeutet,dasseinnachfolgendergenaunachvol-lziehenkann,wie/wann/wermiteinemBugumgegangenwurde.Dazugehören:

•taggen:priorisieren(sieheunten,Prioritäten)•taggen:Status(sieheunten,Workflow)•dokumentieren:WennsichderStatuseinesBugsändert,ambesteneinen

KommentarimBug-Verlaufhinterlassen,ambestenso:–Beispiel:[Issued->Analyze].Dieswürdebedeuten,dasssich

PersonFoomitdemBugauseinandersetztunddentagIssuedent-ferntunddurchdentagAnalyzeersetzthat.Diesbedeutetfüralleanderen,dass:*sichbereitsjemandumdenBugkümmert*anderekönnendienochoffenenbugsbequemfilternundsehen,wasalsnächsteszutunist

–Beispiel:[p1->p2].*Bedeutet:PersonFoohatdenBugherunterpriorisiertvonP1nachP2

*Beispiel:[+p1]·Bedeutet:PersonhatP1-tagandenBughinzugefügt

20.2.2Prioritäten

BugssindambestenPriorisiertvon“P1”bis“P4”.DiePrioritätenentsprechenungefährfolgendenIdeen:

Page 96: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

96 CHAPTER 10. BUILD SYSTEME

# Diese Verzeichnisse mit -isystem (oder nach OS abhängig) an den Compiler als Suchpfade mitgeben. -isystem bindet "externe" Header so ein, dass diese keine Warnings werfen.include_directories(SYSTEM

${CMAKE_SOURCE_DIR}/vendor/${CMAKE_SOURCE_DIR}/vendor/cautomata${CMAKE_SOURCE_DIR}/vendor/make_unique${CMAKE_SOURCE_DIR}/vendor/serialization/include

)

# Shared lib bauenadd_library(cppautomataadapter SHARED

adapter/CompressedAutomatonAdapter.cppadapter/SCDAWGAdapter.cppadapter/VoidSequenceAdapter.cpp

)target_link_libraries(cppautomataadapter cautomata)

add_library(cppindexer SHAREDindexer/DocumentIndexingAutomaton.cpp

)target_link_libraries(cppindexer cppautomataadapter cautomata)

add_executable (sis main.cpp)target_link_libraries(sis cppautomataadapter cppindexer cautomata ${Boost_LIBRARIES})

10.3 rake

rake3 ist ein kleines aber feines Build-Tool, das hier als eine Alternative zu makekurz vorgestellt werden soll. rake ist und wird in Ruby geschrieben und ist aufden meisten Systemen, die ruby mitliefern, enthalten.

rake ist aber nur eine von sehr vielen Alternativen zu make! Es gibt vieleweitere, ähnliche Tools, doch nur eines, nämlich make kann als echter “Standard”angesehen werden. Nicht zuletzt aber lohnt sich ein Blick auf make: unterUmständen lässt sich make durch diesen kleinen Umweg schneller und einfacherverstehen…

Rake ist – im Gegensatz zu cmake – aber kein Makefile-Generator und kannfolglich (leider) keine makefiles generieren!

3http://rake.rubyforge.org/

Chapter 20

Bug tracker

Inhalt20.1Motivation . . . . . . . . . . . . . . . . . . . . . . . . . 16520.2WAST-Workflow . . . . . . . . . . . . . . . . . . . . . . 166

20.2.1 Konventionen . . . . . . . . . . . . . . . . . . . . . . 16620.2.2 Prioritäten . . . . . . . . . . . . . . . . . . . . . . . . 16620.2.3 Workflow . . . . . . . . . . . . . . . . . . . . . . . . 16720.2.4 Spezialität: Umbrella-Bug . . . . . . . . . . . . . . . 167

20.1 Motivation

Der Bug-Tracker dient der gemeinsamen Verwaltung von Bugs und der Version-ierungObwohl eigentlich einleuchtend und selbstverständlich haben “ordentliche” Bug-Tracking best practices eine Reihe entscheidender Vorteile:

• Transparenz: Alle Mitarbeiter haben einen genauen Überblick über denStand des Projekts / der einzelnen Komponenten

• Milestones und wesentliche Entwicklungsschritte über Komponenten hin-weg können besser erreicht werden, das gesamte Projekt sich schneller en-twickeln

• Genauigkeit: Durch die Transparenz und das Wegfallen von“Flüsterpost-Ketten” ist es wesentlich einfacher sich gemeinsam zukoordinieren

• Genaue Rückgabe: Es ist zu jedem Zeitpunkt klar, was man denPhilsophen gegenüber geliefert hat / was noch aussteht / wer geradeworan arbeitet.

165

Page 97: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

10.4.GYP97

10.4gyp

gyp(GenerateYourProjects)4isteinMakefile-Generator,dervonGooglefürdenBuild-ProzessvonChromeentwickeltwurde.ErwirddesweiterenauchfürdenbuildvonNode.jsverwendet(wasanandererStellewichtigwird–hierwerdenwirgypwiederbegegnen).gypistalsoeinbuild-automationtoolähnlichzucmake,gegenübercmakeaberwerdendieTargetsingyp-filesalsJSON-Strukturbeschrieben–hiereinBeispielfüreingyp-file:

1{2'targets':[3{4'target_name':'foo',5'type':'executable',6'msvs_guid':'5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65',7'dependencies':[8'xyzzy',9'../bar/bar.gyp:bar',

10],11'defines':[12'DEFINE_FOO',13'DEFINE_A_VALUE=value',14],15'include_dirs':[16'..',17],18'sources':[19'file1.cc',20'file2.cc',21],22'conditions':[23['OS=="linux"',{24'defines':[25'LINUX_DEFINE',26],27'include_dirs':[28'include/linux',29],30}],31['OS=="win"',{32'defines':[33'WINDOWS_SPECIFIC_DEFINE',34],35},{#OS!="win",36'defines':[37'NON_WINDOWS_DEFINE',38],

4https://code.google.com/p/gyp/wiki/GypUserDocumentation

164CHAPTER19.TESTDRIVENDEVELOPMENT

Page 98: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

98 CHAPTER 10. BUILD SYSTEME

39 }]40 ],41 },42 ],43 }

19.2. ARTEN VON TESTS 163

wurde, sind diese einzelnen Klassen bereits durch die Unit-Tests in sich getestet.Der Integration Test nun testet diese einzelnen Kompomeneten in ihrem Zusam-menhang, ihrer Kooperation etc. Diese Art von Tests wird aber zumeist eherab einer umfangreicheren Größe des Projekts benötigt.

19.2.3 Sanity Tests

Neben Unit- und Integration-Tests gibt es auch noch die sog. Sanity-Tests.Diese Art von Tests validiert und prüft User-Eingaben, Datentypen und ähn-liches auf korrekte Werte.

19.2.4 E2E Tests

E2E-Tests, bzw. End-to-end-tests sind sehr ähnlich zu Integration Tests, indemsie das Zusammenspiel der einzelnen Komponenten prüfen, haben aber eher einkonkretes Interaktions-Szenario des Benutzers im Blick: oft werden e2e Testsin Web-Frameworks und in der Entwicklung von Webseiten verwendet, um einkomplettes “Szenario” der Benutzer-Interaktion durchzuspielen und zu prüfen,ob dieses von Anfang bis Ende fehlerlos ablaufen kann.

Beispiel:

• User geht auf Seite• User sucht etwas• User klickt ein Ergebnis an• User wird auf Seite des Ergebnisses geleitet• User will dort eine Eingabe machen• User muss angemeldet sein• User meldet sich an• User is angemeldet• User kann Eingabe machen• User kann Eingabe speichern• …

Page 99: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter11

Web

Inhalt11.1Web-Applikationen....................99

11.1.1SchematischeDarstellung...............10011.1.2UnterschiedlicheKombinationsmöglichkeiten.....101

11.2MEAN-Stack........................10211.2.1Vorteile.........................10311.2.2Node...........................10411.2.3Angular.........................10411.2.4Express.........................10411.2.5MongoDB........................104

11.3Jade.............................10511.3.1Bootstrap........................10511.3.2BootstrapUI......................10511.3.3jQuery..........................105

IndiesemKapitelwerdendiewesentlichenZügevonWeb-Applikationenvorgestellt(dazuzählenClient-Server-KonfigurationenundKommunikation),undamBeispieldes[MEAN-Stack][DerMEAN-Stack]einkonkretes,sehrmodernesFrameworkzumErstellenvonSPAs(SinglePageApplications),bzw.RichClientWebApplicationsvorgestellt.WesentlichbeidiesenistdasdynamischeLadenvonSeiten-Bestandteilen,stattdemkomplettenReloaddergesamtenSeite.

11.1Web-Applikationen

ModerneWeb-ApplikationenfunktionierenimAllgemeinennachwenigen,wesentlichenPrinzipien.InwelcherArtundWeisediesekonkretausgestaltetwerden,isteineandereFrage–dieBasicsjedochbleibendieselben.

99

162CHAPTER19.TESTDRIVENDEVELOPMENT

classstringAppendFeature{EXPECT(

stringAppendFixture::teststring1_append_in.append('c')==stringAppendFixture::teststring1_append_out

);

//hiergibtesschondenzweitenTestfall!EXPECT(

stringAppendFixture::teststring2_append_in.append('c')==stringAppendFixture::teststring2_append_out

);//weiteretestsderSpezifikation...

};

ErfülltderTestdieSpezifikation?WaswäredennnunmitdemFall,dassderStringauf\nendet?Solldercharchinterdem\nangefügtwerden,dasnewlinemöglicherweisekomplettersetzen,odersichwomöglichvordasnewlineeinsetzen?EinTestwirdKlärungbringen,und,enpassantdieSpezifikationderKlassestringfestigen!SeidieSpezifikationnunerweitertumfolgendeRegel(n):

1.esgibteineKlassestring2.string::append(charc)solleinenBuchstabenandenbestehenden

Stringanfügen3.wennderstringleerist,sollderneuestringausdemangefügtenBuch-

stabenbestehen(imPrinzipnureinSpezialfallvon2.)4.wennderStringaufeinnewlineendet,solldercharactervordemnewline

einfügtwerdenunddasnewlineanletzterStellebehaltenwerden

DieTestskönntennunerneutrefactoredwerdenundfolgendesergeben:

classstringAppendFixture{std::map<string/*input*/,string/*output*/>fixture{{"foobar","foobarc"},{"","c"},{"foobar\n","foobarc\n"},

};};

classstringAppendFeature{conststringAppendFixtureF;

for(constauto&f:F.fixture){EXPECT(f.first==f.second);

}};

19.2.2IntegrationTests

IntegrationTeststestenindenmeistenFällendasZusammenspielvoneinzel-nenKlassenoderSoftware-Komponenten.WieimvorherigenAbschnittgezeigt

Page 100: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

100 CHAPTER 11. WEB

11.1.1 Schematische Darstellung

Figure 11.1: Web Apps Basics

11.1.1.1 Ablauf der Aktionen

• Anfrage (1) vom Client (B) an den Server (A)• Anfrage (2) des Servers (A) an die Datenbank (C)• …

11.1.1.2 Aktionsarten

Die genannten Aktionen können unterschiedlicher Art sein:

Anfrage (1) kann – nach dem HTTP-Protokoll unterschiedliche Methoden haben:

• GET• POST• PUT• UPDATE• DELETE

19.2. ARTEN VON TESTS 161

19.2.1.1 Features/Fixtures

Angenommen, es gibt eine Klasse string, und diese Klasse soll eine Methodeappend(char c) besitzen, welche einen Buchstaben an den String anhängt.

Die Spezifikation sagt also:

• es gibt eine Klasse string• string::append(char c) soll einen Buchstaben an den bestehenden

String anfügen

Die Fixture enthält vorgegebene Eingaben und die erwarteten Aus-gaben/Rückgabewerte. Die stringAppendFixture wird genau dieses verhaltenabbilden:

In einer schematischen Darstellung:

class stringAppendFixture {string teststring1_append_in = "foobar";string teststring1_append_out = "foobarc";

};

Jede Fixture ist einem Feature zugeordnet. Das Feature ist ein kleiner Testfall,der die Funktionen der getesteten Klasse verwendet, die Eingaben der Fixturean diese füttert und die Rückgaben anhand der Fixture überprüft.

Die Klasse stringFeature wird also die Spezifikation von string::appendprüfen (erneut in schematischer Darstellung):

class stringAppendFeature {EXPECT(

stringAppendFixture::teststring1_append_in.append('c')== stringAppendFixture::teststring1_append_out

);// weitere tests der Spezifikation...

};

Diese Sorte von kleinen Tests zu schreiben ist sehr einfach und dabei aberhochgradig effektiv!

Bald nämlich wird einem auffallen, dass es sinnvoll wäre, zu testen, was passiert,wenn der string vorher leer ist:

class stringAppendFixture {string teststring1_append_in = "foobar";string teststring1_append_out = "foobarc";string teststring2_append_in = "";string teststring2_append_out = "c";

};

Page 101: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

11.1.WEB-APPLIKATIONEN101

DieAnfragenvomTyp(1)vomClient(B)andenServer(A)richtensichimmernacheinerbestimmtenRouten.

DerServerbestimmt,wieseineAPIgestaltetist,undreagiertentsprechendaufAnfragenanbestimmteRouten.

Anfragenkönnensein:

DerServer(A)kannaufAnfrage(1)imSchritt(4)mitunterschiedlichenTypenvonRessourcenantworten(selbstverständlichwird(B)diesen“richtig”anfragen,bzw.genaudieseErgebnisseerwarten):

•GET-AnfragenacheinerstatischenHTML-SeiteaufeinembestimmtenPfad,serverkanndiesedirektausliefern

•GET-AnfragenacheinerRessource(möglicherweisevoneinerDatenbank,oderausanderenQuellen),serverkannJSONliefern

•POSTaufeinebestimmteRoute:ServersolldieimPOSTgesendetenDatenirgendwohinpacken

DERHTTP-StandardunterstützttheoretischnochmehrAnfrage-Methoden,allerdingssinddiesedefactoaberkaumbisgarnichtumgesetzt(dienichtumgesetztenMethodenlassensichgutGETundPOSTemulieren)

DieSchritte(3)und(4)sindoptional.DerTypderDatenbankistauchnichtfestgelegtundesgibtimwesentlichen2TypenvonDatenbanken:

•Relationale(SQL-Datenbanken)•Nicht-Relationale(NOSQL-Datenbanken),Dokumentorientert,meist

eigentlichsehrJSON-artig

InSchritt(5)sendetderServerseineAntwortaufAnfrage(1),diesekann,wiegesehen,eineHTML-Seitesein,JSON,oderetwasanderes.AndiesemPunktistesAufgabedesClient,dieseAntwortentsprechendzuverarbeiten.

11.1.2UnterschiedlicheKombinationsmöglichkeiten

HiereinekleineListe,wasanwelchenStellenmöglicherweisevorkommenkönnte–dieseListeistbeiweitemnichtexhaustiv!

11.1.2.1Server

AlsServerkönnenunterschiedlicheSoftware-KomponenteninBetrachtkommen.EinServerliefertimwesentlichenDatenaus(er“serve-d”):

•Apache

160CHAPTER19.TESTDRIVENDEVELOPMENT

TestDrivenDevelopmentgehtdabeieinenzunächstungewöhnlicherscheinendenWeg:eswerdenzuerstdie(failenden)Testsgeschrieben,unddanacherstdiedazupassendeImplementation(alsodieImplementation,diedenTest“pass”-enlässt).

DerWorkflowimTDDistalsokurzgesagtfolgender:

1.Testschreibendernichtklappenwird2.PassendeImplementationschreiben,diedenTestklappenlässt3.Abhier:wiederbei1)beginnen

InteressanterweiseerlaubtTDDzumeisteineschnellereEntwicklungimProjekt,einelangfristiggesehenstabilere,ausgereiftereundnachhaltigereCode-BaseundmachtdabeiauchnochSpaß.

Obwohleszunächstparadoxerscheinenmag,sogibteszwareinenklarenMehraufwand,zuerstdieTestsunddanachdieImplementationzuschreiben,durchdasvorherigeschreibenderTestsaber

•wirddieSpezifikationnocheinmalgenauerüberdacht,•liegtdieSpezifikationauchinkonkreterFormvor:spätereEntwickler

sehenTeiledesCodes“live”inderVerwendung•liegendieTest-Fällebereitsvor•machtmansichbereitsimplizitGedankenüberdiespätereAPIundVer-

wendungder(nochzuschreibendenKlasse)•Könnenedge-caseswesentlichbessererkanntunddaherauchgetestetwer-

den

19.2ArtenvonTests

Zumeistsinddiesog.Unit-Testsdiewichtigsten,beieinemgrößerenProjektwiediesemjedochistesdenkbar,volleIntegrationTests,Sanity-Tests,etc.paratzuhaben.

19.2.1Unit-Tests

EinUnit-TestbildetklassischerweisedieFunktionalitäteinerKlasseineinerIsoliertenArtundWeiseab.

IdealerweisebildetderUnit-TestzueinerKlassezugleichauchihreSpezifikationabundprüftdieseanhandderFixturesdurch.

Page 102: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

102 CHAPTER 11. WEB

• IIS• nginx• lighttpd• unicorn• Node• …

11.1.2.2 Client

• Browser: Firefox, Chrome, Chromium, Safari, IE, …• curl, wget, …

11.1.2.3 Datenbank

Wie bereits erwähnt gibt es unterschiedliche Typen von Datenbanken und imwesentlichen SQL-orientierte und NO-SQL-orientierte:

• SQL-orientierte Datenbanken

– MySQL– PostgreSQL

• NoSQL-orientierte DB:

– MongoDB– CouchDB– Redis

• Graph-orientierte Datenbanken:

– Neo4j– viele andere…

11.2 MEAN-Stack

Der MEAN-Stack ist ein Framework für die Entwicklung von modernen Web-seiten – ähnlich wie das bekanntere “Ruby on Rails”. Diese neue Generation vonWebseiten ist auch als “SPA” (Single Page Web-Applications) oder “Rich ClientWeb Applications” bekannt und unterscheidet sich von “herkömmlichen” Web-seiten dadurch, dass stets nur einzelne Teilbereiche einer Webseite neu geladenwerden anstatt durch eine Reihe von Seiten “vorwärts und rückwärts” zu gehenund diese jeweils komplett zu laden. Rich Client Web Applications fühlen sichwesentlich “applikationshafter” an als “herkömmliche” Webseiten und zeichnensich nicht zuletzt dadurch aus, dass mehr Arbeit, die klassicherweise auf dem

Chapter 19

Test Driven Development

Inhalt19.1Motivation und Vorteile . . . . . . . . . . . . . . . . . 15919.2Arten von Tests . . . . . . . . . . . . . . . . . . . . . . 160

19.2.1 Unit-Tests . . . . . . . . . . . . . . . . . . . . . . . . 16019.2.2 Integration Tests . . . . . . . . . . . . . . . . . . . . 16219.2.3 Sanity Tests . . . . . . . . . . . . . . . . . . . . . . . 16319.2.4 E2E Tests . . . . . . . . . . . . . . . . . . . . . . . . 163

19.1 Motivation und Vorteile

Die Vorteile von Test-geleiteter Entwicklung sind mannigfaltig. Unter anderemerlaubt eine Test-Suite folgendes:

• Es ist einfach nach der Kompilierung einen sogenannten “Sanity-Test” zumachen, um zu überprüfen, ob alle Teile auf dem target-host genau sofunktionieren wie sie es auf der Entwicklungsmaschine getan haben undalle Teile richtig kompiliert wurden und verfügbar sind

• Es ist einfach, später neue Funktionalitäten einzubauen, da stets dasSicherheitsnetz besteht, zu sehen, ob die Veränderung am Code möglicher-weise an anderer Stelle einen Fehler auslöst

• Es ist wesentlich einfacher, sein eigenes Programm zu debuggen, und manbenötigt wesentlich weniger sog. “printf-debugging”, da die (vielen kleinen)tests mögliche Fehler sehr gut lokalisieren und eingrenzen. In den meistenFällen wird durch gute (d.h. viele kleine) Tests die Ursache des Problemssehr schnell ersichtlich und es wird einem mühsames “dem Code hinter-hersteigen” erspart.

159

Page 103: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

11.2.MEAN-STACK103

ServergemachtwurdeaufdenClient–alsodenBrowserdesBeutzersausge-lagertwird.GenaugenommenistderMEAN-StacknichteinFramework,sonderndieKom-binationmehrerer,kleinererFrameworks,SchichtenundModulezueinemsoge-nanntenstack.

11.2.1Vorteile

EntscheidenderVorteildesMEAN-StacksgegenüberRubyonRailssindu.a.folgende

•mankanndurchalleTeilehinwegstetsnurinJavascriptbleiben•dieWebseitensindwesentlichperformanterunddieLoadaufdemServer

bleibtwesentlichgeringer•dieSub-Komponenten(diegleichbesprochenwerden)sindjeweilsgegen

andereaustauschbar:indiesemSinnehandeltessichumeinenStack:mankannfürdiejeweiligenAufgabendurchausauchandereModulezumEinsatzbringen

•esgibtwenigerKonventionenundeinenfreierenAufbau(dieskannsowohleinVor-alsaucheinNachteilsein)

HierbeistehendieInitialenfürfolgendeTeile,welche–ganzgrobumrissen–,folgendeAufgabenübernehmen:

•MongoDB1–Datenbank•Express2–FrameworkaufbauendaufNode,fürdieServer-Seite•Angular3–fürdieClient-Seite•Node4–derWebserver(ähnlichwie,aberstattApache,nginx,unicorn,

…)

WieobenangedeutetließensichdieeinzelnenKomponentendesStackauchdurchandereKomponentenaustauschen–dazuimfolgendeneinekleineAufzäh-lung,welcheAlternativen(untervielenvielenmehr)potentiellbestehenkönnten–hierbeiwerdenvielleichtauchdieAufgabendereinzelnenKomponentendeut-licher:

•MongoDB:mysql,postgresql,redis,couchDB,…•Express:koa,puresNode,…•Angular:jQuery+php,ember.js,sails.js,…•Node:Apache,nginx,unicorn,foreman,…

1MongoDB(2014)2expressjs(2014)3Google(2014)4node(2014)

Page 104: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

104 CHAPTER 11. WEB

11.2.2 Node

Node5 wird verwendet um einen eigenen Webserver selbst zu schreiben. Node istein unglaublich schneller Webserver und ein funktionsfähiger eigener Webserverlässt sich in Node bereits mit wenigen Zeilen schreiben.

Da am Ende Webseiten über eine normale WWW-Adresse ausgeliefert werdensollen und meistens ein Apache auf dem Server bereits läuft und auf dem HTTP-Port 80 “listened”, kann dieser Port nicht erneut belegt werden. Node machtdaher seinen eigenen Port auf, z.B. 6688, was aber wiederum bedeuten würde,dass der user die seite auf diesem Port ansteuern müsste, z.B. webseite.com:6688.

Für diesen Fall wird zumeist ein sog. “Reverse Proxy” im Apache eingerichtet,der alle unterschiedlichen Services und Webserver die möglicherweise sonst nochauf dem Server laufen zusammenfasst und eine einheitliche Oberfläche nachaußen bietet (d.h. keine expliziten Port-Angaben vom User verlangt, die ihnohnehin nur verwirren würden). Bei einem Reverse-Proxy wird Apache mit-geteilt bestimmte Pfade auf bestimmte Ports einfach weiterzuleiten und nichtselbst zu bearbeiten.

11.2.3 Angular

Angular erlaubt es, vieles an Logik bereits in der View zu lösen, d.h. an derStelle, an der es in einem MVC-Pattern6 häufig gebraucht wird. (Der andere,gegenteilige Ansatz nennt sich “Fat Controller”).

Angular erlaubt das ganz hervorragende “double data-binding”, welches mansich lieber live in einem Beispiel anschaut um es zu verstehen. Damit erlaubtes Angular unglaublich schnell schöne Web-Applikationen zu entwickeln.

11.2.4 Express

Express ist ein Mini-Framework, das auf Node aufbaut, und es deutlich einfachermacht, einen Server mit Routes, Middleware, etc auf die Beine zu stellen. Dabeiarbeitet es sehr eng mit dem Node-Webserver zusammen.

11.2.5 MongoDB

MongoDB (von “humounguous”, riesig) ist eine sogenannte “NoSQL”-, bzw.Dokumentenorientierte Datenbank.

Dabei speichert es im Gegensatz zu SQL-artigen Datenbanken JSON-Objekte(“Dokumente”) anstatt von Tabellen und ist wesentlich einfacher zu bedienen.

5node (2014)6vergleiche hierzu auch das Kapitel MVC im Abschnitt Design Patterns

Part VIII

Best Practices

157

Page 105: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

11.3.JADE105

AuchpasstessichbesseransichschnellundhäufigwechselndeDatenbank-SchemataanundistdadurchwesentlichflexibleralseineSQL-BasierteDaten-bank.

11.3Jade

11.3.1Bootstrap

11.3.2BootstrapUI

11.3.3jQuery

156CHAPTER18.DESIGNPATTERNS

Page 106: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

106 CHAPTER 11. WEB

Chapter 18

Design Patterns

Inhalt18.1MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15518.2MVVM . . . . . . . . . . . . . . . . . . . . . . . . . . . 15518.3MV* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15518.4 (Teile aus SIS) . . . . . . . . . . . . . . . . . . . . . . . 155

18.1 MVC

18.2 MVVM

18.3 MV*

18.4 (Teile aus SIS)

155

Page 107: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter12

XML

Inhalt12.1TEI..............................10712.2XPath............................107

12.1TEI

12.2XPath

107

154CHAPTER17.NODEWRAPPING

Page 108: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

108 CHAPTER 12. XML 17.4. DEMONSTRATION 153

37 '-Wall',38 '-Wextra',39 '-Wno-attributes',40 '-Wno-pointer-arith'41 ]42 }43 ]44 ]45 }

Hiermit ist es also möglich, wie oben gezeigt, die C++-Klasse WL von Javascriptaus anzusprechen:

1 var addon = require('./build/Release/WLNodeWrap');2

3 var wl = new addon.WLNodeWrap();4

5 wl.add('foo');6 wl.add('bar');7 wl.add('baz');8

9 var size = wl.size();10 console.log( size ); // 3

Page 109: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter13

Dokumentation

Inhalt13.1pipelinemitgpp,ppp&pandoc............109

13.1.1HinweisezurInstallationderdependencies......11113.1.2HinweisezurBenutzungdesMakefiles........111

13.1pipelinemitgpp,ppp&pandoc

DiesesDokumentwurdeerstelltmiteinerelaboriertenpipeline,diemehrereToolsumfasst.Dabeiwirdvonpandoc1derwesentlicheTeilübernommen,unddiesesvongpp2,dem“generalpreprocessor”undppp3,dem“pandocpreprocessor”begleitet.MitpandoclassensicheinebreiteVielfaltvonDokumenteninMarkdowner-stellenundinverschiedeneFormateexportieren,wiez.B.:

•LATEX

•HTML•ebooks•Präsentationen•u.v.w.m.

UmdiesesDokumentvollsetzenzukönnensindmindestensnotwendig:1http://johnmacfarlane.net/pandoc/2http://en.nothingisreal.com/wiki/GPP3https://github.com/typesetters/p5-App-pandoc-preprocessbzw.https://metacpan.org/

release/App-pandoc-preprocess

109

152CHAPTER17.NODEWRAPPING

17.4.3Schritt3:binding.gyp,diebuild-Dateifürnode-gypschreiben

NichtzuletztmussnocheineDateibinding.gypangelegtwerden,welche–ganzwieeinMakefile–,diebuild-Dateifürnode-gypdarstellt.node-gypisteinspeziellesbuild-Tool(vergleicheBuildSysteme)für“node-addons”undkümmertsichumdasnotwendigelinkingzudenbenötigtennode-undv8-libraries.ZumvorhandenenProjektsiehtdiebinding.gypfolgendermaßenaus(esgehtindieserbinding.gypv.a.auchdarum,C++11transparent,überverschiedeneBetriebssystemehinwegverwendenzukönnen):

1{2"targets":[3{4"target_name":"WLNodeWrap",5"sources":["addon.cpp","WLNodeWrap.cpp"]6}7],8#globalflagsgohere9#`cflags_cc!`issupposedtomean:removetheseflags

10#`cflags_cc`issupposedtomean:addtheseflags11'conditions':[12[13'OS=="mac"',{14'xcode_settings':{15'GCC_ENABLE_CPP_RTTI':'YES',16'GCC_ENABLE_CPP_EXCEPTIONS':'YES',17'CLANG_CXX_LANGUAGE_STANDARD':'c++11',18'MACOSX_DEPLOYMENT_TARGET':'10.7',19'OTHER_CFLAGS':[20'-fPIC',21'-Wall',22'-Wextra',23'-Wno-attributes',24'-Wno-pointer-arith'25]26}27}28],29[30'OS=="linux"',{31'cflags_cc!':['-fno-rtti'],32'cflags_cc':[33'-frtti',34'-fPIC',35'-fexceptions',36'-std=c++11',

Page 110: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

110 CHAPTER 13. DOKUMENTATION

• pandoc4

• gpp5

• ppp6

– dot7

– neato8

– rdfdot9

– ditaa10

– Image::Magick11

– rsvg-convert12

– yuml13. (als python-modul installieren mit pip installhttps://github.com/wandernauta/yuml/zipball/master odereasy_install https://github.com/wandernauta/yuml/zipball/master)

– plantuml14

• TeXLive / MikTex / MacTex15

Empfohlen werden dazu noch für das Bibliographieren:

• zotero• chrome zotero plugin• zotero plugin auto export bibtex

Desweiteren sei hingewiesen auf das von David Kaumanns mit Stefan Schweterentwickelte Template zur Gestaltung von Bachelor- und Hausarbeiten, welchesauf dieser pipeline aufbaut:

• BA Thesis Template16

Der Workflow eines vollen Typeset gestaltet sich folgendermaßen:

• Vorverarbeitung mit gpp: Datei-includes, Teile Ein- und Ausblenden jenach #defines

4http://johnmacfarlane.net/pandoc/5http://en.nothingisreal.com/wiki/GPP6https://github.com/typesetters/p5-App-pandoc-preprocess bzw. https://metacpan.org/

release/App-pandoc-preprocess7http://www.graphviz.org/Documentation.php8http://www.graphviz.org/pdf/neatoguide.pdf9https://metacpan.org/release/RDF-Trine-Exporter-GraphViz

10http://ditaa.sourceforge.net/11http://www.imagemagick.org/12http://live.gnome.org/LibRsvg13https://github.com/wandernauta/yuml14http://plantuml.sourceforge.net/15http://www.dante.de/tex/TeXDistro.html16https://gitlab.cis.uni-muenchen.de/David/stub-template-bathesis

17.4. DEMONSTRATION 151

53 std::string str{ *ustring };54

55 // Unwrap WL to `This'56 WLNodeWrap* This = node::ObjectWrap::Unwrap<WLNodeWrap>(args.This());57

58 // Talk to WL's member `wl_'59 This->wl_.add(str);60

61 return scope.Close(Undefined());62 }63

64 Handle<Value> WLNodeWrap::Size(const v8::Arguments& args) {65 HandleScope scope;66

67 // Unwrap WL to `This'68 WLNodeWrap* This = node::ObjectWrap::Unwrap<WLNodeWrap>(args.This());69

70 // Return WL::wl_'s return value to Javascript (as a number)71 return scope.Close( Number::New( This->wl_.size() ) );72 }

17.4.2.1 Besprechung des Codes

• Zeilen 1–17: Diese Zeilen sind direkt aus der node-Dokumentation

• Zeilen 18–23: An dieser Stelle wird das Mapping vorgenommen, welchesbesagt, dass auf Javascript-Seite eine Methode add vorhanden sein wird,welche auf WLNodeWrap::Add zeigt. Dort wiederum wird dann auf daseigentliche add(), nämlich WL.add() weitergeleitet werden. (Das selbegilt für size() [JS-Seite] -> WLNodeWrap::Add [JS-V8-C++-BridgeEbene] -> WL::size() [echte C++-Ebene])

• Die Zeilen 54–57 zeigen die Verbindung aus der node::ObjectWrap/JS-V8-C++-Bridge-Ebene zur “echten” C++-Ebene und methode:

– zunächst wird das “eigentliche” Objekt auf node-Seite “aus-gepackt” (Zeile 54) und dessen member wl_, die “eigentliche”C++-Klasse angesprochen, und auf dieser nun die Methodeadd(const std::string&) aufgerufen.

• Jede Methode auf der V8-Ebene muss seinen Scope schließen und diesesals Rückgabewert zurückliefern. Zeile 59 zeigt, wie man ein “void” zurück-geben kann.

• Die Zeilen 66–69 zeigen erneut, wie sich size()/Size()/size() vonJavascript bis in die C++-Ebene verknüpfen lassen.

• Die Zeilen 48–51 führen den “klassischen Dreisatz” vor, wie Strings vonJavascript bis in C++-Strings umgewandelt werden.

Page 111: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

13.1.PIPELINEMITGPP,PPP&PANDOC111

•Vorverarbeitungmitppp:alle“code”-TeiledieGraphikenbeschreibenzuGraphikenrendern

•Zentrale:pandoc:ExportinverschiedeneFormate:pdf,html,tex,ebook,etc.

Figure13.1:DerTypesettingProcess

EinegenauereBeschreibungundAnleitungfindetsichinppp-Documentation.pdfimRepositoryvonppp17.

13.1.1HinweisezurInstallationderdependencies

FürHinweisezurInstallationderdependenciesbezüglichderRechneramCIP-Pool,vergleichedieREADME.mdinBAThesisTemplate18.

13.1.2HinweisezurBenutzungdesMakefiles

FürHinweisezurBenutzungdesMakefiles,vergleicheebenfallsdieREADME.mdinBAThesisTemplate19.

17https://github.com/typesetters/p5-App-pandoc-preprocess18https://gitlab.cis.uni-muenchen.de/David/stub-template-bathesis19https://gitlab.cis.uni-muenchen.de/David/stub-template-bathesis

150CHAPTER17.NODEWRAPPING

3#endif4

5#include<node.h>6#include"WLNodeWrap.hpp"7

8usingnamespacev8;9

10Persistent<Function>WLNodeWrap::constructor;11

12voidWLNodeWrap::Init(Handle<Object>exports){13

14//Prepareconstructortemplate15Local<FunctionTemplate>tpl=FunctionTemplate::New(New);16tpl->SetClassName(String::NewSymbol("WLNodeWrap"));17tpl->InstanceTemplate()->SetInternalFieldCount(1);18

19//Prototype20tpl->PrototypeTemplate()->Set(String::NewSymbol("add"),21FunctionTemplate::New(Add)->GetFunction()22);23tpl->PrototypeTemplate()->Set(String::NewSymbol("size"),24FunctionTemplate::New(Size)->GetFunction()25);26

27constructor=Persistent<Function>::New(tpl->GetFunction());28exports->Set(String::NewSymbol("WLNodeWrap"),constructor);29}30

31Handle<Value>WLNodeWrap::New(constArguments&args){32HandleScopescope;33

34if(args.IsConstructCall()){35//Invokedasconstructor:`newWLNodeWrap(...)`36WLNodeWrap*obj=newWLNodeWrap();37obj->Wrap(args.This());38returnargs.This();39}else{40//Invokedasplainfunction`WLNodeWrap(...)`,turnintoconstructcall.41constintargc=1;42Local<Value>argv[argc]={args[0]};43returnscope.Close(constructor->NewInstance(argc,argv));44}45}46

47Handle<Value>WLNodeWrap::Add(constv8::Arguments&args){48HandleScopescope;49

50//Standardunpackingofstrings51Local<String>String=args[0]->ToString();52String::Utf8Valueustring{String};

Page 112: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

112 CHAPTER 13. DOKUMENTATION 17.4. DEMONSTRATION 149

17.4.2 Schritt 2: Wrapper-Klasse WLNodeWrap, die vonnode::ObjectWrap erbt, schreiben

Die Wrapper-Klasse WLNodeWrap wiederum orientiert sich sehr stark an der o.g.node-Dokumentation.

Im wesentlichen erbt sie von node::ObjectWrap und exportiert eine static-Methode Init. (Diese static Methode ruft der vorherige Schritt auf:NODE_MODULE -> WLNodeWrap -> InitAll -> WLNodeWrap::Init!)

Desweiteren wird die eigentliche, zu wrappende Klasse WL<std::string> derKlasse WLNodeWrap als Member hinzugefügt.

1 #ifndef NODEWRAP_HPP_SBNDJF7E2 #define NODEWRAP_HPP_SBNDJF7E3

4 #include <node.h>5 #include <string>6 #include "WL.hpp"7

8 class WLNodeWrap : public node::ObjectWrap {9 typedef WL<std::string> wrapped_wl;

10

11 public:12 static void Init(v8::Handle<v8::Object> exports);13

14 private:15 explicit WLNodeWrap() = default;16 virtual ~WLNodeWrap() = default;17

18 static v8::Handle<v8::Value> New(const v8::Arguments& args);19

20 // Add wird nach WL.add(const std::string&) gemapped werden21 static v8::Handle<v8::Value> Add(const v8::Arguments& args);22 // Size wird nach WL.size() gemapped werden23 static v8::Handle<v8::Value> Size(const v8::Arguments& args);24 static v8::Persistent<v8::Function> constructor;25

26 wrapped_wl wl_;27 };28

29 #endif /* end of include guard: NODEWRAP_HPP_SBNDJF7E */

Selbstverständlich gibt es eine passende Datei WLNodeWrap.cpp, welche dieseDeklarationen des Header definiert, auch hier kann man sich wieder sehr eng andie node-Dokumentation halten:

1 #ifndef BUILDING_NODE_EXTENSION2 #define BUILDING_NODE_EXTENSION

Page 113: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter14

UnifiedDeployment

Inhalt14.1wast-infrastructure....................113

14.1.1BündelungderKomponentenuntereinemDach...11414.1.2Abstraktiondesdeployment-Prozesses........115

14.2userwastd..........................116

14.1wast-infrastructure

DurchdenunifieddeploymentprocessinWASTwerdenalleKomponenten(un-abhängigvonihremAufbau,ihrenverwendetenModulen,backends,frontends,…)abstrahiertuntereinemDachzusammengefassst,undmitnureinemBefehlverwaltet,administriert,unddeployed.

DiesesVorgehenhatdenentscheidendenVorteil,dassspätereGenerationenalleKomponenteningewohnterWeisebilden,kompilierenunddeployenkönnen–ohnesichspeziellmitdemeinzelnenModulimDetailauskennenzumüssen–und,letztendlich,dabeieinzelneBefehleinderrichigenReihenfolgemitdenrichtigenArgumentenaufdiesenaufrufenzumüssen.

DerunifieddeploymentprocesswirdnachundnachimmerstärkereingesetztwerdenumdiegesamteTool-undKomponenten-LandschaftvonWASTzuver-walten,d.h.–unteranderem–,Gesamt-Releasesanzulegen(nachdemSeman-ticVersioning-Schema),denDevelopmentunddenMaster-Branchzuverwal-ten(siehe[gitbranchingmodel][]),einzelneKomponentenupzudaten,neuean-notierteDatenausBergenmiteinemBefehlinalleSuchmaschinenzuverteilenunddergleichen.

113

148CHAPTER17.NODEWRAPPING

maßeninnerhalbvonJavascriptverwendetwerdenkann:

1varaddon=require('./build/Release/WLNodeWrap');2

3varwl=newaddon.WLNodeWrap();4

5wl.add('foo');6wl.add('bar');7wl.add('baz');8

9varsize=wl.size();10console.log(size);//3

UmdieseszuerreichensindfolgendeSchrittenötig:

1.Einsteigsdateiaddon.cppschreiben2.Wrapper-KlasseWLNodeWrap,dievonnode::ObjectWraperbtundWLals

Memberenthältschreiben3.binding.gyp,diebuild-Dateifürnode-gyp,schreiben4.entstehende*.nodeDateientsprechendinJavascripteinbindenundbe-

nutzen

17.4.1Schritt1:Einsteigsdateiaddon.cppschreiben

EinekleineDateiaddon.cppwirddiegesamteStrukturvonC++nachJavascriptverbinden,undsieht–demBeispielderDokumentationfolgend–,soaus:

#ifndefBUILDING_NODE_EXTENSION#defineBUILDING_NODE_EXTENSION#endif#include<node.h>#include"WLNodeWrap.hpp"

usingnamespacev8;

voidInitAll(Handle<Object>exports){WLNodeWrap::Init(exports);

}

NODE_MODULE(WLNodeWrap,InitAll)

Hierwirdfestgelegt,dasseinModulmitdemNamenWLNodeWrapdefiniertwird,und,sobalddiesesperrequire(varaddon=require('./build/Release/WLNodeWrap');aufJavascript-Seiteaufgerufenwird,zurFunktionInitAllgesprungenwerdensoll.DieFunktionInitAllwiederumwirdWLNodeWrap::Initaufrufen,welcheswirsogleichdefinierenwerden.

Page 114: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

114 CHAPTER 14. UNIFIED DEPLOYMENT

14.1.1 Bündelung der Komponenten unter einem Dach

Die zentrale Stelle an der alle Komponenten der WAST-Landschaft zusammen-laufen ist das repository wittfind-web.

wittfind-web stellt nach außen hin die zentrale Webseite als Einstieg für dieNutzer dar; nach innen hin ist dies der Schnittpunkt an dem alle Module zusam-menlaufen1.

Das zentrale Makefile, welches alle diese administrativen Aufgaben übernimmt(und dabei u.a. an komponentenspezifische Makefiles weiterleitet ist hier).

+++ BEGIN DEPRECATED +++Ab hier ist dieses Kapitel ein bisschen out-dated, vermittelt aber trotzallem den richtigen Eindruck von unserem neueren Makefile-Ansatz,bitte die folgenden Teile Updaten!Um die Komponenten und Tools unter einem Dach zu bündeln bietet wast-infrastructure den Befehl wast.

Unter wast werden die verschiedenen Komponenten registriert und sind damitfür den “unified deployment”-Prozess verfügbar:

> ./wastWAST, version 0.9.5

This is the help section

Usage:

./wast <command>

Available COMMANDS:init : initialize (all) componentsbuild <component> : build component <component>start <component> : start component <component>stop <component> : stop component <component>restart <component> : restart component <component>

Available COMPONENTS:wast-feedback-appwast-websitewf

1siehe hierzu auch das Kapitel Integration Tests und E2E Tests. Inegration Tests prüfendas korrekte Zusammenspiel von Komponenten welche, einzeln für sich bereits alle ihre eigenen[Unit Tests][] bestehen. Mit E2E Tests beschreibt man komplette User-Szenarien, wie diesesich auf der Webseite bewegen und mit dieser interagieren. Hierbei wird auch gleichzeitig dieVerfügbarkeit der Webserver und der auf diesen vorhandenen routes, etc. geprüft)

17.4. DEMONSTRATION 147

Figure 17.1: Node Wrapping Pattern

8 class WL {9 typedef StringType string_type;

10 typedef std::vector<string_type> value_type;11

12 public:13 explicit WL() = default;14 virtual ~WL() = default;15

16 void add(const string_type & s);17 size_t size() const;18

19 auto begin() -> typename value_type::iterator;20 auto end() -> typename value_type::iterator;21 bool operator== (const WL& other) const;22

23 private:24 value_type wl_;25 };26

27 #include "WL.cpp"28

29 #endif /* end of include guard: WL_HPP_A8E3G2X4 */

Diese Klasse soll nun also nach node gewrapped werden, damit sie folgender-

Page 115: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

14.1.WAST-INFRASTRUCTURE115

sis

DieKomponentenwerdenunterAvailableCOMPONENTSgelistetundsindsomitfürdieBefehle,dieunterCOMMANDSgelistetsind,verfügbar.

BeispielsweiselässtsichsomitalsodieKomponentewfmitfolgendemBefehlbildenundstarten:

>./wastinitwf&&\./wastbuildwf&&\./waststartwf

Selbstverständlichlässtessichdarübernachdenken,welcheweiterenSub-Befehlefürwastnochdenkbarsind(z.B.istwastrelease<version>nochnichtimplementiert,unddenkbarsindauchBefehlewiewasttest<component>,wastdeploym<component>umdievorhergehendendreiBefehlezusammenzufassen).DieserTeilbefindetsichbishernochinderbeta-undEvaluations-Phase,dahersollenzunächstdiewichtigstenBefehlerobustimplementiertsein,bevorneueFunktionalitäthinzugefügtwird.

UmwastneueFunktionalitäthinzuzufügenodereineKomponenteTeildesuni-fieddeployment-Prozesseszumachenistgarnichtvielnötig,wieimnächstenTeilgezeigtwird.

14.1.2Abstraktiondesdeployment-Prozesses

wasterwartetvoneinerKomponenteimwesentlichen2Dinge:

•dieKomponentewollinwastregistriertsein•dieKomponentesollfürallewast-Sub-Befehle,dieunterstütztwerden

sollen,einentsprechendesSkriptliefern.Konkretmusswf,wennesdieBefehlewastbuildundwaststartanbietenwill,inseinemVerzeichnisdieDateienwast.buildundwast.startanbieten.

14.1.2.1Beispiele

IndiesemBeispielsolldieKomponentesisundihreImplementationimRahmenderwast-infrastructurebetrachtetwerden.

ZunächstalsodieRegistrierungderKomponenteinderwastinfrastructureinderDateiwast:

14COMPONENTS=(wast-feedback-appwast-websitewfsis)

146CHAPTER17.NODEWRAPPING

MöglichwirddiesdurchdiederzeitschnellsteJavascript-Implementation,V8.V8isteineJavascript-ImplementationinC++undwirdvonGoogleopensourcebereitgestellt.(V8istübrigensauchimBrowserChromefürdieJavascript-Ausführungzuständig.)ÜberdieseBridgenunkönnenalleobengenanntenAufgabenzwischendenbeidenSprach-Weltenwahrgenommenwerden.

17.1Beispiel

DasKapitelWeb-EbeneimTeilSISzeigtingenauererWeiseeinBeispielfürdieVerwendungderC++-AutomatenaufJavascript-Ebene.

17.2NodeAddon

DadasSchreibenvonNode-AddonskeineganzsimpleSacheist,empfiehltessichdieDokumentationhierzusehrgenauzustudierenundsichunbedingtsonahewiemöglichandievorgeschlagenenPatternsundBeispieleinderDokumeneta-tionzuhalten:http://nodejs.org/api/addons.html

17.3SchematischeDarstellung

Abbildung17.1aufSeite147zeigtdieschematischeDarstellungeinesnode-wrap.

17.4Demonstration

DieseDemonstrationhältsichsehrengandasPattern“WrappingC++Objects”ausdernode-addon-Dokumentation(http://nodejs.org/api/addons.html#addons_wrapping_c_objects)undbeschreibtnocheinmaldieeinzelnenSchritteetwasdeutlicheralsesdieDokumenationselbsttut.

Angenommen,esgibteineeinfacheKlasseWordList(bzw.WL)mitfolgen-demHeader(unddenentsprechendenDefinitionenzudenMethodenineinempassenden.cpp-File):

1#ifndefWL_HPP_A8E3G2X42#defineWL_HPP_A8E3G2X43

4#include<string>5#include<vector>6

7template<classStringType>

Page 116: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

116 CHAPTER 14. UNIFIED DEPLOYMENT

Als nächstes die entsprechenden Skripte in der Komponente selbst:Hier also die Datei wast.build innerhalb der Komponente “sis”:

#!/bin/sh

set -x # Show the commands that are executed

# try "Creating build directory" bymkdir -p build

# try "Switching to build directory" bycd build

# try "Running cmake" bycmake ..

# try "Running make" bymake VERBOSE=1

# try "Switching to web component" bycd ../web

# try "Installing web dependendices" byCXX=/usr/bin/g++-4.8 npm install

# try "Installing web dependendices" bybower install

Und hier die Datei wast.start innerhalb der Komponente “sis”, um den Befehl./wast start sis zu unterstützen:

#!/bin/shset -x# try "Starting feedback app" bycd webLD_LIBRARY_PATH=/srv/www/vhosts/wast/components/sis/build/lib \sudo -u wastd forever start -a app.coffee

+++ END DEPRECATED +++

14.2 user wastd

Alle Skripte und Komponenten, die einen Webserver starten und lange laufen,sollen unter dem “Pseudo-Superuser” genannt wastd gestartet werden.

Chapter 17

Node Wrapping

Inhalt17.1Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . 14617.2Node Addon . . . . . . . . . . . . . . . . . . . . . . . . 14617.3 Schematische Darstellung . . . . . . . . . . . . . . . . 14617.4Demonstration . . . . . . . . . . . . . . . . . . . . . . . 146

17.4.1 Schritt 1: Einsteigsdatei addon.cpp schreiben . . . . 14817.4.2 Schritt 2: Wrapper-Klasse WLNodeWrap, die von

node::ObjectWrap erbt, schreiben . . . . . . . . . . . 14917.4.3 Schritt 3: binding.gyp, die build-Datei für node-gyp

schreiben . . . . . . . . . . . . . . . . . . . . . . . . . 152

Node-Wrapping bezeichnet das wrappen von C++-Klassen derart, dass dieseinnerhalb von Javascript verwendbar gemacht werden.

Im Rahmen von SIS wird dies konkret vorgeführt: die dokument-indexierendenAutomaten auf der C++-Ebene werden von der Javascript-Ebene (und damitdem node-Webserver) nur ein einziges Mal deserialisiert und ab dort als vollw-ertige Automaten im Speicher gehalten.

Vom node-Webserver aus nun lassen sich die C++-Automaten ansprechen undbenutzen.

Um dieses language-binding zu bewerkstelligen bietet node den sog. “addon”-Mechanismus, welcher es eben erlaubt, C++-Klassen mit Javascript zuverbinden.

Die Verbindung dieser beiden Sprach-Welten läuft dabei in beide Richtungen:sowohl lassen sich aus der C++-Welt Javascript-Objekte bilden und diese nachJavascript “pushen”, als auch C++-Objekte auf der Javascript-Seite konstru-ieren, laden und dergleichen.

145

Page 117: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

14.2.USERWASTD117

Dieser“Pseudo-Superuser”hatdenVorteil,dassWebserver,dievonjemandanderemgestartetwurden,voneinerweiterenPerson–imFalledesFalles–auchwiederge-kill-tundgestopptwerdenkönnen.NormaleProzesse,dievoneinembestimmtenUsergestartetwurden,erlaubenesnicht,voneinemanderenUserge-kill-tzuwerden.

DerUserwastdistabernichtimechtenSinneeinSuper-Usermitroot-Rechten,sondernlediglicheinentsprechendausgestatterUser,derebendiesegemeinsameNutzungvonlangelaufendenProzessenüberverschiedeneUserhinwegerlaubt.

144CHAPTER16.SERIALISIERUNG

•std::is_class<C>isteingültigerType•DerbetreffendeContainerChateineMethodebegin()undeineMethode

end()welcheeinenconst_iteratorzurückliefern.

FürmehrDetailsvergleichehttps://github.com/xdbr/cpp-generic-serialize.

Page 118: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

118 CHAPTER 14. UNIFIED DEPLOYMENT 16.4. APIS 143

• Wenn ein Container vorliegt (gesteuert von den Prinzipien von SFINAEund EnableIfContainer<T>), dann betrachte rekursiv alle Elemente([Type Traits][]: value_type) dieses Containers, so lange bis du auf einenfundamentalen Datentyp stößt: int, char, o.ä.

• Sobald ein Container bis auf seine fundamentalen Datentypen zurückge-führt, ist, so kann dieser Type binär gespeichert werden:

template <typename T, EnableIfFundamental<T>...>Tsave(std::ofstream & os, T t) {

os.write(reinterpret_cast<const char*>(&t), sizeof(t));return t;

}

• Hierbei wird zuerst die Größe des Containers und danach die einzelnenfundamentalen Datentypen gespeichert, z.B.:

template <typename T, EnableIfContainer<T>...>Tsave(std::ofstream & os, T t) {

unsigned size = t.size();save(os, size);

for (auto it = begin(t); it != end(t); ++it) {save(os, *it);

}return t;

}

Das Einlesen funktioniert mutatis mutandis.

Ein Container liegt vor – und aktiviert nach den Prinzipien von SFINAE –die entsprechende save/load Funktionalität wenn folgendes Konstrukt einengültigen Typ zurückliefert:

template<typename C>struct is_container<C,

typename is_of_type<typename C::const_iterator(C::*)() const,&C::begin,&C::end

>::type> : std::is_class<C> { };

D.h. es wird, um einen Container zur Compile-Zeit zu erkennen vom type Cfolgendes erwartet:

Page 119: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

PartVII

Techniken

119

142CHAPTER16.SERIALISIERUNG

namespaceusb=util::serialize::binary;

/*Example:Writenestedcontainertoabinaryfile*/std::list<std::map<std::string,unsigned>>list={{{"foo",1},{"bar",2}},{{"baz",1},{"quux",2}}

};

/*save*/std::ofstreamos{"file.bin",std::ios::out|std::ios::binary};usb::save(os,list);os.close();

DasEinlesenvonBinärdatenmitgenericserializeistebenfallssehreinfach:

namespaceusb=util::serialize::binary;

/*Example:Readnestedcontainerfrombinaryfile,way#1*/std::ifstreamis{"file.bin",std::ios::in|std::ios::binary};std::list<std::map<std::string,unsigned>>list;usb::load(is,list);

EinandererWegwärees,denContainer-Typalstemplate-ArgumentanzugebenundC++11’sautozunutzen:

namespaceusb=util::serialize::binary;

/*Example:Readnestedcontainerfrombinaryfile,way#2*/std::ifstreamis{"file.bin",std::ios::in|std::ios::binary};

autolist=usb::load<std::list<std::map<std::string,unsigned>>

>(is);

AufdieseArtundWeisewerdenbeliebigeContainerineinemFormatwieinderGrafikAbbildung16.1abSeite138angedeutet,angelegt.

16.4.3.1BeobachtungenDiesesKapitelbeschreibtsehrtiefeundz.T.sehrkomplexeDetailsundistnuralstechnischeReferenzfürInteressiertegedacht.

ImwesentlichenbedientsichgenericserializederTechnikenderTemplateMetaProgrammierungunddenHilfestellungenvonhttp://flamingdangerzone.com/cxx11/2012/05/29/type-traits-galore.html.

DabeifunktioniertderSpeicher-Algorithmusfolgendermaßen:

Page 120: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

16.4. APIS 141

int main() {/* Container füllen ... */

// JSON nach std::cout serialisieren:cereal::JSONOutputArchive json_archive_cout{std::cout};json_archive_cout( wl );

/* ... */}

Das Einlesen ist wiederum genauso einfach:

#include <iostream>#include <fstream>#include <string>

#include <cereal/archives/binary.hpp>

#include "WordList.hpp"

int main() {

/* Es gibt eine Binär-Serialisierte WordList ... */std::ifstream is{"out.bin", std::ios::binary};

// cereal Input-Archiv auf diese Datei festlegencereal::BinaryInputArchive binary_archive{ is };

// leeren Container anlegenWordList wl;

// Container aus Binär-Datei ladenbinary_archive(wl);

return 0;}

16.4.3 generic serialize

generic serialize erlaubt es, beliebige Standard-Container (mit beliebigerSchachtelung) individuell mit save zu speichern und mit load zu laden.Es kümmert sich automatisch darum, die richtige Speichermethode für denContainer und die “Tiefe” des Containers zu finden.Die API von generic serialize ist ebenfalls sehr einfach und überschaubar. Siefunktioniert so:

Page 121: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

Chapter15

C++

Inhalt15.1WrappingvonCnachC++...............121

15.1.1Vorteile.........................12215.1.2Patterns.........................122

15.2PolicybasedDesign....................12515.2.1Beispiel.........................125

15.3Typetraits.........................12715.3.1Beispiel.........................128

15.4TemplateMetaProgrammierung............12915.5SFINAE...........................12915.6SilentDegredation.....................130

15.6.1Beispiel.........................13115.6.2Bemerkung.......................131

15.7StaticDispatching/Tagdispatch...........13215.8Detail-Beschreibung....................13315.9Bemerkungen........................13415.10WrappingvonC++nachJavacript(Node).....134

IndiesemKapitelwerdenentscheidendeTechnikenvorgestellt,diebesondersinfortgeschrittenenC++-ProgrammeneinegroßeRollespielenkönnen.DiefolgendenTechnikenkommensehrvielzumEinsatzinwittfindundSIS.

15.1WrappingvonCnachC++

InmanchenSituationenbietetessichan,CstructsnachC++zuwrappen.

121

140CHAPTER16.SERIALISIERUNG

private:list_tlist_;

public:template<classArchive>voidserialize(Archive&archive){

archive(list_);}

};

NunkanndieKlassevonaussenserialisiertunddeserialisiertwerden:

#include<iostream>#include<fstream>#include<string>

#include<cereal/archives/binary.hpp>

#include"WordList.hpp"

intmain(){WordListwl;

//ElementezumContainerhinzufügenstd::stringbaz{"baz"};wl.add("foo");wl.add(std::string{"bar"});wl.add(baz);

std::cout<<wl.size()<<std::endl;

//Binär-Dateianlegen,inwelcheserialisertwerdensollstd::ofstreamos{"out.bin",std::ios::binary};

//cereal-ArchivaufdieBinär-Dateianlegencereal::BinaryOutputArchivebinary_archive_file{os};

//SerialisierbarenContainerindascereal-Archivgebenbinary_archive_file(wl);

return0;}

NachXMLoderJSONzuserialiserenfunktioniertgenaunachdemselbenSchema:

Page 122: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

122 CHAPTER 15. C++

15.1.1 Vorteile

Die entscheidenden Vorteile des Wrappens von C nach C++ sind:

• automatische und saubere Allokation / Deallokation von Klassen bzw.structs (dieses ist auch bekannt unter dem Namen “RAII” – zu diesemsiehe auch das nächste Kapitel sowie Definitionen)

• einfacheres “Handling” der Instantiierung von Klassen, also Konstruktionund, v.a. sauberere, sicherere Destruktion

Selbstverständlich lassen sich nach dem Wrapping auch alle Vorteile von C++bzw. C++11 (und, später C++14) nutzen. Darunter fallen u.a.:

• Die Smart Pointers shared_ptr und unique_ptr: Diese legen u.a. festeOwnership zu Grunde. Damit wird verhindert, dass man vergisst einstruct wieder zu deallokieren und die Zuständigkeit wird festgelegt: wersoll den pointer am Ende wieder deallokieren?

• Templatisierung

• Vererbung und Interfaces und damit klare Strukturen: Mit C++ lässt sichviel stärker auf der Problem-Ebene arbeiten denn auf der reinen Sprach-Ebene

15.1.2 Patterns

Grundlegend funktioniert das Adapter/Wrapper-Pattern immer auf die gleicheArt und Weise: Es gibt eine Klasse die gewrapped werden soll, den Adaptee undeinen Wrapper, den Adaptor bzw. Wrapper.

Figure 15.1: Adapter Pattern

16.4. APIS 139

16.4.2 cereal

Die API von cereal ist relativ einfach – für einen tiefergehenden Einblick vergle-iche das Kapitel Zweistufige Serialisierung in SIS: Symmetric Index Structures.

Im Grunde ist es lediglich notwendig eine Methode der folgenden Art in seinerKlasse zu schreiben:

Angenommen, die Klasse hat folgendes Member list_:

#include <vector>#include <string>

class WordList {public:

typedef std::vector<std::string> list_t;

/* Constructors, Methods, etc... */

private: // Memberslist_t list_;

};

So reicht es bereits aus, die notwendigen header von cereal und eine Methodeserialize() folgendermaßen zu schreiben:

// This method lets cereal know which data members to serializetemplate<class Archive>void serialize(Archive & archive) {

archive( list_ ); // serialize things by passing them to the archive}

Die Klasse sieht nun also so aus:

#include <vector>#include <string>

#include <cereal/types/string.hpp>#include <cereal/types/vector.hpp>

class WordList {public:

typedef std::vector<std::string> list_t;

/* Constructors, Methods, etc... */

Page 123: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

15.1.WRAPPINGVONCNACHC++123

DerWrapperhälteineVerbindungzumAdapteeundbildetdieAPInach.DerClientwirdnurnocheinenAdaptorbzw.WrapperinstantiierenundderAdap-torkümmertsichdarum,denentsprechenden,eigentlichenAdapeezukonstru-ieren.

WennderClientMethodendesAdaptorsverwendet,sowirddieserlediglichdieParameterandenAdapteeweiterleitenunddieErgebnisse,dievomAdapteekommenwiederandenClientzurückleiten.

ImFallvonC++bietetessichnatürlichan,denAdapteealsPointerimAdaptorzuhalten.

Einmögliches,elegantes,sicheresundeigentlichsimplesPatternumCstructsnachC++zuwrappenbeschreibt(R.MartinhoFernandes2013)mitseiner“RuleofZero”.EinekonkreteAnwendungwirdimKapitelAbschnitt3.6.1.1abSeite43sowiehierimDetailbeschrieben.

UmdiesesPatternbesserverstehenzukönnensollandieserStellenocheinmaleingenuererBlickdaraufgeworfenwerden.AlsBeispieldientindiesesmFalldieKlasseVoidSequenceAdapter,welchedasC-StructVoidSequencewrapped.

VoidSequencestelltinderC-SchichteineArtstd::vectordar,indemeseineListevonElementenführt,und,fallsderallokierteSpeichernichtausreicht,neuenbesorgt,umweitereElementeinseinenMemberseinfügenzukönnen.DabeispeichertesbeliebigeObjekte,indemessichalsvoid*verwaltet–let-zteressetztnatürlichvoraus,dassdiesepointerspäterwiederentsprechend“zurückgecastet”werden.

WieauchimmerdasstructimDetailaussieht,dasWrapping-Patternbleibtstetsidentisch.ZunächstsolleinnaiverAnsatzvorgestelltwerden,welcherdannkontrastiertwirdvondem“RuleofZero”-Ansatz.

1#include"Adaptee.h"23classAdaptor{4Adaptee*adaptee_;5Adaptor():adaptee_{newAdaptee()}{};6~Adaptee(){deleteadaptee_;}7};

DiesernaiveAnsatzzeigtdasWrapping-PatterninklassischerWeiseinC++:eswirdeinPointerzumAdapteegehalten.DerPointerwirdimKonstruktorhergestelltundimDestruktordeallokiert.Problematischwirdes,wennder“Konstruktor”desAdapteeeineexceptionwirft:KonstruktorensollenkeineExceptionswerfen,daessonstschwierigwird,bereitsgelaufeneAllokationenrückgängigzumachen.

EinfortgeschrittenererAnsatzistder“RuleofZero”-Ansatzvon(R.MartinhoFernandes2013):IndiesemFallistauchdieOwnershipzurAdaptee-Ressourcegeregelt,daessichhierumeinenunique_ptrhandelt.

138CHAPTER16.SERIALISIERUNG

Figure16.1:BeispielfüreinByte-Layout

–hierbeihatdererstestd::stringeinesize()==4–hierbeihatderzweitestd::stringeinesize()==6

DieingesamteGrößedesBinärformatsbeträgtdann19Byte.

16.3.1Beobachtungen

•DerersteCharacterbelegt1Byte•unsignedintbeträgt4Byte(aufeinem64-Bit-System)•boolbelegt1Byte:Obwohleinbooltheoretischnur1Bitstatteinem

ganzenByte(8bit)bräuchte,tritthierdasPhänomendesPaddingaufunddasbitwirdaligned(siehedazuhttp://en.wikipedia.org/wiki/Data_padding)

•Derstd::vector<std::string>istfolgendermaßenaufgebaut:–daserstebytewirdbelegtmitderAngabe,wievieleElementedervectorenthält,alsomitvector.size()

–dasnächstebytekündigtdieGrößedeserstenstd::stringsan:4–nunfolgendie4charactersdeserstenstrings–dadervector2stringsenthältmussnundieLängeninformationüber

denzweitenStringfolgen:string2.size()==6–nunfolgennoch6charsdeszweitenstringsdesvectorunddie

Informationensindvollständig.

16.4APIs

16.4.1Boost.Serialization

Vergleichehttp://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html

Page 124: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

124 CHAPTER 15. C++

1 #include "voidSequence.h"23 class VoidSequenceAdapter {4 using adaptee_handle = std::unique_ptr<VoidSequence, decltype(&::VoidSequenceFree)>;56 private:7 adaptee_handle adaptee_;89 public:

10 VoidSequenceAdapter()11 : adaptee_{ ::VoidSequenceInit(1), &::VoidSequenceFree } {}12 ~VoidSequenceAdapter() {}13 };

15.1.2.1 Besprechung des Codes

• Zeile 1 bindet die Definitionen des C structs ein• Zeile 3 definiert eine Adapter-Klasse VoidSequenceAdapter, die das C

struct VoidSequence wrappen wird• Zeile 4 definiert einen geeigneten Daten-Typ für den Adaptee:

– Der Typ des unique_ptr ist unique_ptr<VoidSequence> miteinem custom-Desktruktor. Letzterer wird aufgerufen, sobald derunique_ptr destruiert wird.

• die gewöhnungsbedürftige Schreibweise &::VoidSequenceFree bedeutetfolgendes:

– unique_ptr verlangt, wenn man einen custom-DTOR angeben will,als zweites Template-Argument den Typ einer Funktion. Dieses wirddurch decltype generiert.

– decltype wiederum wird den Typ der Funktion VoidSequenceFreezurückliefern

– & nimmt die Adresse der Funktion (liefert also einen Pointer zurück)– ::VoidSequenceFree gibt an, dass es sich hier um eine namespace-

lose Funktion handelt. (Also das Gegenstück von, z.B. std::)

• adaptee_handle adaptee_ legt das member adaptee_ vom Typadaptee_handle an. Damit ist sichergestellt, dass zu dem Zeitpunkt,an dem die Destruktion des Objekts VoidSequenceAdapter stattfindet,alle seine member destruiert werden. Damit wiederum wird dercustom-DTOR des adaptee_handle angestoßen und dieser ist einVoidSequenceFree, also ist die Rückbindung an die C-Schicht gegeben.

• Zeile 10-11: Der CTOR von VoidSequenceAdapter nun wird das memberkonkret initialisieren: Als erstes Argument wird die Konstruktionsfunk-tion des C-structs mitgegeben, als zweites Argument die Adresse derDestruktionsfunktion des C-structs.

• Zeile 12: Der DTOR des VoidSequenceAdapters braucht nichts weiter –das member adaptee_handle wird nach den Standard-Regeln von C++destruiert werden.

16.2. FORMATE 137

16.1.1.4 generic serialize

ist eine Idee und ein Proof of Concept von Florian Fink und Daniel Bruder, umeinzelne Container gezielt durch ein- und die selbe API im Binärformat auf dieFestplatte schreiben und von dort wieder laden zu können. Dies wird ermöglichtdurch C++11 und Template Meta Programmierung und SFINAE. Teile hiervonwerden im folgenden gleich beschrieben werden.

16.2 Formate

Die wesentlichen Formate, um Klassen, deren Members und Vererbungskettenauf Festplatte zu speichern und später wieder zu laden sind v.a. die drei folgen-den:

• JSON / Text• XML• Binärformat

cereal und boost serialization unterstützen jeweils alle 3 der hier genanntenFormate.

Selbstverständlich ist das Byte-Format das platzsparendste unter den Formaten,dabei auch das am kompliziertesten “zu debuggende”, sollten Fehler auftreten.JSON ist sowohl platzsparend als auch bequem zu lesen. XML ist am meisten“verbose”.

16.3 Klassische Verfahren: Binärformat undbyte-layout

Beim Serialisieren in das Byte-Format gibt es eine gängige Praxis die hierbeschrieben werden soll.

Im Binärformat muss der Anwender das byte-layout genau kennen, um etwassinnvolles damit anfangen zu können – die Grafik in ?? ab Seite ?? soll diesverdeutlichen.

In diesem Fall werden 4 Variablen gespeichert:

• ein char• ein unsigned int• ein bool• ein std::vector<std::string> mit der Größe 2:

Page 125: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

15.2.POLICYBASEDDESIGN125

15.2PolicybasedDesign

Policy-baseddesignerlaubtes,eineKlasse,dieverschiedenePolicieskennt,aufvieleArtenundWeisenzukonfigurierenundsomiteindeutlichunterschiedlichesVerhaltenderKlasseerzeugenzukönnen.

Policiesdeckendabeiunterschiedliche,orthogonaleKonzepteabundlassensichmiteinanderkombinierenumeineVielzahlvonFunktionalitätenundVerhal-tensweisenzubewirken.

VergleichevorallemdieImplementationdererstenGenerationvonSmartPoint-ern(auto_ptr)welchezudenheutigenStandard-Smart-Pointern(shared_ptrundunique_ptr)geführthabenin(Alexandrescu2000).

15.2.1Beispiel

UmdasBeispielausdemvorherigenKapitelerneutaufzugreifen,sollandieserStelleaufdietatsächlicheImplementationdesadaptee_handleeingegangenwerden:

1classManaged:std::true_type{};2classUnmanaged:std::false_type{};34template<classStringType=std::string,classManagedAdaptee=Managed>classVoidSequenceAdapter;56template<classStringType,classManagedAdaptee>7classVoidSequenceAdapter{89usingadaptee_handle=typename

10std::conditional<11ManagedAdaptee::value==true//ifadapteeistobemanagedbythisadapter12,std::unique_ptr<VoidSequence,decltype(&::VoidSequenceFree)>//thenhandleisaunique_ptrw/customDTOR13,VoidSequence*//otherwise:bareptr,noautomaticdeletion.14>::type;//finally:don'tforgettochoosethistype15adaptee_handleadaptee_;1617/*...*/18};

AbegesehenvondenTemplateMetaProgrammierungs-Anteilen(std::conditional)unddenTypeTraits-Anteilen(ManagedAdaptee::value)indiesemBeispielsollandieserStellederPolicy-BasedAnsatz(ManagedAdaptee)genaubetrachtetwerden.

KurzzurWiederholung:NachderDefintioninZeile4,kanneinVoidSequenceAdapterauffolgendeArtenundWeiseninstantiiertwerdenunddabeieinsehrunter-schiedlichesVerhaltenaufweisen:

1VoidSequenceAdapter<>v1;/*std::string,managed*/2VoidSequenceAdapter<std::wstring>v2;/*std::wstring,managed*/3VoidSequenceAdapter<std::wstring,Managed>v3;/*same*/4VoidSequenceAdapter<std::wstring,Unmanaged>v4;/*std::wstring,unmanaged!*/

136CHAPTER16.SERIALISIERUNG

16.1.1Hinweise

16.1.1.1SelbstgeschriebeneSerialisierungsmethoden

zuverwenden,kannmehrereNachteilehaben:

•esgibtschonguteundweithin-getesteFrameworkswirdboost-serializationundcereal.

•SerialisierunginC++richtigzumachen,kannsehrkompliziertseinundvielAufwanderfordern(v.a.dieSerialisierungvonPointernundtrackenderselben,vonVererbungsketten(virtualvs.non-virtual)undvieleweiteredetailreicheProbleme)

•ÜbertragbarkeitundWartung:solltenandereEntwicklerdiemitdervorhandenenCode-Baseweiterarbeitenmüssen,sokennendiesehöchst-wahrscheinlichschonboostserializationundhabenvorherschonmitdiesergearbeitet

16.1.1.2BoostSerialization

isteineweitverbreitete,d.h.gutbekannteundinvielenProjektengetesteteSerialisierungsbibliothek.BoostSerializationkannu.a.auchrawpointerserial-isiern,wennsolchealsKlassenmemberverwendetwerdenundVererbungskettenbeiderDeserialisierungrichtigauflösen.Leideristesz.T.etwaskomplexunddieDokumentationnichtgeradeleichtzuverstehen;dafüraberistesmiteinedermächtigstenSerialisierungsbibliotheken.

16.1.1.3cereal

cerealisteinejungeSerialisierungsbibliothekundverwendetv.a.FeaturesausC++11,wiez.B.TemplateMetaProgrammierung,umweitreichendeAnnah-menüberDatentypenmachenzukönnen.(Diesistvorallemdarumwichtig,weilC++keineIntrospectionhatbzw.habenkann).

cereal’sAPIistrelativeinfachzuverstehenundeinzusetzen,weshalbcerealinSISeingesetztwird,umdenC++-TeilderAutomatenaufderFestplattezuspeichernundwiederzuladen.

Hinweis:inSISwerdennurdieC++-SchichtderAutomatenvoncerealserialisiert;fürdieC-SchichtwerdendieC-eigenenSerialisierungsmetho-denverwendet.DabeideSchichtenunddiedarinbefindlichenKlassenaufeinanderaufbauen,isthierbeiabertunlichstdaraufzuachten,dassbeide(De-)Serialisierungenordentlichaufeinanderabgestimmtsind!SiehedieentsprechendenKapitelbeiSISfüreinetiefereDokumentationzudiesemThema.

Page 126: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

126 CHAPTER 15. C++

Wie im vorherigen Kapitel besprochen, wird die Klasse VoidSequenceAdapter– im Standardfall – den Speicher des Structs adaptee_ automatisch am Endeseiner eigenen Lifetime deleten, indem es die Funktion VoidSequenceFree ausder C-Schicht aufrufen wird.

Nun kann es aber ganz bestimmte Situationen geben, in welchen dieses Verhal-ten nicht nur unerwünscht sondern fehlerhaft wäre. In diesen Fällen lässt sichein weiteres Template-Argument, Unmanaged mitgeben, um die Klasse derartanders zu gestalten, dass sie kein (!) automatisches delete von VoidSequenceausführen wird.

Dabei spielen folgende Teile zusammen:

• class Managed : std::true_type {}; ist eine bereits fertige Klasseohne weitere Implementation. Sie stellt einen “sprechenden” strong typedar, der sich als Template-Argument nutzen lässt. std::true_typestellt einen Typ aus C++11 dar, der folgendem Typ entspricht:std::integral_constant<bool, true>. Das heisst, es handelt sichhier um einen “strong type” vom Typ bool mit der Belegung true,dessen einfachste Implementierung folgende sein könnte (der Standardübernimmt dieses aber):

template<class T, T v>struct integral_constant {

static constexpr T value = v;};

• Hiermit wiederum lassen sich entscheidende Weichen (zur Compile-Zeit!)stellen, um VoidSequenceAdapter entweder Managed oder Unmanaged zumachen. Um zur Compile-Zeit die Klasse VoidSequenceAdapter anderszu konfigurieren lässt sich Managed::value abfragen, um zu sehen, wiedie Klasse konfiguriert werden soll (vergleiche hierzu das “Type Traits”-sowie das “Template Meta Programmierungs”-Kapitel).

• In diesem elaborierteren Fall wird also der Typ des adaptee_handle zurCompile-Zeit entschieden und kann – je nach Typ von ManagedAdaptee –eines der beiden folgenden werden:

std::unique_ptr<VoidSequence, decltype(&::VoidSequenceFree)>

oder schlicht:

VoidSequence*

Mit diesem Policy-Based Ansatz ist es also möglich, eine Klasse zu schreiben,die mehreren Ansprüchen – je nach Bedarf – gerecht werden kann: ImStandardfall ist VoidSequenceAdapter eine Adapter-Klasse, welche den

Chapter 16

Serialisierung

Inhalt16.1Methoden zur Serialisierung . . . . . . . . . . . . . . . 135

16.1.1 Hinweise . . . . . . . . . . . . . . . . . . . . . . . . . 13616.2 Formate . . . . . . . . . . . . . . . . . . . . . . . . . . . 13716.3Klassische Verfahren: Binärformat und byte-layout . 137

16.3.1 Beobachtungen . . . . . . . . . . . . . . . . . . . . . 13816.4APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

16.4.1 Boost.Serialization . . . . . . . . . . . . . . . . . . . 13816.4.2 cereal . . . . . . . . . . . . . . . . . . . . . . . . . . . 13916.4.3 generic serialize . . . . . . . . . . . . . . . . . . . . . 141

Unter Serialisierung versteht man das Abspeichern einer konkreten, instanzi-ierten Klasse – henau genommen der Klassentyp, seine Member und dieVererbungskette – auf der Festplatte, um diese Klasse in genau diesem Zustandzu einem späteren Zeitpunkt wiederherstellen zu können.

16.1 Methoden zur Serialisierung

Für das Serialisieren und Deserialisieren in C++ gibt es mehrere Möglichkeiten:

a) selbst geschriebene Serialisierungsmethoden verwendenb) Boost Serializationc) cereald) generic-serialize

135

Page 127: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

15.3.TYPETRAITS127

RAII-Prinzipenfolgt;solltejedocheinanderes,möglicherweiseorthogonales,Verhaltenbenötigtwerden,solässtsichdiesesebensoumsetzenundderrestlicheCode,derVoidSequenceAdapternutzt,kanndiesenauchweiterhinwiegewohntnutzen.

ZudiesemKapitelwirdempfohlenauchdieanderenKapitelTemplateMetaPro-grammierung,SFINAE,Typetraits,undSilentDegredationgenauzubeachten;vorallemaber(Alexandrescu2000),(DiGennaro2012)und(AbrahamsandGurtovoy2005)genauzustudieren.

15.3Typetraits

TypetraitssindimwesentlichenschlichttypedefsineinerKlasse,diemanvonaußenabfragenkann.

EinkleinesBeispielsolldieskurzdarstellen:

Anstattfolgendeszuschreiben:

1#include<vector>2#include<string>3#include<cctype>4#include<algorithm>5#include<iostream>6

7#include<boost/algorithm/string.hpp>8

9intmain(){10typedefstd::vector<std::string>string_vector_t;11

12string_vector_tvec={"foo","bar","baz"};13

14for(std::vector<std::string>::iteratorit=vec.begin();15it!=vec.end();16++it)17{18std::cout<<*it<<std::endl;19}20

21for(autoit=vec.begin();it!=vec.end();++it){22boost::to_upper(*it);23}24

25for(constauto&elem:vec){26std::cout<<elem<<std::endl;27}28

29return0;30}

läßtsichaufeinfachdertypedefvalue_typevonstd::vectornutzen:

134CHAPTER15.C++

–beiderWeiterleitung–demdispatching–,verwendetautobar()[[dispatcher]]diesenTagderart,dasses:*einMini-ObjektvomTyptag<T>anlegt–durchuniforminitial-

ization:tag<T>{}–diesesMini-Objektkannauchwiederumalslediglichdeskriptivbe-

trachtetwerden,denneswirdletztendlichvomOptimizierentferntwerden

•nunaberistderWegfrei,jenachInstanziierungentwederintbar(tag<int>)oderstd::stringbar(tag<std::string>)aufzurufen.

•SchlussendlichwirdauchnochinnerhalbderdispatchendenMeth-odederRückgabewertoffengehaltenundrichtetsichnachdemRückgabewertderlogik-tragenden,[[dispatched_to]]-Methode:->decltype(this->bar(tag<T>{}))

15.9Bemerkungen

Offensichtlichlässtsichmitden[[Attributen]]spielenunddiesesindvariabelhinsichtlichdessen,wodiesegenauplatziertwerden.

AttributewurdeninC++11eingeführt,umdenWegaufSprachebenedahinge-hendzuöffnenundstandardisieren,dassderCompiler(zueinemspäterenZeit-punkt)dieseAttributeinderKompilierungnutzenkann–bisherjedochwer-dendiesevondengängigenCompilerngroßflächigignoriert,sindaberbereitsnutzbar,wieindiesemBeispiel;machenaberlediglichfürdenAnwenderSinn.

DieImplementationvondiesemCode-Stückfindetsichhier.

15.10WrappingvonC++nachJavacript(Node)

SiehehierzudaseigeneKapitelNodeWrapping.

Page 128: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

128 CHAPTER 15. C++

1 #include <vector>2 #include <string>3 #include <cctype>4 #include <algorithm>5 #include <iostream>6

7 #include <boost/algorithm/string.hpp>8

9 int main() {10 typedef std::vector<std::string> string_vector_t;11

12 string_vector_t vec = { "foo", "bar", "baz" };13

14 std::for_each(begin(vec), end(vec), [&](string_vector_t::value_type & elem) {15 std::cout << elem << std::endl;16 });17

18 std::for_each(begin(vec), end(vec), [&](decltype(vec)::value_type & elem) {19 boost::to_upper(elem);20 });21

22 std::for_each(begin(vec), end(vec), [&](std::vector<std::string>::value_type & elem) {23 std::cout << elem << std::endl;24 });25

26

27 auto output_function = [&](string_vector_t::value_type & elem) {28 std::cout << elem << std::endl;29 };30 std::for_each(begin(vec), end(vec), output_function);31

32 return 0;33 }

Type traits lassen sich insbesondere im Zusammenspiel von verschiedenenKlassen nutzen und ermöglichen es, unterschiedliche Klassen unabhängigervoneinander zu halten, dabei aber für mehr Typsicherheit zu sorgen.

15.3.1 Beispiel/// @brief meta-class to handle StringType type traits (using static assertions)template<class T>struct ElementSize {

static constexpr bool T_is_string_type =std::is_base_of< std::string, T>::value

|| std::is_base_of<std::wstring, T>::value ;

static_assert(T_is_string_type,"\n\n\tYou must instantiate this class in question with std::string,""\n\tstd::wstring, or any class derived thereof.\n"

);

typedef T type;typedef T string_type;typedef typename T::value_type value_type;

typedef typename std::conditional<

15.8. DETAIL-BESCHREIBUNG 133

10

11 [[ dispatched_to ]]12 std::string bar(tag<std::string>) {13 return std::string{"foo"};14 }15

16 int bar(tag<int>) [[ dispatched_to ]] {17 return 5;18 }19

20 auto bar() [[ dispatcher ]]21 ->decltype(this->bar(tag<T>{})) // 'this' seems to be needed here.22 {23 return bar(tag<T>{});24 }25 };

15.8 Detail-Beschreibung

• es gibt einen zentralen Einstiegspunkt, die Methode bar(): die Methodebar() ist mit dem Attribut [[dispatcher]] markiert und zeigt damitan, dass bar() keinerlei Logik hält, sondern lediglich weiterleiten (dis-patchen) wird, zu den anderem Methoden, welche die Logik beinhalten.Das Attribut [[dispatcher]] hat keinerlei Funktionalität, ausser, dasssie dem Anwender einen Hinweis darauf gibt, was diese Methode macht.

• ebenso wie es einen [[dispatcher]] gibt, gibt es also nun Logik-tragendeFunktionen oder Methoden, zu welchen dispatched wird, diese sind mitdem Attribut [[dispatched_to]]markiert – wiederum ist dieses Attributlediglich ein Hinweis an den Anwender und könnte dementsprechend aus-gelassen werden, es tragt keine weitere Funktionalität. Die beiden Logik-tragenden Methoden sind:

– int bar(tag<int>) und– std::string bar(tag<std::string>)

• bei einem genauen Blick auf den Funktionsteil des [[dispatcher]] siehtman, dass es die ge-tag-ten Methoden [[dispatched_to]] aufruft, bzw.an diese weiterleitet. Diese letzteren Methoden sind implementationsab-hängig, basierend auf dem type T, mit welchem die Klasse Foo<> instanzi-iert ist.

– zu diesem Zweck gibt es eine weitere (Mini-)Klasse template<classT> struct tag{}; welche auch wiederum zum größten Teilnur “deskriptiven” Charakter hat, um anzudeuten, dass hier eintag-dispatching stattfindet.

Page 129: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

15.4.TEMPLATEMETAPROGRAMMIERUNG129

std::is_same<std::string,T>::value,//ifStringTypeisstd::stringstd::fstream,//thenstream_typeisstd::fstreamstd::wfstream//elseitisstd::wfstream>::typestream_type;

staticconstexprunsignedintvalue=sizeof(typenamestring_type::value_type);

};

15.4TemplateMetaProgrammierung

TemplateMetaProgrammierungbestehtausmehrerenTeilendieindennäch-stenKapitelnbesprochenwerden

15.5SFINAE

Einein“Metaprogrammierungskreisen”häufiggeseheneAbkürzungistSFINAE–wobeidiesesMonstrumanAbkürzungfür“Substitutionfailureisnotanerror”steht(“SubstitutionFailureIsNotanError”2014).

BeiSFINAEgehtesumfolgendesPrinzip:

ManmachtsichdieGarantiedesStandardszunutze,dass,fürdenFall,indemeinTemplate-Argumentungültigist,keinFehlerausgelöst,sonderndieserschlichtübergangenwird.

GanzgrundsätzlichgehtesbeiSFINAEumfolgendes:

Ifaninvalidargumentorreturntypeisformedwhenafunctiontemplateisinstantiatedduringoverloadresolution,thefunctiontem-plateinstantiationisremovedfromtheoverloadresolutionsetanddoesnotresultinacompilationerror.

Kurzgesagt:

•währenddesEinsetzensvonTempalte-ArgumentenindieTemplate-Klassenwerdenpotentiellvieletemplate-KlassenvomCompilerangelegt

•diese“ausgefüllten”Template-Klassenlandenimsog.“OverloaodResolu-tionSet”.

•beidieserOperationkönnenFehlerentstehen(informvon“ill-formed”classes)–diesewerdenschlichtübergangen.

•Voilà!DiesesAussortierendesCompilersvonill-formedclassesbewusstzunutzenistSFINAE.

132CHAPTER15.C++

ImNormalfallwirdnämlichdietemplateclassXüberalldort,wosieverwen-detwird,vomCompiler(u.U.auchvieleMale)instantiiertnurumamSchlussallediese–bisaufeine–wiederzuverwerfen.

C++11erlaubteineeinmaligeSpezialisierungaufdiesichandereCode-Teilestützenkönnenmit:

externtemplateclassstd::vector<MyClass>;

AllerdingsbeisstsichnundiesesKonzeptmitder“silentdegredation”dadurchdiesesVorgeheneinevolleSpezialisierungunddamiteinevolleInstantiierungvorgenommenwird.

15.7StaticDispatching/Tagdispatch

Beimstaticdispatchingbzw.auchtagdispatchinggehtesdarum,verschiedeneFunktionen(oderMembers)mittagszuannotierenund,jenachBedarf,gezieltauszuführen.

Angenommen,manhatdasfolgendeProblem:

EsgibteinKlassen-Templatetemplate<classT>FoowelcheeineMember-Methodebar()hat.

NungibteszweiunterschiedlicheInstanziierungenfürdenContainerFoo:ein-malalsFoo<std::string>undeinmalalsFoo<int>.

BasierendaufdieserInstanziierungsollennunzweikomplettunterschiedlicheMethoden(imSinnevonunterschiedlichenImplementierungen)derMethodebar()aufgerufenwerden.

Diesließesich–indiesemBeispiel–,auchdurchpartielleSpezialisierunger-reichen,dennochgreiftdasBeispielindemSinne,alsdassdietagdispatching-TechnikauchinanderenFälleneingesetztwerdenkann;nichtnurindiesemFall.

Einmember-dispatch-pattern,umdieseszuerreichenkönntez.B.soaussehen:

1#include<type_traits>2

3//C++11Proofofconceptofdifferentimplementationsof4//membermethodsfordifferenttypesofclassinstances.5

6template<classT>structtag{};7

8template<classT>9structFoo{

Page 130: ah q - cip.ifi.lmu.debruder/wast/build/wast-book.pdf · ib i2M *QM ah q A N QHb Q h ? a2 `+ M+2/ /p qBii;2Mbi2BM R RR Em`b2b /2b #bi` +i RXR X X X X X X X X X X X X X X X X X X X

130 CHAPTER 15. C++

In der Standard-Library von C++11 gibt es z.B. eine Meta-Funktionstd::enable_if<>.

Ihre Definition wird in etwa so aussehen:

template <bool Condition, typename T = void>struct enable_if {}; // no members

template <typename T>struct enable_if<true, T> { using type = T; }; // type member

Beispiel-Aufruf:

typename std::enable_if<std::is_floating_point<T>::value>

Wenn nun T von einem is_floating_point-Typ ist, so ist ein Type Trait ::typedefiniert, ansonsten nicht.

Dieses Konstrukt nun lässt sich an verschiedenen Stellen einsetzen um z.B. unterbestimmten Bedingungen Funktionen ein- und auszuschalten, oder unter bes-timmten Bedingungen andere Überladungen anzubieten:

• std::enable_if kann als zusätzliches Argument einer Funktion verwendetwerden (aber nicht bei Operatoren-Überladungen)

• als Rückgabewert (daher aber nicht Konstruktoren und Destruktiren)

• oder als Klassen-Template oder Funktionstemplateparameter

Als Hintergrundlektüre siehe auch:

• http://en.cppreference.com/w/cpp/types/enable_if• http://flamingdangerzone.com/cxx11/2012/06/01/almost-static-if.html

15.6 Silent Degredation

Unter silent degredation bzw. “incomplete instantiation” versteht man folgendesPrinzip: Wenn eine Member-Methode einer Template-Klasse nie verwendet wird,so wird diese auch niemals instanziiert. (Alexandrescu 2000, S.13)

Damit lassen sich also höher-geordnete Klassen schreiben, die nach wie vor kom-pilierfähig bleiben, obwohl einige ihrer Member-Methoden eigentlich ill-formedwären – aber nur, falls diese benutzt werden würden!

15.6. SILENT DEGREDATION 131

15.6.1 Beispiel

Angenommen man hat eine Klasse DoItAll mit folgender implementation:

1 template <class Type>2 class DoItAll {3 Type member_;45 public:67 /* CTOR, DTOR */8 DoItAll(Type t): member_{t} {}9 ~DoItAll() {}

1011 /* Methods */12 inline Type plus(Type other) const { return member_ + other; }13 inline Type div(Type other) const { return member_ / other; }14 };

Angenommen, DoItAll würde folgendermaßen genutzt werden:

1 DoItAll<int> doitall_int{8};23 std::cout << doitall_int.plus(34) << std::endl; // 424 std::cout << doitall_int.div(4) << std::endl; // 2

Oder auch so:

1 DoItAll<std::string> doitall_str{"this is"};23 std::cout << doitall_str.plus(" a string") << std::endl; // "this is a string"

…so wäre bis hierhin alles in Ordnung und würde sauber kompilieren – trotzdessen, dass std::string / std::string ill-formed und kein gütliger Aufrufwäre!

Das Geheimnis dahinter ist, dass Methoden von Template Klassen erst in demMoment konkret instantiiert werden, in dem sie auch tatsächlich genutzt werden,d.h. wenn an keiner Stelle doitall_str.div("some string") aufgerufen wird,wird diese Methode auch nicht instantiiert und die Klasse bleibt kompilierfähig.

Dies ist das Geheimnis hinter silent degredation bzw. “incomplete instantiation”und erlaubt wiederum sehr flexible Klassen zu gestalten.

15.6.2 Bemerkung

Mit C++11 gibt es eine Möglichkeit, Kompilierzeit zu sparen, indem manden Compiler mit extern template anweisen kann, sich darauf zu verlassen,dass eine volle Instantiierung/Spezialisierung einer Klasse an anderer Stellevorgenommen wird und an dieser Stelle nicht zu instantiieren.