Shane Stanleywrote:
On 16 Jan 2016, at 23:39, has <email@hidden> wrote:
>
> Shane Stanley wrote:
> >> Does ASOC support return-by-argument, e.g. for getting NSError**?
> >
> > set {theResult, theError} to (theFileManager's copyItemAtURL:theSourceURL toURL:theDestURL |error| :(reference))
>
> Thanks. Kinda wonky design though; wonder why ASOC doesn't just take an actual reference? What if it's an inout parameter - how do you pass a value in?
Someone once suggested it was based on what happened in another bridge; I don't know if that's true or not.
It looks like a bad imitation of PyObjC, which returns a tuple
containing the method's out/inout arguments in addition to its
result. Python doesn't have a 'reference' type, so it's an
understandable compromise. PyObjC still allows initial values to be
passed in though.
OTOH, AS does have a reference type, so it would've been logical for
ASOC to use that. Passing a type name (`reference`) to tell it to
change its return behavior is just weird. But eh, AppleScript.
I'm not sure about inout -- I can't say I've struck any cases where I've needed to do it. In XCode apps, you can use "contents of" when overriding methods that take pointers to pointers:
on dataOfType:typeName |error| :outError
set contents of outError to current application's NSError's ...
Huh. So it uses references when going from ObjC-to-AS. Weirdly
inconsistent.
The other downside is it doesn't work for methods that don't return a result. There aren't many, and most have workarounds, but there are exceptions.
Yuk. Fortunately, I'm only wrapping methods that return errors by
argument, so I should be okay.
> > Running NSTask in ASObjC is about on-par with do shell script time-wise.
>
> Yeah, I'm not bothered about that: everything in AppleScript [except AE dispatch] is dog-slow compared to other languages (e.g. Python's sort routine is 100x faster than mine, and stable to boot, so merely being "as fast as" is actually a pretty good deal).
I think it's an *excellent* result, considering. Speed-wise ASObjC generally only starts to lag when there's a lot going on, like large repeat loops. That's when it's time to look at wrapping a framework. BridgePlus's -colsToRows: is a good example -- pass repetitive stuff to Objective-C where possible.
Passing data to ObjC is *only* practical when you know the data
types being passed across the bridge. If you don't know, or if you
know there are non-ASOC-compatible data types included (e.g.
records, references, lots of script objects), then you *have* to
keep it AS-side, otherwise ASOC will screw up that data and/or
crash. A few special-case optimizations might be possible - e.g.
`sort list` might automatically switch to using NSMutableArray when
given a list of numbers to sort (not sure about lists of text, as
ordering those needs to use AS's considering/ignoring blocks) - but
general-purpose libraries have to be super-conservative about what
they do with users' data because they just don't know enough about
it and can't risk mucking it up.
> The purpose of creating these libraries is to provide greater capability, robustness, and ease of use.
That's one of the reasons I have a problem with your approach: you're trying to serve three masters.
Curious statement - what's not to like about such objectives?
They're generally achievable within bread-and-butter libraries like
these, and are all just aspects of the same fundamental requirement:
usability. Sure performance is good to have too, but correctness has
to come first. And none of these libraries prevent users for using
ObjC directly when their use case permits it.
> The benefits of NSTask over `do shell script` are that it allows you to interact with a Unix-style process directly, piping data in and out, and to operate asynchronously as well as synchronously. (TBH, the TaskLib's kind of borderline - I'll ditch it if I decide it doesn't add sufficient value over what currently exists, but it'd be nice to get a decent prototype working first so I can properly judge it.)
Well you don't have to use a terminationHandler. But if you need to, why not put it in a framework?
I'm not keen on adding ObjC code to libraries (more code, more
complexity, more potential points of failure), but looks like it'll
be necessary in such cases. I think TaskLib will end up being set
aside as it's more important to get essential basics like TextLib,
DateLib, and ListLib done, and I don't want to spend much more time
on these libraries.
> And ideally I want something that isn't going to complain when a «class ocid» specifier is passed to it.
You need to be *very* careful with specifiers containing ocids.
Honestly, I'd be happy just to display them as specifiers for now.
Anyway, appreciate the advice.
Ta,
has
|