Dokumentation des Ruby-Algorithmus mit AsciiDoc und Knitr

Veröffentlicht: 2022-03-11

Jedes nicht-triviale Projekt braucht Dokumentation, und es muss mit großartigen Erklärungen und sogar Illustrationen fesseln, damit es tatsächlich gelesen und verwendet wird. Ingenieure erstellen Software zur Lösung von Geschäftsproblemen, im Allgemeinen ohne über umfangreiche Erfahrung in diesem bestimmten Geschäft zu verfügen. Daher ist die Dokumentation des Geschäfts genauso wichtig wie die Dokumentation der Software.

Die Dokumentation kann nachträglich hinzugefügt werden, aber ich finde, dass das Schreiben einer funktionalen Spezifikation vor dem Codieren eine große Hilfe ist. Eine funktionale Spezifikation ist eine Quelle der Wahrheit für jedes Teammitglied in allen Disziplinen und erzwingt ein High-Level-Design vor der Implementierung, um unnötigen Aufwand zu vermeiden. In diesem Beitrag werde ich ein Beispielprojekt vom Prototyping bis zum Schreiben einer funktionalen Spezifikation für ein beispielhaftes Ruby on Rails-Projekt durchgehen, um zu beschreiben, was die App tun soll, und als Referenz während der Entwicklung dienen. Mein Ziel ist es zu zeigen, dass Ruby-Projekte AsciiDoc und R verwenden können, um:

  • Erstellen Sie mit R ganz einfach Prototypen für neue Berechnungen, Algorithmen usw
  • Zeigen Sie Ergebnisse aus R einfach in Ihrer Funktionsspezifikation und anderen schriftlichen AsciiDoc-Dokumentationen an
  • Binden Sie es in den Build-Prozess ein, damit die Dokumentation immer mit den neuesten Daten und Algorithmen aktualisiert wird

Eine funktionale Spezifikation ist kein Ersatz für die Dokumentation Ihrer API mit RDoc oder YARD – sie ist eine wichtige Ergänzung, die als Referenz für alle Beteiligten (Programmierer und Nicht-Programmierer) in einem Projekt verwendet werden kann.

Prototyp

Ich mag Lachsangeln und ich möchte für mich und andere eine Möglichkeit haben, den Überblick über die Fische zu behalten und Informationen über die Fische, die sie fangen, auszutauschen. Es braucht auch eine Anzeigetafel, um die Top-Benutzer zu präsentieren. Im Moment gibt es Foren, die für diesen Zweck verwendet werden, aber strukturierte Daten mit einem Scoreboard sind viel cooler.

Ich könnte einen Prototyp in Ruby erstellen, aber Ruby hat nicht die beste Unterstützung für die grafische Darstellung, also werde ich R verwenden. Die Verwendung von R gibt mir viele einfache Möglichkeiten, mit Mathematik und Visualisierung zu spielen, und es ist übergreifend. Plattform.

 # Read in some example data data <- read.csv("func_spec/example_user_data.csv") # Compute the score, weighted by base-10 log of number of reports score <- mean(data$Fish.Caught) * log(length(data$Date)) / log(10)

In nur zwei Zeilen habe ich einige Beispieldaten eingelesen und eine Punktzahl mit meiner proprietären Punktzahl berechnet. R kann dies tun und einen Plot mit einer Vanilla-Installation anzeigen, während für Sprachen wie Ruby oder Python mehr Code und zusätzliche Pakete installiert werden müssen.

Dokumentation des Algorithmus

Nachdem ich mein Bewertungssystem erstellt hatte, konnte ich direkt mit dem Code beginnen. Tatsächlich hätte ich das Prototyping in R überspringen und direkt in meiner Ruby on Rails-App prototypisieren können. Das Prototyping in R war jedoch schnell und sehr nah an der zugrunde liegenden Mathematik. So richte ich die Dokumentation ein:

  • kingfisher/
    • Rakefile
    • doc/
      • func_spec.Radoc

Mein Beispiel-Rails-Projekt heißt Kingfisher, und ich lege die Dokumentation in einen „doc“-Ordner. Ich werde nicht auf die AsciiDoc-Syntax eingehen, da die AsciiDoctor-Site eine Reihe großartiger Dokumentationen dafür enthält, aber hier erfahren Sie, wie Sie mit knitr ein Diagramm in das AsciiDoc einfügen:

 //begin.rcode freq_change, fig.asp=0.618, fig.width=12, fig.align="center" times_fished <- 1:50 plot(times_fished, 5 * log(times_fished) / log(10), ylab="User score when average 5 catches per trip", xlab="Number of fishing trips in the past 12 months") //end.rcode

