Rick Gordon wrote:
> I have been working with AppleScript for a long time (though
still not at a level comparable to many on this list), and took up
_javascript_ for web/ebook work within the last couple of years, and
have found that just getting into it for a not-too-long while will
iron out a lot of the confusion, leaving me sometimes screaming for
AppleScript to do something as simply as can be done in _javascript_.
Having cut my teeth on AppleScript and later started using Python as
well, I share your pain. (It got so frustrating that I ended up
copying AppleScript's application scripting capabilities to Python,
which was a PITA to do but still a million times easier than the
reverse.:p)
> Random key takeaways (in no particular order of importance):
>
> 1) Practically speaking, "arrays" = "lists".
Yes. JS's 'Array' class is directly equivalent to AS's 'list' type.
However, in JXA, a JS array that contains multiple items is NOT the
same thing as an ObjectSpecifier that specifies multiple elements.
Where the _javascript_ for Automation release notes start babbling on
about "Element Arrays" and "Filtering Arrays", be aware that it's an
absolute sack of lies. (I'm pretty sure Chris Nebel's the one
responsible; if he'd like to try explaining his reasoning it would
be most enlightening for all of us.)
> 2) Declare all variables, whether you need to or not;
undeclared variables are automatically global; declared variables
are restricted to their scope (which mostly means between paired
brackets).
Best thing is to add the following line at the top of every script:
"use strict";
It looks kind of kludgy (because it is), but it tells newer
_javascript_ compilers to enforce some rules such as making sure all
variable declarations begin with `var`. _javascript_OSA, incidentally,
automatically adds the "use strict" flag to all scripts, so users
never need to do it themselves. JXA does not; just one of many
missed opportunities to make it less painful.
> 4) With blocks equal tell blocks, but with blocks are
considered bad form in modern JS (for reasons I won't bother with).
Well, roughly analogous. But their design is fundamentally flawed,
and they're banned in strict mode. Avoid them entirely. If you want
to reuse an ObjectSpecifier, just assign it to a variable; unlike
AppleScript, there's no "implicit get" behavior so it won't get
messed up.
> 6) Coercing data to the correct type is even more important
than in AS.
Depends what you mean by that. Also, I think you meant 'Casting'; I
know the docs tend to fudge the jargon, but 'coercion' is where the
conversion happens automatically while 'cast' is where the code
explicitly requests it. e.g.:
1 + "2" -- coercion
1 + ("2" as number) -- cast
The problem with JS and (to a slightly lesser extent) AS is that
they're way too sloppy about which coercions are allowed and where
they can occur. Comparisons can be particularly problematic if
operands types aren't strictly controlled, e.g. in AppleScript, it's
impossible to know how the following 'simple' test will behave for
different values of `x`:
x < 10
because the behavior alters radically according to the value's type:
"5" < 10 --> false(!)
5 < 10 --> true
Thus, unless you're already sure you know what type the value of `x`
will be, you need to add your own cast:
(x as number) < 10
_javascript_'s behavior is a bit different, but brings its own nasty
gotchas. In particular, be very wary of using the `==` operator,
because that will cast both operands to the same type before
comparing them; thus, for example:
0 == "0" // true
0 == false // true
null == undefined // true
Using `===` performs an exact comparison, which is more often what
you want:
0 === "0" // false
0 === false // false
null == undefined // false
> 7) _javascript_ is (in many, but not all ways) a "C-like"
language, so much of the syntax (though not necessarily the way it
works) is familiar to someone with some experience in C or Python.
Syntactically, sure: _javascript_ syntax is a straight rip-off of C
syntax, with all the ridiculously complicated punctuation, statement
vs _expression_ schizophrenia, stupid ambiguity and fault intolerance,
etc.
Semantically though, _javascript_ is no more nor less a "C-like"
language than AppleScript, Python, or any other Algol-descended
language. They're all much of a muchness there.
> 8) In InDesign at least, some things that require repeat loops
in AS can be done with a single statement.
There's no point comparing how Adobe's embedded _javascript_
interpreter (JSX) and _javascript_ for Automation (JXA) interact with
application objects, because they're using different interfaces.
- JSX talks to InDesign and other Adobe apps via an object-oriented
interface, similar to the venerable Document Object Model (DOM)
interface found in web browsers.
- JXA talks to applications via their Apple Event Object Model
(AEOM) interfaces, which uses Remote Procedural Calls (RPC) plus
simple relational queries. (It is _not_ OOP, though this is a common
misconception exacerbated further by Apple's own misleadingly worded
documentation.)
If you want to understand how JXA is _supposed_ to communicate with
scriptable apps, go download the _javascript_OSA zip file off the old
appscript website and spend some time playing with the JABDemo app
included in it. Type an application command into the top-left pane
in AppleScript syntax, run it, and the bottom pane will display the
equivalent _javascript_ (JOSA) syntax.
> All that said, I would LOVE to see an actual book (or at least,
a serious tutorial) on JS for AppleScripters. But googling
_javascript_ for coders will bring up some useful links.
Persuade Apple to produce a _javascript_ for Automation implementation
that isn't a piece of shit, and I will write that book. Honestly, I
would've *loved* to write that book, and it would've been a bloody
brilliant book too. Hell, I've been practising for the last 15 years
and know this stuff better than anyone else on the planet. But if
there's other one lesson I've learned in that time, it's that you
cannot build good work on top of bad work: you just end up with
another layer of bad.
And that's the real problem: JXA simply isn't good enough to be
worth writing a book about. Now, if the AppleScript team want to
accept and admit they fucked it up, and resolve to do it over again
right, I will be happy to write as much as it takes to help make
that happen.
Otherwise, I maintain my previous position: Apple should forget JXA
and return to their original (WWDC13) plan of having developers
embed _javascript_Core directly into their apps, and let users'
scripts talk directly to those apps' Cocoa APIs via JSCore's own
JS-ObjC bridge. It's not a great plan, but unlike this JXA shambles
it's one that thousands of app developers will enthusiastically
support, tens of thousands of _javascript_ users will be happy to use,
and will actually work right.
Regards,
has
--
Apple event bridges for Python/Ruby/ObjC
<http://appscript.sourceforge.net>
_javascript_ OSA component
<http://sourceforge.net/projects/appscript/files>
Learn AppleScript, 3rd edition
<http://www.apress.com/9781430223610>
|