Autor Thema: Wie werden Lilypond/Scheme Skripte debugged ?  (Gelesen 2621 mal)

mgd

  • Member
Wie werden Lilypond/Scheme Skripte debugged ?
« am: Montag, 18. Mai 2015, 18:30 »
Hallo Forum,

bei dem Versuch den genauen Algorithmus in einem Skript für mein von Harm so vortrefflich gelöstes Markup Problem zu verstehen bin ich darauf gestoßen, dass ich nicht weiß, wie man genau Lilypond/Scheme Skripte debuggen kann.

Aus anderen Programmierumgebungen bin ich es gewohnt zur Not einfach an bestimmten Stellen im Programm Log-Anweisungen in das Programm zu schreiben und mit ihnen den Wert von Variablen, Listen oder auch komplexen Datenstrukturen auszugeben (auf die Konsole oder eine separate Datei). So entstehen dann Traces, mit denen ich im Zweifel den exakten Ablauf nachvollziehen kann.

Gibt es so etwas auch für Lilypond/Scheme ? Und wo ?
Oder was macht man alternativ ?

Liebe Grüße,
Michael

martinmagtenor

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #1 am: Montag, 18. Mai 2015, 23:16 »
Hallo Michael,

keine ganz einfache Frage für dieses Forum.

Ohne Anspruch auf Vollständigkeit:
  • natürlich kann man auch mit Guile/Scheme/Lilypond debuggen. Schau Dir mal in der Lilypond-Installation im Ordner ly die Datei guile-debugger.ly an. (Anmerkung: keine eigene Erfahrung damit, => Entwickler-Foren).
  • In der Kommandozeile kann man log-level aktivieren (--loglevel=level, mit level aus NONE, ERROR, WARNING, BASIC, PROGRESS, INFO (Standard) und DEBUG, siehe auch --help). Und es gibt Lilypond-Befehle um entsprechende Meldungen zu erzeugen, z.B. (ly:debug (format #f "Meldungstext name=~s" name)). Da stehen einem Formatierungsplatzhalter ähnlich wie in vielen anderen Sprachen (C, Perl, ...) zur Verfügung, nur dass eben anstelle des %-Zeichens die Tilde verwendet wird um einen Platzhalter einzuleiten.
  • Und dann gibt es noch das einfache (display "Hello world.\n")

Und dann noch ein Tipp: lilypond bringt mit der Sandbox eine einfache Kommandozeilenumgebung mit, eigentlich ein Guile-Prompt. Dieser eignet sich sehr gut elementare Scheme-Konstrukte auszuprobieren, ohne das ganze Lilypond-Gedöns darum herum. Im Prinzip gilt, eine Liste ist eine Liste und was der Inhalt ist, ist egal wenn es um den Umgang mit der Liste geht.

Aus Deiner direkten Frage schließe ich auf eine gewisse einschlägige Erfahrung ...

Grüße
  Martin

mgd

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #2 am: Dienstag, 19. Mai 2015, 00:58 »
Vielen Dank Martin,

das bringt mich deutlich weiter :)

(display listvar) war mein erster Versuch. In einer lilypond Sandbox Kommandozeileumgebung klappt das auch, aber in lilypond innerhalb einer Scheme Funktion in einem "normalen" lilypondfile liefert das keinen für mich erkennbaren Output. Oder ich benutze das einfach noch richtig für diesen Zweck.

Dein Hinweis auf die Formatstrings ist sehr hilfreich. Die Referenz in der Lilypond Doku ist da extrem knapp und war in diesem Punkt für mich nicht verständlich. Das ist jetzt klarer.

Mit guile-debugger.ly werde ich mal ein wenig experimentieren. Das ist vermutlich das, was ich eigentlich suche :)

Zitat
Aus Deiner direkten Frage schließe ich auf eine gewisse einschlägige Erfahrung ...

Korrekt.

Vielen Dank,
Michael

Arnold

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #3 am: Dienstag, 19. Mai 2015, 09:17 »
Ich benutze das »Spur-Ausgeben« meistens in einem Konstrukt wie
(for-each display (list "\n" ... ))und Lilypond in der Kommandozeile (also Ausgabe ist hier die Standardausgabe auf die Konsole).

Leider ist unter Windows der von Lilypond benutzte UTF-8-Zeichensatz ein wenig ein Fremdkörper. Deshalb habe ich mir ein C-Programm als Hülle geschreiben, welches die beiden Ausgabe-Streams (stdout und errout) in Pipes umleitet, diese als UTF-8 interpretiert, und als UTF-16 am Bildschirm ausgibt. Zuvor wird noch die Textkonsole den Codeset 65001 (UTF-8) umgeschaltet. Nachteilig bei diesem Programm ist, daß die zeichliche Synchronisation von stdout und errout verloren geht, dafür aber schreibe ich die errout-Texte in roter Farbe und die stdout-Texte in gelb - so finde ich meine Informationen schneller.

Arnold

erich

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #4 am: Dienstag, 19. Mai 2015, 10:00 »
Hallo, Michael

ich benutze frescobaldi (ob das unter Windows verfügbar ist, weiß ich nicht) und zur Ausgabe verwende ich in der Regel display-scheme-music gff. eingebunden in eine (begin . . . .)-Anweisung

Gruß
Erich

fugenkomponist

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #5 am: Dienstag, 19. Mai 2015, 20:17 »
semi-off-topic: Ja, Frescobaldi gibts für Linux, Mac OS und Windows.

harm6

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #6 am: Dienstag, 19. Mai 2015, 23:17 »
DISPLAYFUNKTIONEN

