Call External Subroutine

Hi,

I read the Shane chapter about Handlers and Methods but I miss something before

I would like, just to understand, move some handlers in a separate .applescript file fro maintenance and for separate handlers in a medium size project

First problem. When, after creating a test project in Xcode 4.5.2, I choose File → New → file, there is no applescript class.

So the question is: How I can create a new Applescript file?

Second question: once created I would like to have the getTotalNumber handler in the small sample below in this new file and call it from the main AppDelegate.applescript. How I can do that?
There are other possibilities?

Thanks in advance

Ame

script AppDelegate
property parent : class “NSObject”

on applicationWillFinishLaunching_(aNotification)
	-- Insert code here to initialize your application before any files are opened
    set myNumber to getTotalNumber({10,5})
    log myNumber
end applicationWillFinishLaunching_

on applicationShouldTerminate_(sender)
	-- Insert code here to do any housekeeping before your application quits 
	return current application's NSTerminateNow
end applicationShouldTerminate_


on getTotalNumber(myArray)
    set myTotal to item 1 of myArray + item 2 of myArray
    return myTotal
end getTotalNumber

end script

Well, first of all, your handler is not written properly. because it takes a parameter, you should write it like this:

on getTotalNumberFromArray_(myArray)
    set myTotal to myArray's objectAtIndex_(1) -- Cocao is 0-based, unlike applescript which starts at 1
    return myTotal as integer -- or whatever else you need. You need to coerce a lot in ASObjC
end getTotalNumberFromArray_

And you call it like this:

set myArray to current application's NSArray's arrayWithObjects_({10, 5}) 
set result to my getTotalNumberFromArray_(myArray) -- needed to create an nsarray first

I think that you need to understand how AppleScriptObjC works before trying to create other files from which to call methods and handlers. This is not vanilla AppleScript, as such the code you provided as an example would never work.

When you’re ready, look in the previous postings about how to create external files, it has been answered before many times.

Besides, no need to worry about creating other files until you get to 2000+ lines of code. Unless you want to have “modules” that you’d like to move around from app to app.

Hope this helps.

Model: MacBookPro8,2
Browser: Safari 534.51.22
Operating System: Mac OS X (10.7)

Hi

my previous post was a simple example when you work with one file so I suppose that handler as normal vanlla script don’t require the underscore, required as written in the sane book when you work with multiple .applescript files.
Anyway I solved and I post here for future references:

Create a new project in Xcode 4.x (my version is 4.5.2)
You have a single file called AppDelegate.applescript

If I want to call a subroutine that I want to create in another .applescript file, create a new file based on “Empty” module and call for example test.applescript.

Now in first file (AppDelegate.applescript) put the following (as example):

script AppDelegate
property parent : class “NSObject”

on applicationWillFinishLaunching_(aNotification)
	-- Insert code here to initialize your application before any files are opened
    tell current application's test to set myNumber to getTotalNumber_({10,5})
    log myNumber
end applicationWillFinishLaunching_

on applicationShouldTerminate_(sender)
	-- Insert code here to do any housekeeping before your application quits 
	return current application's NSTerminateNow
end applicationShouldTerminate_

end script

and in the new applescript file called test.applescript put the handler you want to call:

script test

on getTotalNumber_(argumentList)
    
    -- Coerce argumentList as list
    set argumentList to argumentList as list
    
    set myTotal to ((item 1 of argumentList) + (item 2 of argumentList)) as integer
    return myTotal
end getTotalNumber_

end script

All works. I ask confirmation if all is correct. (thanks to Shane book)

Ame

Yes, that seems correct. I haven’t tried it in Xcode, but if you say that it works then it should be fine. Syntax-wise it looks fine.

You have it understand that by your first post it didn’t look like you had understood how applescriptobjc works, it gave a different impression. Usually, it takes as many underscores as there is arguments in your handler. Unless I am wrong, plain vanilla AppleScript syntax won’t work for handlers in an applescriptobjc app.

There is other ways to link different script files, mainly via your nib file. It makes the syntax much simpler, but is a bit more complex to setup at first.

For custom handlers the underscore character to indicate parameter(s) is not mandatory.

You need it only for
¢ “translating” Objective-C methods to ASOC by replacing the colons with underscores
¢ calling ASOC handlers from Objective-C code

As I said in my previous post, unless I am wrong. Turns out I was. But for reasons of consistency I would prefer to use underscores all the time, if it were me…

Hi ame
I am fairly new to ASOC and have found several ways of doing things, I also am not sure what the “correct way” is, but below are some of the ways that have worked for me with a bit of trial and error. If any of my comments are totally wrong, please let me know as I would prefer that my projects are done correctly ( you never know what problems dodgy code could cause as you project gets more complicated)

Xcode issue
To give you my take on your other questions, I also can’t create a new .applescript file via Xcode.
I duplicate an existing file in Finder, re-name it to whatEver.applescript and then drag it into the “classes” folder of the project.

SubRoutine - Multiple .applescript files
I found a few ways that have worked. Some with connection’s via IB, some without.



property test_class : class [b]"test"[/b] of current application     ---  [b] "test"[/b] must be the filename of the .applescript file

script AppDelegate
    property parent : class "NSObject"
......

tell test_class to set whatever to getTotalNumberFromArray_(myArray)
or 
set whatever to test_class's getTotalNumberFromArray_(myArray)

etc


You could also make use of “init()” in the test file, do an “alloc()'s init()” from the delegate and get an instance of the script that you assign to a property in the delegate and refer that.

The other way is to do the “Blue Cube” connection route. Do a search for blue cube, there are quite a few topics that explain it quite nicely.

Regards

Paul

Plus:

  • calling ASObjC handlers in another ASObjC class.