Re: character of a string which is a number.
Re: character of a string which is a number.
- Subject: Re: character of a string which is a number.
- From: has <email@hidden>
- Date: Tue, 11 Oct 2005 19:04:50 +0100
Emmanuel wrote:
>Perplexing enough, what would you expect that line to return:
>
>0 + (character 50000 of "1234")
An error when resolving the reference, obviously. The rules by which the AppleScript interpreter decides when and where to automatically resolve a reference object are thorougly baroque and not documented outside of Apple, but let me put on my speculative hat and see if I can disentangle what's going on.
It's fair to assume that the AS interpreter always defers resolution of literal references for as long as possible. This makes sense as AS references really represent first-class queries that can be resolved by applications against their Apple Event Object Model (when the reference is given as a parameter to an application command), or (to a more limited extent) by the AS interpreter itself (when the reference is to some part of a local AS object such as a list or string). Therefore, when the AS interpreter encounters a literal reference in your code, it constructs the query object first and worries about resolving it later. Note that this is very different to how other languages evaluate conventional literal OO references (and a common source of confusion for folks coming to AS from those languages).
So now the question is: where in the AS interpreter does responsibility for resolving query objects fall?
Originally I suspected that the compiler inserted the relevant instruction at appropriate points when analysing the AST, but that hypothesis falls apart on closer inspection. e.g. In a command like 'foo(word 1)', the 'word 1' query is resolved at different locations depending on whether the command is handled by a local script handler or an application event handler, and the compiler has no way to know in advance which one it'll be. So forget that.
My current theory is that query resolution is left to the discretion of the individual sections of C code that the AS interpreter executes in response to each applicable bytecode instruction. For example, the C code that dispatches a command to a local handler is responsible for searching the parameter list for any query objects and resolve them before executing the handler code. The C code that dispatches a command as an Apple event is responsible for packing them into the event's parameter list as-is. And so on for the C code that corresponds to each AS operator (+, -, of, a ref to, as, etc.) and statement (if, repeat, etc.); each one is independently responsible for resolving, or not resolving, the query object passed to it. Now, I can't vouch for the correctness of this hypothesis (maybe a kindly AS engineer would like to confirm/deny?), but it seems to fit with observation so let's roll with it.
Going back to your original example:
0 + (character 50000 of "1234")
The above theory states that the part of the interpreter which evaluates the 'add' instruction receives the following objects as operands: an integer, 0, and a query, 'character 50000 of "1234"'. The first thing this code should do is check each operand is an integer or real, and if not ask the part of the interpreter responsible for performing type conversions to convert them to a number. I'm assuming AS maintains a big dispatch table of coercion handlers in much the same way as the Apple Event Manager does, so AS looks up a handler that performs query-to-number conversions (or it may be a query-to-anything handler; doesn't really matter here) and passes the 'character 50000 of "1234"' query to it.
Now, something like:
(character 3 of "1234") as number
works just fine, so we know such a coercion handler exists and returns the right result when given valid input. However, try executing:
(character 50000 of "1234") as number
and AS raises a coercion error (-1700) instead of a 'no such object' error (-1728). Unfortunately, this is normal behaviour for coercion handlers: if an operation fails for any reason they report a coercion error rather than the original error. (IIRC, the idea is to give other parties a chance to try the same conversion in other ways, in the hope they'll have better luck. It's just a pity this also serves to mask the original error.)
At this point, the coercion code ought to be reporting back to the 'add' code that things are a washout and that it should jump to the code that raises an AppleScript exception. It seems to manage this OK in other instances, e.g. '0 + {a:1}' reports exactly the coercion error it should, so I don't know why it's not doing so here. It seems incredibly careless that AS should suddenly lose an entire query object except for its root completely by accident. Also note that not all math operators make the same mistake: -, *, mod and div all produce different sorts of wrong answers, while / actually does the right thing and reports the expected coercion error.
But then, this is AppleScript we're talking about, and many brave men and women have run screaming into the night trying to fathom its mysterious, twisted depths, and short of a pit, a hose, and a captive AppleScript engineer I don't expect any of us 'outsiders' ever will. I'm sure the AS engineers will chip in with a definitive explanation if they really want to, and in the meantime I'm sure you know the way to the Radar bug database by now. ;)
Live long and prosper,
has
--
http://freespace.virgin.net/hamish.sanderson/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Applescript-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden