• 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: Why these errors?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why these errors?


  • Subject: Re: Why these errors?
  • From: has <email@hidden>
  • Date: Tue, 11 Feb 2014 00:01:08 +0000

Jon Pugh wrote:

>On Feb 10, 2014, at 4:53 AM, 2551 wrote:
>> Objective-C does this, but AppleScript isn't a true 'object-orientated' programming language, not least because its nature - to be an inter-application metalanguage rather than an application development language - doesn't lend itself to inheritance of class behaviour.

> Technically, this is completely wrong. AppleScript is a true object oriented language, with object inheritance of behavior and data.

You are correct, but with giant honking caveats: *only* native language objects are OO; the inter-process communication stuff is entirely RPC plus first-class queries. The gross confusion created by AppleScript's well-intentioned [1] obfuscation of local vs remote objects and the bridging between extends well into HP Lovecraftian realms of insanity.

Furthermore, AppleScript "inheritance" is very different to the inheritance mechanism found in most OO languages: AS actually uses message delegation, where each object in a delegation chain either handles the message itself if it recognizes it or forwards it to the next object up the chain (its "parent") if not. Given that AppleScript was designed, amongst other things, so that scripts could be loaded and executed by scriptable application, and even attached to specific objects (just as Hypertalk scripts attached to objects in Hypercard stacks), understanding this delegation mechanism is useful to all AppleScripters, regardless of whether they write fancy OO or plain old procedural code themselves.

IOW, you do not need to know or care that AppleScript is an object-oriented language in order to use it, nor do you even have to know what OO is. Indeed, I can tell you from having explained application scripting principles to many professional developers that prior knowledge of OOP is a giant hindrance to actually learning AS correctly, as superficial syntactic similarities and [mis]use of common jargon leads them to form major misconceptions about how it actually works. This is why non-programmers who don't really understand AppleScript make far better AppleScripters than highly skilled professional developers who profoundly *mis*understand it. (And that's all I have to say about that, as the rest involves tearing shreds off every Apple staff responsible for AppleScript since 1993.)


Anyway...

The OP's confusion is rooted in AppleScript's original design decision to have no less than *six* different syntaxes [2] for performing the same damned operation: a message send.

Indeed, you won't find a single AppleScript user who hasn't suffered this particular confusion at some stage. Eventually they learn through word of mouth or whatever to add a 'my' keyword in front of their command; however, most almost certainly just apply it rote voodoo style because that's "just how you do things" in that particular use case, and very few (virtually none?) ever form a complete and accurate understanding of the actual mechanisms involved [3].

Because 'foo bar baz' and 'foo_bar(baz)' *look* fundamentally different, users naturally assume that they *are* different. From there, it's not unnatural to assume that, because the first command syntax 'belongs' to an application-provided handler and the second to a script-provided handler, their actions are going to be similarly associated: "application commands" will be handled by the application; "AppleScript commands" by the script.

Oh, the pedagogical pestilence of such careless misdirection. But just as things in AppleScript that look different may sometimes be the same, one can't automatically assume that things that look the same must be identical, or that things are inherently related just because they appear in a common format style. The fact that a particular command's syntax comes from an application and the handler for the command is also found in that application doesn't mean AppleScript will naturally send that command to the application: it'll send it wherever you tell it to send it, and if it goes to the wrong place then that's your fault for telling it wrong.

In truth, everything you'll ever hear about "application commands" versus "AppleScript commands" is a completely false distinction. In the AppleScript world there's just commands. Plus - tragically - half a dozen different crazy syntaxes and a load of other distractions to smother this very simple, utterly fundamental concept in rampant misdirection and endless confusion.

In absence of further information, a command's destination is determined by the default target object set by its current context. Every script [object] defines a default target, which is itself. When you issue a command within a script object, it is normally received again immediately by the script object, which will handle it itself if it contains a handler of the same name, or else delegate it to its parent if it doesn't. This delegation mechanism is why you can write a script like this in AS Editor:

    count documents

Run it, and you'll get back the number of open editor documents: at some point along the delegation chain, the unhandled message gets sent to the host application to see if it knows how to handle it. (I may have once figured out the exact order of events, but've long since forgotten.)

Of course, if you're so uncouth as to then add a 'count' handler to this script:

    on count obj
        say "poop"
    end

then you're probably twelve and deserve what you get. Although it will also help illustrate how message dispatch works, and also help reinforce the point that how/where command/handler syntax is defined has zero effect on where messages are dispatched to.

AppleScript users normally use native identifiers when naming their own handlers [4], so will typically write stuff like:

    on foo_bar(myVar)
        ...
    end

    foo_bar("baz")

This doesn't mean most ASers actually understand the details of operation, but only that they've mastered an established pattern for constructing a particular task. They assume the local 'foo_bar' handler will handle the local 'foo_bar' command, not because there's some mercilessly logical but invisible runtime dispatch mechanism at work, but simply because they both use the same visible syntactic form and the names match up.

However, you can just as easily create a *remote* stay-open applet with a handler [5] named 'foo_bar' that takes a single positional parameter, then call it from your *local* script like this:

    foo_bar("baz") of application "My Applet"

although a more commonly used construct is:

    tell application "My Applet"
        foo_bar("baz")
    end

which brings us to AppleScript's most used and least well understood feature: the 'tell' statement. Ignoring its various unholy hidden "features", such as its delightful ability to inject all manner of randomly evil keywords into the AppleScript namespace, the 'tell' statement only has one genuine purpose: to set a new default target object to be used within the context of that statement block.

The middle line of the above script says "send the message foo_bar", but because it doesn't state *which* object to send it to, AppleScript simply sends it to the default target object, whatever that currently is. It works because the 'tell' statement specifies a new default target to be used within the scope of that statement block. In this case, that new target is an instance of AppleScript's built-in 'application' type, created by the 'application SELECTOR' specifier[6].

However, the current default target is only used when you don't specify an explicit target yourself. For example, to explicitly specify the current script as the command's target:

    tell application "My Applet"
        foo_bar("baz") of me
    end

Or you could just use another 'tell' block to declare a new default target, of course:

    tell application "My Applet"
        tell me
            foo_bar("baz")
        end
    end

AppleScript maintains [a reference to] the current script [object] in its built-in 'me' variable, so what the middle line now says is "send the foo_bar message to the current script", and since it's not needed here the surrounding 'tell' block is simply ignored. And since AppleScript just looooves its synonyms and homonyms, it allows you to write 'my X' as a straight synonym for 'X of me'.

Hence the "Put 'my' Before the Name" mantra, handed down by the wise men of one generation to the next in a grand old tradition whose true meaningful origins are long since lost in the mists of time...

And so it goes. But hey, AppleScript did make me the person I am now [7], which you can take as you will. <g>

Regards,

has

--

[1] What roads to Hell are paved with.

[2] 10.9 goes one better: AS now has seven!

[3] Like XML and income tax, if you *think* you understand AppleScript you almost certainly *don't*. Heck, I'm one of the very, very few who has made it all the way to *true enlightenment*, and if you ask me to explain it back to you won't get much more out of me than "Ph'nglui Mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn." (Which possibly translates as "Dr Cook is grading assignments next semester", though I may be wrong.)

[4] As demonstrated, using identifiers as handler names in AppleScript code is not actually a requirement, but it's a good convention to follow since injecting even more randomly-defined keywords into the AppleScript namespace is just asking to cause trouble. (Thankfully, previous versions of AppleScript didn't make it at all easy to do so anyway, while politeness prevents me saying precisely what I think about 10.9's new library system encouraging it...)

[5] Known as a "script server" in established AppleScript parlance, thereby further compounding the illusion of differences and divisions where there are none. I swear, somewhere in Hell there's a 10th Circle reserved just for software developers who keep making up clever and unique naming schemes for everything. And directly beneath, the 11th Circle - which is where all the hapless designers of "end-user programmer languages" ultimately go. :p

[6] I won't get into the full gory details of how object specifiers are evaluated, nor some of the extra tricks AS uses to decide a command's target when it's written in keyword-based syntax, lest folks here start going all head-splodey.

[7] I meant, professional software developer and creator and purveyor of fine end-user languages to our graphicks industrees. (Anything else is COMPLETELY incidental.)

_______________________________________________
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:
    • [Related] William Cook
      • From: has <email@hidden>
    • Re: Why these errors?
      • From: Shane Stanley <email@hidden>
  • Prev by Date: choose file default location in OS X 10.8
  • Next by Date: Re: Why these errors?
  • Previous by thread: Re: Why these errors?
  • Next by thread: Re: Why these errors?
  • Index(es):
    • Date
    • Thread