[Openmcl-devel] init-file mechanism cleanup?
Shannon Spires
svspire at sandia.gov
Mon May 16 22:45:36 PDT 2011
All-
I'd like to discuss the init-file mechanism in CCL and suggest an alternative to the current mechanism.
The current mechanism for specification of init-files in CCL is a mess:
-- It's inconsistent between #'save-application and #'build-application and the various application classes.
-- There are at least a couple of different ways to override it, some of which work as expected
and others of which don't.
Typically init-files are defined in an explicit method on the application class. This means that it's not easy to change them dynamically when doing a save-application.
The way #'save-application handles init-files now is to bind the arg in a closure that calls #'toplevel-function. That's not particularly bad, except that that mechanism is ignored if the user specifies a toplevel-function.
Worse, there are four different methods for toplevel-function, and all but one ignore the init-file argument. The one for cocoa-application is one of the methods that ignores it. Yet cocoa-applications actually pay attention to the init-file, and they don't allow you to override it (because of the way #'new-cocoa-listener-process works).
There is a variable called *load-lisp-init-file* which the #'toplevel-function method on lisp-development-system pays attention to but nobody else does. Most notably, #'new-cocoa-listener-process doesn't pay attention to it.
#'build-application doesn't even take an init-file argument. That's easy to fix, but even if you specify an argument to #'build-application such that it passes it to #'save-application, the :init-file arg is ignored. Why? Because #'new-cocoa-listener-process makes its own, separate decision about the init-file.
Here's my proposed solution to all this.
Modify #'build-application so it takes an :init-file argument.
Remove the init-file argument from all #'toplevel-function methods. All but one are
already ignoring it.
Change the #'toplevel-function method on lisp-development-system to do
(startup-ccl (ccl::application-init-file ccl::*application*))
instead of
(startup-ccl (and *load-lisp-init-file* init-file))
as it does now.
Keep the init-file argument to #'startup-ccl.
Leave #'new-cocoa-listener-process alone, since it's doing things right.
Add a slot called init-file to application class with an accessor called application-init-file. When an init-file is explicitly specified to #'save-application or #'build-application, stick it into the init-file slot of the application object rather than juggling it lexically.
Remove existing methods on #'application-init-file.
Add appropriate :initforms for the :init-file slot to class application.
Add two :around methods on application-init-file to wit:
(defmethod ccl::application-init-file :around ((a cocoa-application))
(unless (shift-key-now-p)
(call-next-method)))
(defmethod ccl::application-init-file :around ((a application))
(when *load-lisp-init-file*
(call-next-method)))
The upshot:
-- The old init-file behavior still works -- and works more consistently:
If *load-lisp-init-file* is nil, no init-file is loaded under any circumstances.
If *load-lisp-init-file* is true but the shift key is held down as a cocoa-application
starts, no init-file is loaded.
-- #'build-application now takes an :init-file arg like #'save-application, and it actually works.
-- It becomes easy to change an init file on the fly just by changing the slot value of
the init-file slot in the application object.
Questions:
What to do about *ccl-ide-init-file*?
Comments about this proposal?
Thanks,
Shannon Spires
More information about the Openmcl-devel
mailing list