Module Loading System

I was impressed by the great effort that’s gone into http://applemods.sourceforge.net/ but it just seems too complicated and not portable enough for my needs. I wrote this system as a way to mimick the way that other programming languages use a search path for importing modules. I wanted to be able to store subroutine libraries on my system and have multi-file systems that can find each other while developing then be able to combine them all into an application bundle for shipping without changing any code. I’ve tried to make it as simple as possible.

(*
Name: 			MODULE IMPORT SYSTEM
Description:		Follows a search path to load script modules. 	
				1st search path: System module area - /Library/Scripts/Modules/ - Good place for library modules
				2nd search path: Caller's parent directory - For multi-file systems
				3rd search path: Caller application bundles's scripts folder - For application deployment
				This routine must be in every module that calls another module.
Instructions:		eg. set sys to import_module("sys")	
Date of last edit:	28/12/05
*)

on import_module(moduleName)
	--Search Path 1
	try
		set searchPath to (path to scripts folder from local domain as text) & "Modules:"
		set importModule to load script file (searchPath & moduleName & ".scpt")
		return importModule
	on error
		--Search Path 2
		try
			set pathToMe to path to me as text
			set posixPath to do shell script "dirname " & quoted form of POSIX path of pathToMe
			set searchPath to (POSIX file posixPath as text) & ":"
			set importModule to load script file (searchPath & moduleName & ".scpt")
			return importModule
		on error
			--Search Path 3
			try
				set searchPath to pathToMe & "Contents:Resources:Scripts:"
				set importModule to load script file (searchPath & moduleName & ".scpt")
				return importModule
			on error
				error "Module: " & moduleName & " wasn't found."
			end try
		end try
	end try
end import_module

If you want portability with AppleMods libraries, assuming you’ve used the standard header you can load them at compile-time by adding the line:

property _ : __load__(_Loader's makeLoader())

You should also modify the first line of the header from:

property _Loader : run application "Loader"

to:

property _Loader : run application (get "Loader")

as AppleScript gets a bit tetchy otherwise when the Loader applet isn’t available.

Information on writing Loader-based libraries is currently a bit thin, but for now you’ll find basic documentation available on my site. It’s fairly comprehensive, though not as easy to follow as I’d like. (Although I do have plans.)

You’re right that Loader is a bit more complicated than ad-hoc solutions, but it was designed as a general-purpose library-loading system with the ability to resolve nested dependencies to any depth, so trades a bit of simplicity for added power. Mostly the current form just lacks refinement. It’ll never reduce to a 10-line piece of copy-n-paste code, so there’ll always be a place for that (unless Apple ever deign to fix the deficiency at source, of course). That said, I’m planning some improvements to submit to AM some time this year, so if you’d like to send me a list of shortcomings you’ve found, suggestions for improvements, etc. then please do as it’d be very useful.

Hi Hamish
The only criticisms I could make are the ones you’ve mentioned yourself. I think it’s an absolutely sterling effort and should be commended. This functionality really should be part of Vanilla Applescript. I imagine it was left out because Apple wanted to keep things simple to avoid scaring newbies. However, I think it’s slightly counterproductive because modularity is such a great aid to understandability and encourages good coding habits.
I was inspired by AppleMods to write this routine but came at it from the perspective of ‘How can I do this in the simplest way possible?’
I do intend to submit some of my libraries to AppleMods when I find the time because it really deserves the support from all of us.