Applescript behind on functions

kel means log in the sense of getting the logarithm of something, not sending to standardError or whatever.

Introspection in C?

There’s too much ideology in programming, IMO…

Then it is back to a wrapper class, and I am not sure how AsobjC gets access to libc, if it isn’t linked in, then it is probably better to yank in the code for the math functions directly into the wrapper class.

No, but it could be simulated by a class with class methods, and an “interpreter” for those calls, so it would work like a dispatcher. That should also be an excercise in your book. :slight_smile: (Since creating calls for all the function calls in the c-library, with error checking, would obviously bloat down the whole system, rather than implementing the few calls one needs. ( I guess the math functions to be the most wanted ones. And the problem is most easily solved, at least as I see it, with a wrapper class.)

Maybe, it is often so, that practice doesn’t go hand in hand with theory.

Time is, I think, our worst enemy.

“In theory there is no difference between theory and practice, but in practice there is” I’ve read this somewhere and I think this applies for all coders.

Hardly, application communication goes through the AppleEvent manager, even for internal communication. This can be dispatched and run in another thread. What it does when you try that, the AppleScript class will move it’s immediately to the main thread again. Then the AppleEvent manager can’t handle events in a asynchronous way. It receives an event, sends it to the right application, waits for a response and send it back to it’s caller. Between this process the same caller and target can’t send another event, instead you event will be queued.

So to me it’s impossible to create that, or you need to write a small event manager yourself where you create your own thread id but still the only thing you will achieve is the already existing “ignore application responses” block. Then you could try to send an AppleScript object and dispatch that code an run in an NSAppleScript object in your faceless application. Still if that code running in an NSApplication object, you’re still dealing with the same AppleEvent manager (there is only one in the OS) that will queue your event. Then there is a second thing, AppleScript doesn’t support function “pointers” once the function gets out of scope, there is no way of getting it back into scope again. Unlike in most programming languages where I can bind (automatically or manually) the method back to an object so keywords like me, this, my, self etc… and inheritance chain works again.

There are too many limitations in AppleScript to support a complete dispatch, It’s not that I’m not looking forward for something like this.

I think I can do this with Xcode. Stefan showed me how to make the new class. The hard part for me is writing the C program. Unless, different classes are created for each function. Here’s the section I was looking at:
https://developer.apple.com/library/mac/documentation/Performance/Conceptual/vecLib/Reference/reference.html#//apple_ref/doc/uid/TP40002498
I’m wondering if I’m on the right track.

You don’t need vecLib unless you want massive accuracy – all you need is in Math.h, which is imported by default. Assuming you’re going to call it from ASObjC, something like:

- (NSNumber *)logOf:(NSNumber *)number
{
 return [NSNumber numberWithDouble:log([number doubleValue])];
}

Most of the code is boxing and unboxing the numbers.

Ah, I see. What?

You see an wrapper around a C function. C functions can’t be called by AppleScriptObjC directly but C functions can be called by Objective-C because Objective-C is a superset of C. So when you write yourself a method in Objective-C you can call indirectly the C function log; Objective-C class will act a bridge between C and AppleScriptObjC. Such methods that only makes C functions callable through Objective-C are called wrappers.

Oh that’s the wrapper. I was thinking that the wrapper was the ApplescriptObjC.

Edited: and thanks for the script Shane.
kel

Hello Kel.

Yeah, the part you create in ASobjC is also a wrapper. So, you call a wrapper that calls a wrapper.

PS. Don’t forget to link in libc. And you should also find, and have a gander at /usr/include/architecture/i386/math.h (or x86, or whatever for i386).

Everything you need for starters is defined there.

Hi,

Getting there. I linked in libc in Build Phases. This is the .m file:

This is the .h file:

I didn’t have parameters in the other project. Am I supposed to write something like:

instead of what I have above in the .h file?

Thanks,
kel

The syntax without parameters in your .h file is correct,
but it must match the implementation syntax

Hello.

I also think that in this particular case, it is easiest to implement it as a class method, that is with a + in front of it, instead of a “-”. I have no idea how well that will work with ASobjC though. Maybe you’ll have to instantiate an object there, in order to send a message.

Too ee the code did look good and well, but you are supposed to specify the parameter in the interface file (.h) file.

I also didn’t see any include of <math.h>, but that is just nit-picking really.

Hi,

I’m stuck. Here’s the AppDelegate:

script AppDelegate
	property parent : class "NSObject"
    property CLog: class "CLog"
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_
    
    on applicationDidFinishLaunching_(aNotification)
        set theLog to my CLog's logOf_(0.5)
        log (theLog)
    end applicationDidFinishLaunching_
    
    on applicationShouldTerminateAfterLastWindowClosed_(aApplication)
        return true
    end applicationShouldTerminateAfterLastWindowClosed_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

Tried it with + in stead of minus. Same error and warning:

Edited: hi McUsr. How do you specify the parameter in the interface file?

Edited: added the underscore to logOf in the AppDelegate and still getting error.
set theLog to my CLog’s logOf_(0.5)

Try getting rid of the Clog property and change this:

set theLog to my CLog's logOf_(0.5)

to:

set theLog to current application's CLog's logOf_(0.5)

Hi Shane,

Commented the ‘property CLog: class “CLog”’ and changed the line to:
set theLog to current application’s CLog’s logOf_(0.5)
I’m still getting the error:
2013-10-19 15:43:03.408 CLog[2285:303] +[CLog logOf:]: unrecognized selector sent to class 0x100001168
2013-10-19 15:43:03.412 CLog[2285:303] *** -[AppDelegate applicationDidFinishLaunching:]: +[CLog logOf:]: unrecognized selector sent to class 0x100001168 (error -10000)
Also, the implementation still shows the warning:
#import “CLog.h”

@implementation CLog

  • (NSNumber *)logOf:(NSNumber *)number
    {
    return [NSNumber numberWithDouble:log([number doubleValue])];
    }

@end
Method definition for logOf not found.

I’m wondering if I linked the right libc

Another thing is that the math.h file is not here:
/usr/include/architecture/i386/math.h
it’s here:
/usr/include/math.h

Darn, I have to go to work.

Thanks for all the help,
kel

- (NSNumber *)logOf:(NSNumber *)number

That needs to be:

+ (NSNumber *)logOf:(NSNumber *)number

Class methods need +, not -.

Hi Shane and everybody,

Tried changing the ‘-’ to ‘+’ again. Success! Now it works!?? I did the exact same thing before. Maybe there were a couple of things wrong when I tried it before.

Yeah, now I get get any C function. Next thing I’ll try is getting the C constants.

Thanks a lot!
kel

Here’s the working script with comments:

script AppDelegate
    -- rem: to link binary with libc.dylib
    (* .h file
     #import <Foundation/Foundation.h>
     
     @interface CLog : NSObject
     
     + (NSNumber asterisk)logOf;
     *)
    (* .m file
     #import "CLog.h"
     
     @implementation CLog
     
     + (NSNumber asterisk)logOf:(NSNumber asterisk)number
     {
     return [NSNumber numberWithDouble:log([number doubleValue])];
     }
     
     @end
     *)
    
	property parent : class "NSObject"
    property CLog: class "CLog"
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_
    
    on applicationDidFinishLaunching_(aNotification)
        set theLog to current application's CLog's logOf_(0.5)
        log (theLog)
    end applicationDidFinishLaunching_
    
    on applicationShouldTerminateAfterLastWindowClosed_(aApplication)
        return true
    end applicationShouldTerminateAfterLastWindowClosed_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_

I think I didn’t have the 'current application’s CLog’s … before when I changed the minus to plus sign, but not sure if that was part of it.

:smiley:

Edited: one thing I’ve found is that you don’t need to link binary with libc library. I think Shane said math.h is built-in. Also, there is still a warning in the Clog.m file “Method definition for ‘logOf’ not found”. Not sure if you can skip that warning. The script still works so far.

Thanks a lot everybody,
Have a good day,
kel

Hello.

It is really cumbersome that it has to be this way now, given all the other goodies we have got! If you have something that uses a sine or cosine, that you want to share, then you have to first write that part, then you’ll have to write an Objective-C wrapper. And I am pessimistic about supplying this, and having it work without code-signing. So there you go, a whole lot of work in order to share a script.

Those basic math functions, has been built into basic, for the last 40 years or so. And it is pretty basic, mandataroy stuff.

Something well worth keeping at a central place, -in Standard Additions.

IMHO, Apple should have supplied the basic transcedental functions in Standard Additions, together with every basic function that is used in Basic, like sgn, and the like. That could even sport the enthusiasm for both Mac’s and AppleScript even more.

Sorry for bringing old topics alive but I want to correct my own as other statements here about scripting additions. I’ve been working with scripting additions day and night for the last few weeks and found out that a lot has changed since the last time I (tried) to write one. I will continue on a statement StefanK has made but probably will also be in conflict with my own previous statements here.

My first argument against that statement would be that anyone can write a scripting addition without using a single line line of Carbon. Scripting additions are written using CoreServices framework umbrella (AE framework to be exactly). AppleScript itself is using the OSA framework which is part of the Carbon umbrella. That AppleScript makes uses of the Carbon umbrella only means it runs on Carbon level, not that it uses any Carbon code at all. Also webkit is released under the Carbon umbrella without using a single line of Carbon code. Also the CoreFoundation is both Carbon and Cocoa. That libraries or processes are connected to a deprecated API doesn’t mean they make use of it. It’s like asking for a banana but getting an entire jungle with a gorilla holding a banana for you (something Joe Armstrong said about OOP) when you include a framework into your project.

Technology outdated? I don’t think so because Leopard followed by Snow Leopard had some big improvements and got rid of the cumbersome handler loading, disposing and initialization of scripting additions but also the calling mechanism of the routines are much more efficient enabling much more commands per second. Mountain Lion extended it with some new functions for comparing AppleEvent descriptors. Mavericks once again improved the loading handlers and commands run even more efficient. All improvements you will not find in the AppleScript Language Guide or AppleScirpt release notes. As far for the technique, the technique is first of all far from old. Objective-C’s runtime for instance is an older technique but still primary used on application level in Mac OS X.

So what is wrong with it? As Shane mentioned, everything is global, there is no namespacing in AppleScript and because scripting addition works next with AppleScript, it will inherit it’s best features but also it’s flaws. Another thing is that a scripting addition is in fact a dynamic C library (dylib) that will be loaded by OSA. That means it’s sitting on the heap of the process who loads the osax. Memory management is very, very important. Simply put, a poorly written scripting addition can mess up the heap and unable to load any kind of script anymore in worst case People keep saying that there is no persistent data in scripting addition, true, but it’s also an understatement. No executable can store persistent data, a process neither. Applications (processes) can’t store them either, therefore we use files like preferences, temporary files and documents. Only script objects can be saved into a file and loaded later, the properties will have the same value afterwards.

I think 3rd party developers should create more scripting additions again. As some older scripters probably know that in the late 90’s there were hundreds of different scripting additions available. I think besides that the number of C developers for the Mac has decreased, maybe those who are left have also lost their interest into AppleEvents.