3

It appears that AppleScript knows the special value null.

How do I return such a value from my Cocoa Scripting based app for a scriptable property?

If I return nil (NULL) or NSNull for a scriptable property getter from my Cocoa Scripting-based app, the script editor interprets that as missing value.

And if I return [NSAppleEventDescriptor nullDescriptor], AppleScript even shows an error.

2 Answers 2

1

AppleScript uses a typeNull descriptor to indicate unassigned/no value, whereas missing value is represented by a typeType descriptor of cMissingValue. (It's analogous to the undefined vs null mess in JavaScript, and a similar PITA.)

Sign up to request clarification or add additional context in comments.

8 Comments

Are you saying that it should be possible for me to return a null value from my app code? How, then?
The point is: don't. AppleScript doesn't handle 'undefined' well, and frankly like JS's undefined it's a misfeature that should never have been introduced at all. Use 'missing value', which is analogous to JS's null; that's what it's there for. typeNull descriptors should only be used as the root in an object specifier chain. (While AEM defines dedicated typeObjectBeingExamined and typeCurrentContainer types to indicate the roots of relative references, an absolute reference, i.e. one relative to the app's root 'application' object, just uses typeNull to indicate that root.)
There is a null keyword defined in the depths of AppleScript's aeut, along with other busted or useless crap; don't use that. And don't be thinking about scripting languages as if they were C; they're not: they don't have pointers, so they don't have C-style null pointers either. Use the standard missing value object to indicate an "omitted" value (c.f. JS's null object, Python's None object, Ruby's nil object, etc), or define your own enumeration/value-class if your app needs a null keyword that has a specific meaning to itself (e.g. if your app is some sort of programmer tool).
This question is related to the linked one about using records. I wanted to be able to let the user check if a record value is non-existing, and the "whose" clause does not appear to work with exists, so I thought returning a special value, such as null, would help with that. I understand I could use yet another value that I define myself, but that seems wrong to me if I could just use the already existing "null" from AS.
Regarding that other post, use missing value to indicate an "empty" property. The Cocoa Scripting framework will (mostly) automatically bridge between nil and missing value for you. And a whose clause should be able to filter on your elements' owner property, e.g. tell application "Contacts" to every person whose organization = missing value. I suggest you post relevant portions of your sdef and code there, and/or make up simple test cases to narrow it down; while CS is not short of its own bugs and shortcomings, you should make sure it's not something in your implementation first.
|
1

I'm using the cMissingValue version of "null", like so:

NSAppleEventDescriptor(typeCode: UInt32(cMissingValue))

I decided to use that based on the testing below.

I'm using Swift to run and passing parameters to an AppleScript subroutine, using the code here:

Passing variables to an AppleScript

let parameters = NSAppleEventDescriptor.list()

let null         = NSAppleEventDescriptor.null()
let missingValue = NSAppleEventDescriptor(typeCode: UInt32(cMissingValue))

parameters.insert(null, at: 0)
parameters.insert(missingValue, at: 0)
return parameters

These parameters are passed to the AppleScript subroutine, and I've commented each results:

on nilTest(paramNull, paramMissingValue)
    display dialog paramNull buttons {"OK"} # execution error: Can’t make current application into type string. (-1700)
    display dialog paramMissingValue buttons {"OK"} #"msng"

    display dialog "" & paramNull buttons {"OK"} #"current application"
    display dialog "" & paramMissingValue buttons {"OK"} #"missing value"
end nilTest

The NSAppleEventDescriptor.null() version seems to for some reason be getting the "current application" value.

It seems like I may want to use the cMissingValue as shown in the other answer.

The variables can be nil-checked in AppleScript like so:

if yourVar is missing value then
    display dialog "is missing value" buttons {"OK"}
end if

NSAppleEventDescriptor.null() does not hit this check. Type cMissingValue does.

I've added it as a Swift Extension: NSAppleEventDescriptor.missingValue()

extension NSAppleEventDescriptor {

    static func missingValue() -> NSAppleEventDescriptor {
        return NSAppleEventDescriptor(typeCode: UInt32(cMissingValue))
    }

}

2 Comments

Is this an answer or a question? This seems like you should be opening a new question for this.
It's an answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.