2011-12-22 9 views
6

Occasionalmente ci piace esaminare in che modo determinate funzioni sono state definite (quando sono scritte in Mathematica) System`. Questa domanda riguarda il modo migliore per farlo.Qual è il modo migliore per leggere il codice della funzione già definita (in particolare dal contesto System`)?

punti da tenere a mente:

  • Di couse ReadProtected deve essere rimosso prima.

  • I build di solito devono essere utilizzati almeno una volta prima che vengano caricati nel kernel. Una semplice invocazione semplice di solito è sufficiente per questo quando hanno funzionalità estese (ad esempio attraverso le opzioni)?

  • Information (??) fornisce la definizione in un formato di difficile lettura (nessun rientro e tutti i nomi di contesto privati ​​preceduti). Qual è il modo migliore per sbarazzarsi dei nomi di contesto e ottenere il codice formattato?

    Un'idea per sbarazzarsi di determinati contesti è Block[{$ContextPath = Append[$ContextPath, "SomeContext`Private`"], Information[symbol]]. Il codice può essere formattato automaticamente usando Workbench. Rimangono alcuni problemi, ad es. Information non cita stringhe, impedendo che il codice possa essere copiato in Workbench.

In generale, mi interessa come la gente lo fanno, quali sono i metodi che usano per rendere il codice di comandi incorporati come facile da leggere il più possibile.

Caso di utilizzo: ad esempio, recentemente ho inserito il codice di RunThrough quando ho scoperto che semplicemente non funziona su Windows XP (risulta che non riesce a citare i nomi dei file temporanei quando il percorso contiene spazi).


Aggiornamento:It appears che ha usato per essere una funzione per le definizioni di stampa senza contesto preposto, Developer`ContextFreeForm, ma non funziona più nelle versioni più recenti.

+0

È possibile eliminare i nomi di contesto privati ​​inserendo il contesto prima di chiamare '?? '. – cah

risposta

7

Per quanto riguarda la pretty-printing: il seguente è un codice molto schematico che si basa sulla risposta di @ Mr.Wizard per mostrare che alcune semplici regole possono andare un lungo cammino verso il miglioramento della leggibilità del codice:

Internal`InheritedBlock[{RunThrough}, 
    Unprotect[RunThrough]; 
    ClearAttributes[RunThrough, ReadProtected]; 
    Block[{$ContextPath = Append[$ContextPath, "System`Dump`"]}, 
     With[{boxes = [email protected] DownValues[RunThrough]}, 
     CellPrint[Cell[BoxData[#], "Input"]] &[ 
      boxes /. 
      f_[left___, "\[RuleDelayed]", right___] :> 
       f[left, "\[RuleDelayed]", "\n", right] //. 
      { 
      RowBox[{left___, ";", next : Except["\n"], right___}] :> 
       RowBox[{left, ";", "\n", "\t", next, right}], 
      RowBox[{sc : ("Block" | "Module" | "With"), "[", 
       RowBox[{vars_, ",", body_}], "]"}] :> 
       RowBox[{sc, "[", RowBox[{vars, ",", "\n\t", body}], "]"}] 
      }]]]] 

Questo è sicuramente non è una soluzione generale (in particolare, non funziona bene su codice funzionale nidificazione senza molti separata dichiarazioni), ma sono sicuro che può essere migliorato e generalizzato senza troppi problemi per coprire molti casi s di interesse.

+0

Questo funziona molto bene per scopi pratici su questo esempio limitato! @ Mr.Wizard ho trovato una [visualizzazione interessante del codice del programma M] (http://taliesinb.net/quicksort-in-61-characters), sfortunatamente non fornisce il codice per produrlo. – Szabolcs

+0

@Szabolcs: interessante. Hai provato a contattare l'autore? –

+0

@ Mr.Wizard Sì, nessuna risposta finora. Ma è la stagione delle vacanze. – Szabolcs

5

Buona domanda, perché non credo di averlo visto ancora discusso.

Faccio essenzialmente la stessa cosa che hai delineato. È possibile ottenere un po 'diverso di stampa-out con Definition, e più informazioni con FullDefinition:

Unprotect[RunThrough]; 

ClearAttributes[RunThrough, ReadProtected] 

Block[{$ContextPath = Append[$ContextPath, "System`Dump`"]}, 
    Print @ FullDefinition @ RunThrough 
] 
+0

+1 Non sapevo che si potesse manipolare il percorso di contesto per raggiungere lo stesso obiettivo (di eliminare i nomi di contesto privati ​​anteposti). Ho sempre usato BeginContext.Penso che il resto della domanda sui PO valuti "come si stampa il codice Mathematica?" L'unico programma di formattazione del codice sorgente di cui sono a conoscenza è nel menu di scelta rapida di Wolfram Workbench. – cah

+0

@cah C'è un altro problema importante. Prova a copiare il codice 'RunThrough' su Workbench e vedrai che genera errori di sintassi. È perché le virgolette intorno alle stringhe non vengono stampate e questo contiene anche un paio di stringhe di soli spazi bianchi. Quindi la prossima cosa è: come ottenere la fonte su una forma pastosa? Il metodo '$ ContextPath' che ho menzionato anche nella mia domanda in caratteri piccoli. – Szabolcs

+0

@cah Ciò che 'Begin' e gli amici fanno è semplicemente modificare' $ ContextPath', nient'altro. – Szabolcs