Metodologia per l'esplorazione di API in lingue dinamiche

4

Come utente abituale di Standard ML e, in misura minore, di Haskell, il seguente schema è profondamente radicato nel mio approccio "istintivo" alla navigazione e all'apprendimento di nuove API:

  1. Comprendi i tipi.
  2. Ricava e usa teoremi liberi.
  3. Hoogle e Djinn sono i miei amici.
  4. Solo se e quando non ricevo più informazioni da 1, 2 e 3; usa i casi di test (fatti a mano o generati da uno strumento simile a QuickCheck).

Ovviamente, questo modello non si estende ai linguaggi dinamici, quindi ho bisogno di una metodologia diversa. Il REPL Python ha la funzione help() , che fornisce la documentazione per una funzione a condizione che conosca già il suo nome. Il LPL REPL è in qualche modo più intelligente e, oltre alla funzione describe (che è analoga a help() di Python), fornisce anche la funzione apropos , che elenca tutte le funzioni il cui nome contiene una determinata stringa. Ma cosa succede se mi trovo di fronte a una libreria totalmente nuova, che devo imparare partendo dalle basi? Come posso determinare cosa deve essere appreso prima ? Anche se "inizia con i tipi" non funziona, ci deve essere qualcos'altro che fa - che cos'è?

    
posta pyon 04.09.2015 - 20:39
fonte

1 risposta

2

Leggi la documentazione. Quando non hai un compilatore per fare la "comprensione" per te, dovrai impegnarti da solo.

Idealmente, un progetto ha vari tipi di documentazione:

  • esempi di snippet di codice
  • introduzioni, tutorial, how-to
  • documentazione di riferimento

Trovo un po 'di codice di esempio estremamente utile per ottenere una panoramica sommaria delle capacità di un modulo. Ecco un esempio di un modulo Perl che ho visto di recente:

SYNOPSIS

use Term::ProgressBar;

$progress = Term::ProgressBar->new ({count => $count});
$progress->update ($so_far);

Questo non è un programma completo, ma illustra gli aspetti più importanti della sua API. Data una tale sinossi, posso spesso fare un rapido giudizio sul fatto che quel codice sarà utile per me. Se è così, continuo a leggere con la documentazione a livello di quadro generale o tutorial.

La panoramica e il tutorial mi daranno un'ampia panoramica delle parti del sistema e introdurrò le parti più comunemente usate. Per le API piccole e semplici, un tutorial potrebbe non essere nemmeno necessario in quanto puoi semplicemente guardare il codice di esempio e sfogliare l'intera documentazione di riferimento in un paio di minuti. Una volta che ho una panoramica, posso spesso intuire dove potrebbero essere implementate alcune funzionalità che vorrei utilizzare, ad es. quale classe o quale spazio dei nomi.

Quando cerco di usare quel modulo, la documentazione di riferimento diventa più importante per me. Idealmente, questa documentazione ha una voce per ogni tipo / classe / funzione / metodo / variabile / simbolo che fa parte dell'API. Dovrebbe descrivere il suo significato nel contesto del suo sistema e descriverne chiaramente il tipo. Per esempio. una classe dovrebbe descrivere tutti i suoi metodi, i suoi invarianti, la sua inizializzazione, .... Una funzione o un metodo dovrebbero descrivere il significato di ciascun parametro e i tipi accettati, cosa farà la funzione con quei dati, cosa restituirà e se genererà un'eccezione. Ecco un esempio di un progetto al quale sto attualmente lavorando:

next_token

my ($type, $value) = $self->next_token;

Retrieves the next token from the input, applying special commands as needed.

This method is the main parsing driver. It implements various special syntax and delegates to command_*() functions when a command is encountered. Note that whitespace and comments are directly written to the currently selected buffer rather than returning them as a token.

Returns a two-value list: $type is the token type ID of the found token. This should be only used for comparisons with the token type constants. To get the name of the token type, use $self->TOKEN_NAMES->{$type}. $value is the arbitrary value of the token, which in general would be a string.

Throws on illegal syntax.

Stability: The interface of this method is not expected to change, though new behaviour might be added in a backwards-compatible manner.

Example:

my ($type, $value) = $self->next_token;
if ($type != $type->IDENT) {
    die "expected IDENT";
}

I tipi sono ancora lì, sebbene siano oscurati dalla descrizione in testo semplice. Io personalmente lo trovo soddisfacente, ma la firma del tipo corrispondente per una versione puramente funzionale sarebbe qualcosa come

next_token :: ParserState -> Try (ParserState, TokenId, String)
-- where type Try 'a = Either 'a Exception

Infine, se la documentazione di riferimento non è sufficientemente precisa, guarderò il codice sorgente. Molti programmatori non prendono seriamente la documentazione scritta e dimenticheranno di menzionare le informazioni di base, come il tipo di input accettato e quello che verrà fatto sugli errori.

Ovviamente, iniziando con la documentazione di riferimento, o iniziando a usare un sistema senza sapere nulla al riguardo, sarà sempre fonte di confusione. Pertanto, i sistemi di guida integrati come help(symbol) di Python non sono in genere sufficienti per costruire una comprensione iniziale di un sistema. Fortunatamente, molti progetti ospitano la loro documentazione sul loro sito Web in modo da poter leggere comodamente i loro documenti di panoramica.

    
risposta data 04.09.2015 - 23:41
fonte

Leggi altre domande sui tag