• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: AS Library Question
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AS Library Question


  • Subject: Re: AS Library Question
  • From: has <email@hidden>
  • Date: Wed, 16 Dec 2015 15:54:17 +0000

Shane Stanley wrote:

> On 16 Dec 2015, at 10:31 AM, Stan Cleveland <email@hidden> wrote:
>>
>> The libraries I use are custom-made for the work here.
>
> [...]
>
> The solution is to basically to be aware of it, and probably avoid properties within libraries where they're not really needed. And you can do things like add some kind of initialization handler that scripts should run first before they call others.

Not a great idea, as now you've got several scripts contesting over who set what last. Bear in mind that OSA isn't just about running scripts in simple batch-processing; it can also load and persist scripts and repeatedly call their handlers over time.


If library code needs to be stateful, use OOP, e.g.:

-- Foo.scpt library:

on makeFoo()
    script Foo
        property someState : ...

        on someCommand()
            ...
        end someCommand
    end script
end makeFoo

-- your script:

set myFoo to makeFoo() of script "Foo" -- create a new Foo object to reuse throughout your own code
someCommand() of myFoo


Another possibility is to do:

copy myLib to script "SharedLib"

which does a deep copy of the original loaded library, giving your script its own personal copy with its own private state. However, that probably won't work recursively (i.e. if the library you copied itself uses other libraries, those will probably remain shared).


A third option, and often the clearest and safest, is to create a record/script object in your top-level script that contains all the state your libraries need access to, and pass that object as an additional parameter to your library-based handlers when you call them. Bit tedious (since you may be passing the record through lots of handlers that don't need it just to make it available to the few that do) but at least it makes all these dependencies absolutely explicit.


I suppose if you were really desperate for a 'reliable' library loader (or just don't fancy rewriting your existing AM Loader-based systems to use AS's loader), you could even turn AM Loader into an AS library itself. The Loader object itself works well enough (if you don't mind writing lots of grotty `importLib()` boilerplate), and uses `load script` so avoids any hidden sharing with unrelated scripts. As I said in my previous post, the big technical weakness of AM Loader is that it relies on an osax to bootstrap it. The osax hides all the hassle of locating and loading the actual Loader object into your script behind a simple standard `property _Loader : AppleMods Loader` statement that goes at the top of your script. Third-party osaxen can be problematic to say the least these days, especially unmaintained ones, but the same stuff could be done just as easily by an AS library now.



> There are also cases where a persistent lib property makes sense. Something like a number formatter in an ASObjC-based lib, or simply where you scripts to share some info.

For the first, you'd probably use OOP to create and return your custom number formatter, which you then retain in your own code while using it. The one thing you might safely keep in such a library is a cache of, say, previously created instances, if creating those instances is a particularly expensive process (e.g. regex libraries often cache recently-parsed regular expressions so that if the user makes lots of find/replace calls with the same pattern string it can avoid the overhead of re-parsing that pattern every single time).

For the second, yeah, putting state such as preferences that are shared across your system in a library is easiest (caveat the usual concerns of safety, understandability, and maintainability from having lots of shared state across a system).


> And if you don't run scripts from within other apps, you can just ignores it.

Unsafe advice: even if your current usage avoids the problem, you should be including cautionary comments at the top of such libraries warning future maintainers that the library contains mutable state and thus will cause obscure and hard-to-identify malfunctions should two completely unrelated scripts try to load and use it at the same time. Otherwise if you later forget, or the code passes to someone else to maintain, or you choose to distribute those libraries to other users, it's just a booby trap *waiting to happen* should your or their usage patterns differ or change in future.

(And this is why I get so narked about sloppy thoughtless design by "responsible experts" building stuff intended for large numbers of regular users to work with. Users would *never* need to know nor care about such insanely technical problems had developers not created them in the first place. Hell, *no-one* should have to dredge through impenetrable warnings like these. But this is why I switched to other more reliable languages for all my serious automation work years ago: while they still have plenty issues of their own, at least their leaks don't spring anywhere as often or easily as AS's do.)


Regards,

has

--

p.s. Stan, the Apple mailing list archives definitely don't like you as I don't see your new post there either. Feel free to cc/email me directly if you've any specific questions you need answered.
_______________________________________________
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


  • Follow-Ups:
    • Re: AS Library Question
      • From: Shane Stanley <email@hidden>
  • Prev by Date: Re: [ANN] CalendarLib, improved Calendar scripting
  • Next by Date: Re: [ANN] CalendarLib, improved Calendar scripting
  • Previous by thread: Re: AS Library Question
  • Next by thread: Re: AS Library Question
  • Index(es):
    • Date
    • Thread