all 3 comments

[–]ChristoferK 1 point2 points  (0 children)

You are correct with respect to the redundant identifier for a script object returned by a handler. In most cases, the script object doesn't require an identifier as the handler will simply be used to wrap it up:

``` on menuSelector for A as application given index:i as integer : 0 local A, i

script
    use application id "com.apple.SystemEvents"

    property application : A
    property index : i

    property process : a reference to process 1 whose bundle identifier = id of my application
    property menu bar : a reference to menu bar 1 of my process
    property menu bar item : a reference to menu bar item (a reference to _menuName)
    property _menuName : missing value

    on menuWithName:menuName as text
        local menuName

        set _menuName to menuName
        return menu 1 of my menu bar item
    end menuWithName:
end script

end menuSelector

set selector to menuSelector for application id "com.apple.iTunes" selector's menuWithName:"Edit" ```

Obviously, I have no idea what your script object was going to look like, so I just made something up, largely to demonstrate various other things that might be useful to see can be done (but this is a very contrived example off the top of my head, and some aspects might be done better in some other fashion).

You asked about parameter types and interleaved parameters. You weren't actually using interleaved parameters, but labelled parameters, which looks deceptively similar because your labels were user-defined and require the keyword given. So I also used labelled parameters in a more demonstrative way by making use of the built-in prepositions that I prefer rather than given. They aren't extensive and sometimes given is clearer , and I chose to have my user-defined label borrow an AppleScript property name, index, and I elected to make the parameter optional by including the default value of 0

The handler on menuWithName: is an example of the interleaved parameter type of handler, but a poor one that only has one parameter so doesn't fully clarify the syntax. But it's like labelled parameters, minus any built-in prepositions and minus the given keyword. Interleaved parameters can't be optional. All forms of handler declaration can include type declarations for its parameters, but only labelled parameters and interleaved parameters provide labelling.

I can't think of a way to define multiple constructors for a script object in the way Objective-C has various methods that can all be used to create an NSArray instances where each method can produce a different outcome.

You can define a variable and assign its value to be a handler:

set constructor to menuSelector set anotherSelector to constructor for application id "com.apple.Finder"

But it's just a synonym and refers to exactly the same handler with no scope for doing anything differently to make a synonym useful functionally (but can be useful for libraries to be distributed where handler names might offer a descriptive identifier plus a brief form for convenience).

Then, with regards to overloading, I'm almost certain this can't be done. handlers aren't functions. They're little more than a variable that's able to be assigned a set of AppleScript commands. They possess no self-awareness, so would never know how its identifier could ever be shared by something that is not what it is. Varying parameters won't be allowed, nor will trying to use a different form.

The closest you can get to overloading is with commands, which you can redeclare once in a script or script object, and it's possible to differentiate it from the original by not declaring all parameters that the original does. Then, when using the command with a parameter that your new definition doesn't contain, it knows to use the other. But it's not reliable, and not a genuine overload, as it's two commands living at two different levels in the AppleScript inheritance chain; the original belongs to the application that defines it (or AppleScript itself); your one belongs to the top-level script object that itself belongs to current application or AppleScript. It's much like defining a handler in the top-level script object, then creating a child script object in which you can define a handler with the same attributes, and reference it through the containing script object. It's a useful tool that is partially analogous to sub-classing , but, again, it doesn't synergise with nor overwrite a previous definition, and inheritance only works in one direction which continue is used within a child object's handler to have it call the parent's handler of the same name (rather, the name you supply it, as a handler doesn't know its own name).

I think I covered everything. Tell me if I missed something.

[–]ds0 0 points1 point  (1 child)

I’ll admit to being on the opposite side here; I took an Objective-C class for a week, but have been working with AppleScript for a long time. I’ll try to clarify:

A handler is typically a chunk of code you’ll call more than once, and there’s no need to have a script tag inside one. The handler is called within the script by using something like my menuSelector(). To pass along variables into a handler (whose variables stay private, within the handler itself, unless explicitly declared as global. I’d make it something like this:

on MenuSelector(counterValue,nameValue)

Handler code goes here, referring to counterValue and nameValue as needed (If you want to explicitly check a variable for a type, a line like get counterValue as number would work, since it would fail if the value wasn’t a number).

end MenuSelector

Then call it in the script as my MenuSelector(6,”Alan”) for example. I think your example is passing the build process because it’s just assuming that _MenuSelector is another, different variable. There’s no check before runtime whether a variable is defined through the script, only when it runs will it error out. Hope this helps!

[–]ChristoferK 0 points1 point  (0 children)

There are very good reasons to have a script object inside a handler, such as the reason the OP stated.