applescript parsing: list of record types

  • for one of my script commands specified in my sdef file, i've
    specified the direct parameter to be of type="my record type"
    list="yes" where "my record type" is defined in the sdef as a
    record-type element.

    and if i turn i AEDebugReceives, i can see the list of records coming
    in. however, cocoa scripting complains that it can't make the list
    into a "my record type".

    i've discovered that if i specify in my sdef to take a list of
    type="any", i can then get the data, but i get it as an aedesc, which
    i then have to parse myself. and the documentation in the script
    directory seen by the user is misleading.

    have i encountered a (known) limitation of cocoa scripting? or
    perhaps a bug? is there perhaps another way to write my sdef so that
    i don't have to parse the sdef myself? or is there perhaps some
    method i can/should override in NSScriptCommand to properly handle
    this?

    thanx,
    ken

    ps. i believe this is a cocoa problem, not an applescript problem;
    hence the posting here instead of some other list.
  • On 22 Oct 2007, at 17:14, Ken Victor wrote:

    > for one of my script commands specified in my sdef file, i've
    > specified the direct parameter to be of type="my record type"
    > list="yes" where "my record type" is defined in the sdef as a
    > record-type element.
    >
    > and if i turn i AEDebugReceives, i can see the list of records
    > coming in. however, cocoa scripting complains that it can't make
    > the list into a "my record type".
    >
    > i've discovered that if i specify in my sdef to take a list of
    > type="any", i can then get the data, but i get it as an aedesc,
    > which i then have to parse myself. and the documentation in the
    > script directory seen by the user is misleading.
    >
    > have i encountered a (known) limitation of cocoa scripting? or
    > perhaps a bug? is there perhaps another way to write my sdef so
    > that i don't have to parse the sdef myself? or is there perhaps
    > some method i can/should override in NSScriptCommand to properly
    > handle this?

    The only limitation I remember in this area (though I'm hardly an
    expert on the AppleScript <=> Cocoa side of things) is that you can't
    pass an arbitrary record from AppleScript to Cocoa without using
    type="any" because Cocoa has no way to map the record field names
    into strings for use a NSDictionary keys (remember, AppleScript uses
    four character codes, not strings).  At least, I think that's the
    problem I ran into...

    So, is your record type defined in your sdef file?  Is the syntax of
    your sdef file correct?

    You might be better asking on the applescript-implementors list
    (which I've copied on this reply); even though this is Cocoa related,
    you're still more likely I think to find help there than here.  Of
    course, I might be wrong :-)

    Kind regards,

    Alastair.

    --
    http://alastairs-place.net
  • Ken Victor wrote:

    > for one of my script commands specified in my sdef file, i've
    > specified the direct parameter to be of type="my record type"
    > list="yes" where "my record type" is defined in the sdef as a
    > record-type element.
    >
    > and if i turn i AEDebugReceives, i can see the list of records coming
    > in. however, cocoa scripting complains that it can't make the list
    > into a "my record type".

    Sounds like a bug in Cocoa Scripting. My bet is that when a list of
    values is specified in the sdef, it's unpacking the incoming event by
    getting the parameter (AEGetParamDesc) as typeXXXX, then extracting
    the item(s) in that list (AEGetNthDesc) as typeYYYY.

    For scalar AE types this will work fine as the Apple Event Manager
    includes an anything-to-single-item-list coercion handler, while for
    lists of lists it's effectively a non-issue as the default sdef types
    don't include 'list' so it's effectively impossible to say
    'type="list" list="yes"'.

    For record type descriptors it'll cause a great big mess, however, as
    the Apple Event Manager, for reasons only known to itself, also
    installs a default record-to-list coercion handler that performs a
    lossy, non-reversible conversion by stripping the record's key data
    and returning an AE list containing just the values. So that initial
    AEGetParamDesc call, instead of taking your record and wrapping it up
    as a single-item list before using AEGetNthDesc to extract the items
    in that list, is converting your record to a list and then trying to
    unpack its items as records.

    Dumb, but then, Cocoa Scripting was never the brightest bulb in the
    box, and the original engineer wasn't an AppleScript expert so
    wouldn't have been familiar with all the obscure and sometimes
    bizarre ins-and-outs of the Carbon Apple Event Manager and its modus
    operandi, such as the default presence of a stupid and reckless
    record-to-list coercion handler.

    The solution in this case would be to make Cocoa Scripting a bit
    smarter, so that if the sdef specifies 'list="yes"', it checks to see
    if a parameter is a record-type value before doing anything to it.
    i.e. Pseudocodish example:

    err = AEGetParamDesc(&event, key, typeWildCard, &param);
    if (AECheckIsRecordDesc(&param))
    err = AECreateList(NULL, 0, 0, &listDesc);
    err = AEPutDesc(&listDesc, 0, &param);
    else
    err = AEGetParamDesc(&event, key, typeAEList, &listDesc);

    That's my guess anyway (and feel free to include the above in your
    bug report if you think it'll help.)

    I can think of a couple possible solutions:

    1. replace the default record-to-list coercion handler with a more
    sensible one that wraps the record descriptor as a single-item list
    when initialising your application. Of course, you have to specify
    the fromType as typeAERecord so I'm guessing this'll only work for
    record-type descriptors of typeAERecord, and not for record-type
    descriptors of any other type, which may or may not be an issue for
    you depending on what, if any, custom record types your sdef defines
    and how they're used.

    2. Specify 'type="any"' in your sdef and unpack the resulting
    NSAppleEventDescriptor yourself. This is a bit of a chore do do using
    only Cocoa, but dead easy using objc-appscript's -[AEMCodecs unpack]
    method:

    http://appscript.sourceforge.net/objc-appscript.html

    The only fiddly bit might be if your record includes any object
    specifiers and you need to convert those from aem-style 'references'
    to something Cocoa Scripting readily recognises, but I imagine a
    solution could be found there if needed.

    HTH

    has
    --
    http://appscript.sourceforge.net
    http://rb-appscript.rubyforge.org
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today