Re: Library Use Statement Question
Re: Library Use Statement Question
- Subject: Re: Library Use Statement Question
- From: has <email@hidden>
- Date: Tue, 24 May 2016 17:08:35 +0100
Deivy Petrescu wrote:
>> The technical term would be "import", but "load" is also okay.[1] A
library script is dynamically loaded[2] via OSALoadFile() when a `script
"NAME"` expression is evaluated, then hosted within an AS component
instance as a script object instance that persists for the lifetime of
that CI. AS then dispatches messages from your own script to the library
script much as it dispatches them within your own script (i.e. message
parameters and return values are passed as-is, not copied as they are in
OSAX/scriptable app commands).
>
> Import is good. However, thinking of Python, I don’t really know what
happens when you " from @ import * “. I mean, I know I get the namespace
of @ and I know that this is done at runtime, but I am not sure. I se it
and I know it works.
Python's `import NAME` statement imports a module (library) named NAME
by finding the file named NAME.py, compiles it into a module object
(similar to a script object), stores it within the interpreter for
reuse, and automatically binds that object to a variable named NAME
within your script. The `from NAME import *` variant likewise imports
the module, but instead of binding the module object to a single
variable instead binds all its top-level functions and variables
directly to your script.
From a usability POV, Python's `import SomeLib` is like using:
use SomeLib: script "SomeLib"
to import a NON-terminology-based AS library, or:
property SomeLib : a reference to script "SomeLib"`
which is safer and clearer in its intent (i.e. import the "SomeLib"
library at runtime and bind a reference to it to variable `SomeLib`, but
_don't_ import any terminology it might contain), while using:
use script "AnotherLib"
to import a terminology-based AS library is similar to using `from
AnotherLib import *`.
The difference, of course, is that Python lets you use either type of
import with any library, whereas in AS the behavior is dictated by the
library author and the user doesn't get much choice in the matter.
(About the only choice the user gets is between `use script "NAME"` vs
`tell script "NAME"`, which limits the injection of new terminology to
just the `tell` block instead of the entire script. Plus, of course,
writing and using Python libraries is cleaner and simpler because there
isn't any dictionary XMLs to screw about with or terminology conflicts
to troubleshoot.[1]
> As for load, unless I am mistaken, load script file would actually
load the whole “library" into the calling script, that is taking actual
disk space. I don’t think this happens with the libraries. That is mi
issue with loads
If you use:
property SomeLib : load script "/path/to/SomeLib.scpt"
to load a library into a top-level property, the resulting script object
exists within your own script; so, yes, if you then store that script
again (e.g. as SE applets automatically do) then that script object will
be stored to file along with the rest of your script's top-level state.
Though honestly a few extra KB or even MB of disk space is unlikely to
cause practical concerns on modern machines or broadband connections.
With `use script "SomeLib"` or `tell script "SomeLib"`, the library
script object lives completely outside your own script so isn't stored
when your script is. Although if you do want to bind it at compile-time,
then:
property SomeLib : script "SomeLib"
will bind a _copy_ of the script object directly to your script, at
which point your script owns that object again (though that's usually
not what you want as it means the script won't pick up a newer installed
version of the library unless/until it's explicitly recompiled and resaved).
Eh, but this is AppleScript: "There should always be a single, simple,
totally consistent, easy to understand, SANE way to do it" is virtually
its anti-motto.
>> use script "AnotherLib" -- import a terminology-based library
that defines an `another library command` handler
>> another library command documentRef -- dispatches `ALibCmnd`
message to TextEdit, not to script library as you'd expect!
>
> Does this contradict your statement (*) above? I thought the another
library command documentRef would send a message to the library, as (*)
indicates.
> May be I misunderstood something.
You'd think, but no. AS has a special rule when dispatching
*keyword-based commands that have a direct parameter*: first try sending
the message to the object given as its direct parameter, and only fall
back to dispatching to the object specified as its default target
(current script/`tell` block target) if that object doesn't know how to
handle it. In AS, most types of objects (numbers, strings, lists, etc)
don't know how to handle messages themselves, but there are a couple of
exceptions: script and application objects. Pass one of those objects
(or a direct/indirect reference to one) as your keyword-based command's
direct parameter, and AS dispatches the message to that instead.
That's, like, #35,276 on the List of Things the AS Documentation Never
Tells You, and it's even caught out a crusty old vet like me on more
than one occasion (https://github.com/hhas/applescript-stdlib) when
defining terminology-based commands whose direct parameter can be
'anything'.
Regards,
has
_______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users
This email sent to email@hidden