Hello David, > Neither surprising nor an edge case.
I would say it is quite surprising for most users, and definitely an edge case.
It is essentially a case of `\applyContext` silently behaving differently when
the Voice context was not created yet. And even you are getting this wrong:
> That's because at the point of the first call, you haven't yet descended
> into a Voice or even Staff context from the surrounding Score context.
> So \applyContext prints the Stem.length setting for the Score context
> which has not been changed (you only changed the default for every
> bottom context).
>
> If you want to override Stem.length at the Score level, either write
>
> \override Score.Stem.length = ...
>
> in your \layout block, or write things like described in the docs,
> namely
>
> \layout {
> \context {
> \Score
> \override Stem.length = ...
> }
> }
This creates the same output, because the top context is not Score, but
Global. At the point in question not even a score context exists, so this is
called in the global context. This we can also see when doing
```
testfn =
#(lambda (context)
(display context)
(newline))
\score {
{
\applyContext #testfn
4
\applyContext #testfn
}
}
```
which will display
> #<Global_context Global () >
> #<Context Voice () >
So actually you’d have to do
```\override Global.Stem.length = #0```
or
```\context { \Global ... }```
This makes me wonder one more time if `\applyContext` should take an optional
context argument, allowing to specify which context this should run on, and
fail if this context is not found, such as in this mockup:
```
myApplyContext =
#(define-music-function (name id proc)
((symbol? #f) (string? #f) procedure?)
(define (context-find name id ctx)
(and
ctx
(if (and (equal? (ly:context-name ctx) name)
(or (not id) (equal? (ly:context-id ctx) id)))
ctx
(context-find name id (ly:context-parent ctx)))))
(applyContext
(if name
(lambda (ctx)
(let ((context (context-find name id ctx)))
(if context
(proc context)
(ly:warning-located
(apply format #f "~a:~a:~a:~a" (ly:input-file-line-char-column
(*location*)))
"Context ~a not found"
(if id (format #f "~a = ~a" name id) name)))))
proc)))
testfn =
#(lambda (context)
(display context)
(display ", ")
(display (ly:context-name context))
(display ", ")
(display (ly:context-id context))
(newline))
{ \myApplyContext #testfn 4 \myApplyContext #testfn 4 \myApplyContext Global
#testfn }
\new StaffGroup = "outer" \new StaffGroup = "inner" \new Staff
{ s4 \myApplyContext StaffGroup #testfn s4 \myApplyContext StaffGroup "outer"
#testfn }
```
which would in the given case
```
displayStemLength =
#(lambda (context)
(let* ((grob-def (ly:context-grob-definition context 'Stem))
(length (ly:assoc-get 'length grob-def)))
(display "+ ")
(display length)
(newline)))
\score {
\relative c'' {
\myApplyContext Voice #displayStemLength
g4
\myApplyContext Voice #displayStemLength
g
}
\layout {
\override Stem.length = #0
}
}
```
issue a warning for the first call
> [location]: Warning: Context Voice not found
Cheers,
Valentin
signature.asc
Description: This is a digitally signed message part.