Fügen Sie das in func_spec.Radoc , führen Sie knitr und AsciiDoc aus, und Sie erhalten so etwas in Ihrer Dokumentation:

Beispieldiagrammausgabe nach dem Ausführen von knitr und AsciiDoc.

Hoffentlich verstehen die meisten Entwickler intuitiv, dass die Punktzahl logarithmisch mit der Anzahl der Angelversuche steigen würde; Trotzdem ist dies eine großartige Möglichkeit, dies anzuzeigen, nur um sicherzugehen. Um dieses Diagramm herum würde ich einen Text haben, der erklärt, warum dies wünschenswert ist, damit Entwickler, die nicht fischen, verstehen können, was hier vor sich geht. Dieses Beispiel ist erfunden, aber ich habe diese Art von Prototyping und Dokumentation in der Vergangenheit für andere Projekte (z. B. Finanzen, Bauschätzung) verwendet, bei denen die Ergebnisse der Berechnungen möglicherweise nicht immer offensichtlich sind.

Jetzt, da die Partitur als Prototyp vorliegt und wir einen Plan haben, den wir in die Dokumentation einfügen können, müssen wir nur noch das eingegebene AsciiDoc in ein Ausgabeformat umwandeln. Ich verwende ein paar Regeln in meinem Rakefile, um es in HTML umzuwandeln:

 require 'asciidoctor' require 'pathname' task docs: %w[doc/func_spec.html] rule '.adoc' => '.Radoc' do |t| Dir.chdir(Pathname.new(t.name).dirname) do sh "R -e 'library(knitr);knit(\"#{Pathname.new(t.source).basename}\", " + "\"#{Pathname.new(t.name).basename}\")'" end end rule '.html' => '.adoc' do |t| Dir.chdir(Pathname.new(t.name).dirname) do Asciidoctor.convert_file Pathname.new(t.source).basename, backend: :html5, to_file: true, safe: :safe end end

Jetzt kann ich „Rake Docs“ ausführen und die Dokumentation zum Erstellen abrufen und immer auf dem neuesten Stand sein, selbst wenn ich die zugrunde liegenden Daten oder die Bewertungsberechnung ändere.

Andere Lösungen

Für alles, was mit Ruby on Rails zu tun hat, ist die Dokumentation mit AsciiDoc eine gute Wahl, unabhängig davon, ob die Dokumentation benutzerdefinierte Grafiken enthält oder nicht. AsciiDoc bietet Ihnen eine Ruby-native Möglichkeit, in einem wunderbaren Markup-Format zu schreiben. Abgesehen davon gibt es andere großartige Dokumentationstools, die etwas mehr zu verwalten und in Ihren Build-Prozess für ein Rails-Projekt einzubinden sind.

Sphinx verarbeitet reStructuredText (ebenfalls ein nettes Markup-Format) und kann die Ausgabe von Matplotlib integrieren. Für ein Python-Projekt ist dies perfekt – Sphinx + Matplotlib bieten Ihnen eine Python-native Möglichkeit, eine schöne Dokumentation mit benutzerdefinierten Grafiken zu erstellen. Wenn Sie jedoch an einem Rails-Projekt arbeiten, ist es weniger wünschenswert, mehrere Sätze von Abhängigkeiten für eine separate Umgebung verwalten zu müssen, nur um Ihre Dokumentation zu erstellen.

Es gibt unzählige andere Lösungen zum Erstellen von Dokumentationen, darunter Programme wie Doxygen und LaTeX, die möglicherweise mehr oder weniger Leim benötigen, um in Ihr Build-System zu passen. Wenn Sie ein System wie LaTeX benötigen, verwenden Sie es; Wenn Sie ein ziemlich standardmäßiges Rails-Projekt haben und nur ein bisschen Mathematik haben, die dokumentiert werden sollte, verwenden Sie AsciiDoc und R.

Fazit

Ruby und AsciiDoc bilden ein großartiges Team, und es ist einfach, R in den Mix zu werfen, um schöne Visualisierungen in Ihrer Dokumentation zu erstellen. Sie können jedes Paket im R-Ökosystem, wie ggplot2, einwerfen, um schöne Diagramme in Ihrer Dokumentation zu erhalten.

Das Quellmaterial für diesen Beitrag finden Sie im GitHub-Repo. Zum Zeitpunkt der Veröffentlichung enthält dieses Repo kein „echtes“ Projekt, aber es könnte in der Zukunft sein!

Wenn Sie mit Ruby noch einen Schritt weiter gehen möchten, empfehle ich Ihnen, Metaprogramming mit Ruby Metaprogramming Is Even Cooler Than It Sounds zu lernen.