lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Solution for including a file only once


From: Michael J. O'Donnell
Subject: Solution for including a file only once
Date: Sat, 06 Feb 2010 21:51:19 -0600
User-agent: Thunderbird 2.0.0.23 (X11/20090817)

I *think* that I have the essential solution to include a file exactly
once, no matter how many times it is mentioned. That is, with the
following definition,

    \includeIfAbsent "MyFile.ly"

should copy in MyFile.ly, just as though you had written

    \include "MyFile.ly"

unless an inclusion (either through \include or through
\includeIfAbsent) has already started (and usually finished). If there
is a circular path of \includes, LilyPond appears to enter an infinite
loop, but \includeAbsent will break a cycle. That's why it's important
that I said "unless an inclusion ... has already *started*," rather than
"already happened."

The sweat here involved avoiding any preparatory code to enable the
mechanism. You need nothing more than the definition of includeIfAbsent.

I'm not sure how either \include or \includeIfAbsent behave inside a
context. It's probably not a good idea to use either one except at the
outermost level---inner stuff should usually be done with variables.
But, it would be cool if someone tested the possibility.

I will join the developer list, and introduce the idea there. I think
some such thing should probably be added as a standard function.

Notice that I let the file *calling* for inclusion control whether it
wants to allow multiple inclusions or not. Some systems, including the C
preprocessor, put a guard in the included file, disabling its inclusion
if it has already appeared. I think that I like this form (which
corresponds pretty well to "require" in some languages, but I've
forgotten which ones) better. I think that the guard within a file is
not hard to implement by a similar method.

There is a chance, very small I hope, that the string I used for a
file's guard could be introduced elsewhere, gumming things up. E.g., if
someone wants to have guards within the include files, as well as within
the including files, the names need to be different.

-----------------------------------------------------------------------------------------

includeIfAbsent =

#(define-music-function (parser location fileName) (string?)

  (let ((guardName (string-append "Already Got " fileName)))

    (if (not (defined? (string->symbol guardName)))
      (begin

        (primitive-eval (list 'define (string->symbol guardName) #t))

        #{ \include $fileName #}

      )

      #{ #}

    )
  )
)

--------------------------------------------------------------------------------------------------------

Cheerio,

Mike O'Donnell





reply via email to

[Prev in Thread] Current Thread [Next in Thread]