Passing variables into script libraries

I have a series of script libraries (a string class, a file class, a date class, an OmniOutliner class, etc.) that call each other extensively. Originally, I would just have each class call whatever classes it needed when it was loaded, but this caused Stack Overflow (i.e. an infinite loop). So I tried creating a master classes class that is called whenever I need to load a class.

So in the top level document, I have:

set ClassCScpt to load script alias (((path to library folder) as text) & "Application Support:Applescript Classes:Classes Class.scpt")
ClassCScpt's new_Classes_class({"Application", "Project Time"}, {})
property classDebug : {}
property debugMode : true

The empty list is loadedCs, a variable to keep track of what classes had already been loaded, and not reload them.

Classes Class.scpt looks like this:

on new_Classes_class(classNameList, loadedCs)
	if classNameList contains "Application" then
		if loadedCs does not contain "AppC" then
			global AppC
			set filePath to ((path to library folder) as text) & "Application Support:Applescript Classes:Application Class.scpt"
			set AppCScpt to load script file filePath
			set loadedCs to loadedCs & "AppC"
			set AppC to AppCScpt's new_Application_class(loadedCs)
		end if
	end if
      -- repeat for each additional class
end new_Classes_class

The child classes look like this:


on new_Application_class(loadedCs)
	set filePath to ((path to library folder) as text) & "Application Support:Applescript Classes:Classes Class.scpt"
	set ClassCScpt to load script alias (filePath)
	global AppC, LogC, logIt, FileC, StrC
	if debugMode then set classDebug to classDebug & {{return & "loaded Application Class", loadedCs}}
	ClassCScpt's new_Classes_class({"Application", "Logging", "File", "String"}, loadedCs)
	script Application_class
--properties and subroutines here
	end script
end new_Application_class

I can’t find a way to make loadedCs truly global, which is why it is currently a local variable that is passed into the function call. But will all of the nested calls, I can’t tell if loadedCs is keeping track of everything that’s been loaded. It worked for a while, but now I’m getting a mysterious “StrC (the string class variable) is not defined” error when I attempt to load any of my classes, and I don’t even know where to start in figuring out why that’s happening. I tried setting up a global variable in the script that calls that classes and using that to track which classes are loading and in what order, but I just get a “debugMode is not defined” error.

I can’t help thinking that I must be going about this the wrong way. Can anyone suggest a better way, or a way to debug my tangled web of scripts (I actually have a debugging class, which works pretty well when I can load my classes.) Help.

Thank you,
Rebecca

Have you tried making loadedCs a top-level property?

While it’s not unusual for some libraries to use other libraries, you do want to avoid too much of that. If every single library calls every single other library, then it isn’t really modular code in the first place. So if that’s the case I’d recommend working on disentangling their dependencies first.

Beyond that, you probably want to use a better module loading system. I have one that’s due for release next month; email me if you want a copy (has dot temp3 over at virgin.net).

To hhas:
What I’m really trying to create here is reusable code, more than modular code. For example, the subroutine I call the most is one called get_alias(filePathOrAlias) that takes a file path string or an alias and returns an alias. The idea is that you can give it anything that can be turned into an alias, and it will return an alias. I don’t want to have to copy and paste this a bunch of places. I want to be able to code it once, and use that everywhere. Then, if I discover that it needs an update, I can update it one place.

To Shane Stanley:
I tried that, but I keep getting a “loadedCs is not defined” error, I think because Classes Class.scpt is being loaded repeatedly (hence resetting the variable). That’s the working hypothesis, anyway.

On a related note, how much of a performance penalty am I paying for loading subroutines I don’t actually use?

That would be the point of using libraries. Like I say though, it sounds like you’ve pretty heavy inter-dependencies, so you should look at trying to reduce those if possible (otherwise, you’d be as well just pasting the whole lot into one large shared library) and/or using a more capable module loading system. Writing a good library loader isn’t too hard if you already know how to do it, but if you don’t then I would suggest using an existing one.

Trivial. Locating files and resolving dependencies will be the slower bit, and unless the main part of your script is very short then the library loading process as a whole is unlikely to be a major bottleneck. If in doubt, use a timing osax to profile the main sections of your code.