Direkt in guile (aber natürlich auch für guile in .ly-files):

display, write, format
pretty-print, mein Favorit, benötigt aber (use-modules (ice-9 pretty-print))
write-line, benötigt aber (use-modules (ice-9 rdelim))

oder Du kannst selbst was schreiben, z.B.:
\version "2.19.4"

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% writing info in a new file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


#(define* ((my-write #:optional (port (current-output-port))
                                (option "a") ;; or "w"
                                (write-proc display))
                     arg)
;; my-write is meant as a general custom-definition of write/display etc
;; to make other custom-definitions possible quite easily
;;
;; optional arguments are
;; port       - defaults to the terminal on most systems
;;                   can be set to a file-name-string
;;      option     - default "a" means the output is appended
;;      "w" means the file content will be overriden.
;;                   Only used if port is not the default
;;      write-proc - defaults to display
;;      other possible settings are write or
;;      pretty-print (with the need to use the relevant modules)
;;
;; (my-write) without any specification is pretty much the same as display with
;; an added (newline)
;; Also, see 'write-line'
                 
  (let* ((port (if (eq? (current-output-port) port)
                   port
                   (open-file port option))))
    (write-proc arg port)
    (newline port)
    (if (not (eq? (current-output-port) port))
        (close port))))
       
%% Example-definition:
% Need to set the following to make pretty-print possible
#(use-modules (ice-9 pretty-print))

#(define (write-to-log arg)
((my-write "log.txt" "a" pretty-print) arg))


%% EXAMPLES

#(write-to-log  "blabla")

%#(write-to-log all-user-grob-properties)
(hab' ich vor einiger Zeit mal geschrieben)

In LilyPond:

für den Einsatz mit LilyPond-Syntax

\displayMusic
\displayLilyMusic
\displayScheme
recht neu und wenig bekannt:
value->lily-string
#(use-modules (scm display-lily))

#(display (value->lily-string #{ c'1 #} parser ))

für den Einsatz mit guile in .ly-files

write-me (aus lily-library.scm)
display-scheme-music


Wahrscheinlich habe ich noch etliche display-Funktionen vergessen ...

Damit bin ich immer klar gekommen, wenn ich eigene Funktionen debuggen wollte, bzw fremde zu verstehen suchte.

Tatschlich habe ich noch nie einen Blick in guile-debugger.ly geworfen (sollte ich mal ...)

loglevel=level ist natürlich für andere Sachen durchaus sehr sinnvoll


HTH,
  Harm


mgd

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #7 am: Mittwoch, 20. Mai 2015, 02:53 »
Hmm...das liest sich alles sehr logisch und entspricht auch exakt dem, was ich erwarten würde.

Offenbar hänge ich an etwas sehr banalem und bin zu vernagelt, das Problem zu sehen. Das folgende Skript ist eine sehr verkürzte Fassung eines Skriptes von Harm aus einem anderen Topic (das ich im Detail zu verstehen suche).

\version "2.19.20"

#(define-markup-command (emphasize layout props strg)(string?)
#:properties ((indicator "*"))
  (let* ((mrkp strg)
         (display "strg=") (display strg) (display "\n")
        )
    (interpret-markup layout props mrkp)))

\markup
  \rounded-box
  \emphasize #"a*äö*de*frü*"

Meine Erwartung ist, die diversen (display ...) schreiben mir irgendetwas auf die Konsole. Ich sehe indessen keinen Output, weder unter Linux in Frescobaldi, noch direkt in einer bash.

Ändere ich das Skript derart, vor dem (let* ein (begin einzufügen, so wie hier:
\version "2.19.20"

#(define-markup-command (emphasize layout props strg)(string?)
#:properties ((indicator "*"))
(begin (display "begin strg=") (display strg) (display "\n")

  (let* ((mrkp strg)
         (display "strg=") (display strg) (display "\n")
        )
    (interpret-markup layout props mrkp))))

\markup
  \rounded-box
  \emphasize #"a*äö*de*frü*"

dann sehe ich auf der Konsole den String "begin strg=a*äö*de*frü*", wenngleich er erst sehr spät erscheint, nämlich nachdem die Verarbeitung der Funktion lange abgeschlossen ist. Würden also dort in einem komplexeren Fall irgendwelche Fehlermeldungen oder Warnungen ausgegeben, dann wären die von diesem Aufruftrace vollkommen getrennt und nur bedingt hilfreich.

Was mache ich falsch, bzw. wo liegt mein Denkfehler ?
Oder was muss ich anders einstellen, um das gewünschte Result/Verhalten zu erzielen ?

Etwas ratlos und wie immer dankbar für jeden Hinweis,
Michael

harm6

  • Member
Re: Wie werden Lilypond/Scheme Skripte debugged ?
« Antwort #8 am: Mittwoch, 20. Mai 2015, 10:45 »
Bin in Eile, so nur ganz kurz:

Eine Klammer ist falsch:

Zitat
\version "2.19.20"

#(define-markup-command (emphasize layout props strg)(string?)
#:properties ((indicator "*"))
  (let* ((mrkp strg)
         (display "strg=") (display strg) (display "\n")
        )
    (interpret-markup layout props mrkp)))

\markup
  \rounded-box
  \emphasize #"a*äö*de*frü*"


So sollte es klappen:

\version "2.19.20"

#(define-markup-command (emphasize layout props strg)(string?)
#:properties ((indicator "*"))
  (let* ((mrkp strg))
         (display "strg=") (display strg) (display "\n")
       
    (interpret-markup layout props mrkp)))

\markup
  \rounded-box
  \emphasize #"a*äö*de*frü*"

Gruß,
  Harm