Documentazione dell'algoritmo Ruby con AsciiDoc e Knitr
Pubblicato: 2022-03-11Ogni progetto non banale ha bisogno di documentazione e deve essere coinvolto con ottime spiegazioni e persino illustrazioni, in modo che venga effettivamente letto e utilizzato. Gli ingegneri realizzano software per risolvere problemi aziendali, generalmente senza avere una vasta esperienza in quella particolare attività, quindi documentare l'attività è importante quanto documentare il software.
La documentazione può essere imbullonata dopo il fatto, ma trovo che scrivere una specifica funzionale prima della codifica sia di grande aiuto. Una specifica funzionale è una fonte di verità per ogni membro del team in tutte le discipline e impone una progettazione di alto livello prima dell'implementazione, prevenendo sprechi di sforzi. In questo post, esaminerò un progetto di esempio dalla prototipazione alla scrittura di una specifica funzionale per un progetto Ruby on Rails di esempio per descrivere cosa dovrebbe fare l'app ed essere un riferimento durante lo sviluppo. Il mio obiettivo è mostrare che i progetti Ruby possono utilizzare AsciiDoc e R per:
- Prototipa facilmente nuovi calcoli, algoritmi, ecc. utilizzando R
- Mostra facilmente i risultati di R nella tua specifica funzionale e in altra documentazione AsciiDoc scritta
- Collegalo al processo di compilazione in modo che la documentazione sia sempre aggiornata con i dati e gli algoritmi più recenti
Una specifica funzionale non sostituisce la documentazione della tua API con RDoc o YARD: è un'aggiunta fondamentale che può essere utilizzata come riferimento per tutte le parti interessate (programmatori e non programmatori allo stesso modo) in un progetto.
Prototipo
Mi piace la pesca al salmone e voglio un modo per me e per gli altri di tenere traccia e condividere i dettagli sul pesce che stanno catturando. Ha anche bisogno di un tabellone segnapunti per mostrare i migliori utenti. In questo momento ci sono forum utilizzati per questo scopo, ma i dati strutturati con un tabellone segnapunti sono molto più interessanti.
Potrei realizzare un prototipo in Ruby, ma Ruby non ha il miglior supporto per la rappresentazione grafica, quindi userò R. L'uso di R mi dà molti modi semplici per giocare con la matematica e la visualizzazione, ed è cross- piattaforma.
# 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 sole due righe, ho letto alcuni dati di esempio e calcolato un punteggio utilizzando il mio punteggio proprietario. R può farlo e mostrare una trama con un'installazione vanilla, mentre linguaggi come Ruby o Python richiederanno più codice e pacchetti extra da installare.
Documentare l'algoritmo
Dopo aver creato il mio sistema di punteggio, potrei passare direttamente al codice. In effetti, avrei potuto saltare la prototipazione in R e semplicemente prototipare direttamente nella mia app Ruby on Rails. Tuttavia, la prototipazione in R è stata veloce e molto vicina alla matematica sottostante. Ecco come imposterò la documentazione:
-
kingfisher/
-
Rakefile
-
doc/
-
func_spec.Radoc
-
-
Il mio esempio di progetto Rails si chiama kingfisher e sto mettendo la documentazione in una cartella "doc". Non esaminerò la sintassi di AsciiDoc poiché il sito di Asciidoctor ha un sacco di ottima documentazione per questo, ma ecco come inserire un grafico nell'AsciiDoc con knitr:
//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
Inseriscilo in func_spec.Radoc
, esegui knitr e AsciiDoc e otterrai qualcosa del genere nella tua documentazione:

Si spera che la maggior parte degli sviluppatori capisca intuitivamente che il punteggio aumenterebbe logaritmicamente con il numero di volte pescato; anche così, questo è un ottimo modo per mostrarlo solo per essere sicuri. Intorno a questo grafico, avrei del testo che spiega perché questo è desiderabile in modo che gli sviluppatori che non pescano possano capire cosa sta succedendo qui. Questo esempio è artificioso, ma in passato ho utilizzato questo tipo di prototipazione e documentazione per altri progetti (ad es. finanza, stime edilizie) in cui i risultati dei calcoli potrebbero non essere sempre evidenti.
Ora che la partitura è stata prototipata e abbiamo una trama da inserire nella documentazione, tutto ciò che resta è trasformare l'input AsciiDoc in una sorta di formato di output. Uso alcune regole nel mio Rakefile per trasformarlo in HTML:
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
Ora posso eseguire "rake docs" e ottenere la documentazione da creare ed essere sempre aggiornato, anche se cambio i dati sottostanti o il calcolo del punteggio.
Altre soluzioni
Per qualsiasi cosa che coinvolga Ruby on Rails, documentare con AsciiDoc è un'ottima scelta indipendentemente dal fatto che ci siano grafici personalizzati nella documentazione o meno. AsciiDoc ti offre un modo nativo di Ruby per scrivere in un meraviglioso formato di markup. Detto questo, ci sono altri ottimi strumenti di documentazione che saranno un po' più da gestire e collegare al tuo processo di compilazione per un progetto Rails.
Sphinx elabora reStructuredText (anche un bel formato di markup) e può incorporare l'output da Matplotlib. Per un progetto Python, questo è perfetto: Sphinx + Matplotlib ti offrono un modo nativo di Python per produrre una bella documentazione con grafica personalizzata. Tuttavia, se stai lavorando su un progetto Rails, è tutt'altro che desiderabile dover gestire più insiemi di dipendenze per un ambiente separato solo per produrre la tua documentazione.
Esistono tantissime altre soluzioni per la produzione di documentazione, inclusi programmi come doxygen e LaTeX, che potrebbero richiedere più o meno colla per adattarsi al tuo sistema di build. Se hai bisogno di un sistema come LaTeX, usalo; se hai un progetto Rails abbastanza standard e hai solo un po' di matematica che dovrebbe essere documentata, usa AsciiDoc e R.
Conclusione
Ruby e AsciiDoc formano una grande squadra ed è facile inserire R nel mix per creare belle visualizzazioni nella tua documentazione. Puoi inserire qualsiasi pacchetto nell'ecosistema R, come ggplot2, per ottenere bellissimi grafici nella tua documentazione.
Il materiale di partenza per questo post può essere trovato nel suo repository GitHub. Al momento della pubblicazione, quel repository non contiene un progetto "reale", ma potrebbe in futuro!
Se vuoi fare un ulteriore passo avanti con Ruby, ti consiglio di imparare la metaprogrammazione con Ruby La metaprogrammazione è ancora più bella di quanto sembri.