Deutsches Lilypond Forum (Archiv)
Allgemein => Fragen zu Funktionen => Thema gestartet von: Manuela am Dienstag, 23. August 2016, 08:05
-
Hi,
ich habe wieder mal ein triviales Problem, das mir Kopfzerbrechen bereitet.
Ich habe meine Keyboardprogramme weiter ausgebaut und möchte z.B eine Farbänderung per set! in Lily durchführen. Dafür habe ich eine Prozedur geschrieben, damit die Syntax einfacher wird.
#(define w-key-color (x11-color 'blue))
wColor=#(define-music-function (mycolor)
(symbol?)
#{
#(set! w-key-color (x11-color mycolor))
\void \displayMusic { c }
#} )
#(define (cColor)(set! w-key-color (x11-color mycolor)))
\wColor #'white
\cColor #'blue
wColor funktionert zwar, liefert jedoch eine Warnmeldung Warnung: keine Musik in der Partitur gefunden, cColor geht überhaupt nicht. Was mache ich falsch (sicher ein ganz blöder Fehler, ich ärgere mich so über mich)
-
\void \displayMusic { c }
Warnung: keine Musik in der Partitur gefunden
Ich hab keine Zeit es zu testen oder mich näher damit zu beschäftigen, aber \void sorgt dafür, dass das Ergebnis von \displayMusic { c }, also { c } verworfen wird. Daher vermutlich die Warnung.
-
Hallo Manuela,
scheme arbeitet beim Aufruf einer procedure intern mit Kopien der Argumente. Wenn Du eines dieser Argumente per set! veränderst so ist diese Veänderung auch nur intern sichtbar und somit verarbeitbar. Falls eines der Argumente besagter procedure vordefiniert ist, so wird diese Definition nicht durch set! geändert. Siehe:
#(define my-color (x11-color 'blue))
#(define (set-color target color)
(write-me "\ninternal-1---------------------------------- " target)
(set! target (x11-color color))
(write-me "internal-2---------------------------------- " target))
#(set-color my-color 'green)
#(write-me "my-color, set-color applied, but no changes-- " my-color)
Im Terminal:
internal-1---------------------------------- (0 0 1)
internal-2---------------------------------- (0 1 0)
my-color, set-color applied, but no changes-- (0 0 1)
Dafür müsstest Du ein macro via define-macro definieren.
#(define my-color (x11-color 'blue))
#(define-macro (set-color! target color)
;; nb output is unspecified
`(set! ,target (x11-color ,color)))
#(write-me "\nmy-color, original ------------------------------------- " my-color)
#(set-color! my-color 'green)
#(write-me "my-color, destructively changed ------------------------ " my-color)
Im Terminal:
my-color, original ------------------------------------- (0 0 1)
my-color, destructively changed ------------------------ (0 1 0)
Inwieweit das aus Musikfunktionen heraus klappt, habe ich nicht getestet.
Generell ist das destruktive neu setzen einer Variable durchaus mit Vorsicht zu geniessen...
Gruß,
Harm
-
scheme arbeitet beim Aufruf einer procedure intern mit Kopien der Argumente. Wenn Du eines dieser Argumente per set! veränderst so ist diese Veänderung auch nur intern sichtbar und somit verarbeitbar.
Hallo Harm und fugenkomponist,
danke für die Mühe, die ihr euch macht.
Ich bin wieder einmal an meiner eigenen Blödheit gescheitert, ich habe in der Definition schlichtweg vergessen, die Variable einzufügen.
Er hätte natürlich heißen müssen
#(define (cColor mycolor)(set! w-key-color (x11-color mycolor)))
Der Aufruf mit
#(cColor 'blue)
funktioniert jetzt, aber
\cColor #'grey70
geht nicht. Dafür müsste ich cColor m.E. als music-function definieren, was zur oben erwähnten Warnmeldung führt, da die Funktion keinen Output liefern, sondern nur die Variable ändern soll.
Harm, ich habe noch eine Frage zur Makrodefinition. Wenn ich z.B. nicht den Variablennamen, sondern white oder black übergeben will, was müsste ich machen? Folgendes funktioniert nicht:
#(define-macro (set-color! target color)
;; nb output is unspecified
`(let* ((keyfarbe (if (eq? ,target 'white) w-key-color b-key-color)))
(set! ,keyfarbe (x11-color ,color))))
Update: nach nochmaligem Studium des Lilypond-Scheme-Tutorials bin ich selbst drauf gekommen. Einfach define-music-function durch define-scheme-function ersetzen, die Funktion schaut dann so aus:
wColor=#(define-scheme-function (mycolor) (symbol?)
(set! w-key-color (x11-color mycolor)))
....
%% Aufruf:
\wColor #'LightCyan
-
Harm, ich habe noch eine Frage zur Makrodefinition. Wenn ich z.B. nicht den Variablennamen, sondern white oder black übergeben will, was müsste ich machen? Folgendes funktioniert nicht:
#(define-macro (set-color! target color)
;; nb output is unspecified
`(let* ((keyfarbe (if (eq? ,target 'white) w-key-color b-key-color)))
(set! ,keyfarbe (x11-color ,color))))
Ähm, ich habe keine Ahnung was Du versuchst.
Selbst wenn die Syntax von set-color! richtig wäre, so würdest Du doch eine lokale/interne Variable setzen und dafür brauchst Du das macro doch gar nicht...
Einfach define-music-function durch define-scheme-function ersetzen,
Nimm besser define-void-function, die ist gerade auf solche Anwendungen spezialisiert.
Gruß,
Harm
P.S.
Update: [...]
Eine Bitte.
Ändere Deine Beiträge nur um Tippfehler und ähnliches zu korrigieren. Nicht jedoch um wesentlich neues mitzuteilen. Eine Änderung Deines Beitrags wird nicht als neue Nachricht verkündet.
Ich habe deshalb schon mehrmals wesentliche Informationen bei weitem zu spät bemerkt, zumindest soweit ich weiß. Mit Sicherheit habe ich manches Edit/Update auch überhaupt nicht mitbekommen.
-
Selbst wenn die Syntax von set-color! richtig wäre, so würdest Du doch eine lokale/interne Variable setzen und dafür brauchst Du das macro doch gar nicht...
P.S.
Update: [...]
Eine Bitte.
Ändere Deine Beiträge nur um Tippfehler und ähnliches zu korrigieren. Nicht jedoch um wesentlich neues mitzuteilen. Eine Änderung Deines Beitrags wird nicht als neue Nachricht verkündet.
Ich habe deshalb schon mehrmals wesentliche Informationen bei weitem zu spät bemerkt, zumindest soweit ich weiß. Mit Sicherheit habe ich manches Edit/Update auch überhaupt nicht mitbekommen.
Du hast recht, es ist kein Makro notwendig.
Ok, ich dachte, es ist nicht so gut, wenn ich in einem Thread mehrere Nachrichten hintereinander verfasse, werde ich aber in Zukunft so handhaben.