Archive for the 'Developer' Category

A simple example of Nu and Cocoa

Friday, June 3rd, 2011

I recently had a request of showing how to execute arbitrary Nu code inside of an Objective-C context. I’ve created a simple project to demonstrate this. It is available on Github.

Add Nu framework to your project The first step when working with Nu is to add the framework to your project. The example project creates a small app that simply accepts Nu input in one text field and outputs the results in another. Any errors are eaten by the console, so you may want to run Console.app if you actually try to use the program for anything more than an example project. For the most part, though, you can ignore the example app. Everything is detailed below if you just want to dive in.

With Nu added, you’ll need to set up a Nu parser, pass in some Nu code, and execute it. Fortunately, Nu is really easy to use inside of Cocoa. Once you’ve imported the Nu framework into a file (import <nu /Nu.h>), you need to create the parser (id parser = [Nu parser]). Now, there are two steps to actually executing Nu code. The first step is to parse it into tokens (actually, NuCells internally). The second is to evaluate the tokens. This evaluation is the actual execution. Fortunately, this is simple. First, the parse, id parsedNu = [parser parse:nuString], then evaluate the parsed code, id result = [parser eval:parsedNu]. Of course, I prefer to use the convenience method that handles both at once:

id result = [parser parseEval:nuString];

So, how do we use this in a real application? From the example above, the only thing that is missing is the nuString, that is, an NSString containing Nu code. That string could come from anywhere. You could pull it from your application (NSString *nuString = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"nufile" ofType:@"nu"]];) or put it directly into the code (NSString *nuString = @"(+ 1 1)";).

Now, the question is “How do we set up the Nu environment?” Well, everything in the runtime is already included in our Nu environment, so we get access to all of the other frameworks that we’ve brought in:

; This just works if you've imported CalendarStore.framework
(set store (CalCalendarStore defaultCalendarStore))
(set calendar ((store calendars) lastObject))
(calendar title)

; Close the main window for the example project linked to above
appdelegate = ((NSApplication sharedApplication) delegate)
((appdelegate window) orderOut:nil)

This is great, but what about injecting our own objects into the Nu runtime? This is just as simple as everything else:

// Objective-C
NSString *example = @"This is an ";
NSString *nuCode = @"(+ exampleInjection \"example\")";
id parser = [Nu parser];
[parser setValue:example forKey:@"exampleInjection"];
NSLog( [parser parseEval:nuCode] ); // result: "this is an example"

Basically, inject whatever objects you want into the Nu code by calling setValue:forKey: on the parser. You can also get objects back out fairly easily by calling valueForKey: as in:

// Objective-C
NSString *nuSource = @"(set rejectionExample \"Nu->ObjC\")";
id parser = [Nu parser];
[parser parseEval:nuSource];
NSLog( [parser valueForKey:@"rejectionExample"] );

When you’re done, you can just clean up and close the parser ([parser close]). Working with the Nu parser is fairly easy once you know where to look. Nu.h has all of the information there if you want to read a bit more into it.

For further reading, check out my Nu PluginManager. Of special interest in the code is how I call functions by injecting objects and then calling the top-level functions using those objects as parameters by simply parsing and evaluating a bit more code. I could always get a reference to the actual function NuCell using valueForKey:, but this may be the most simple way without need to know anything about how Nu works internally.

Garbage Collection makes life hard

Friday, June 12th, 2009

A while back, I released a small package that demonstrated integrating several of the most popular scripting languages into Objective-C (PluginManager). It was a great experience for me (as well as a rather frustrating one at times). I learned a lot about the internals of my favorite scripting languages and I’ve used the basic components in other software. I also learned a lot about the limitations of garbage collection in Objective-C on Mac OS X. These limitations are somewhat subtle in many ways, but hit you in the face like a sledgehammer in others. In the extended entry, I’m just going to go down a list off the top of my head of the various things that I’ve run into with GC lately. (more…)

NuSomewhere

Saturday, April 25th, 2009

Over the last few days, I’ve been hacking away at a sideproject that I’m calling NuSomewhere. NuSomewhere is a GUI implementation of nu-anywhere which is found in Nu’s examples folder. nu-anywhere is a command line application that injects the Nu runtime and a console into any application. NuSomewhere wraps nu-anywhere and adds a few additional tweaks.

(more…)

The pain with plugins

Monday, March 16th, 2009

So I pushed a rather significant improvement to PluginManager yesterday that finally fixed a rather large problem with Python support. To my knowledge, all of the plugins now work as expected. At least, objects now cross every bridge. Anyway, the more I work with the PluginManager, the more I realize that garbage collection is a pain in my ass. (more…)

Source: PluginManager

Monday, February 2nd, 2009

I’ve just released a bit of source code that has been a consistent struggle of mine. I love scriptable applications. Applications with an Applescript scripting dictionary win immediate points in my book. I also really love applications that provide multiple ways to write plugins. But let’s face it, very few applications actually let you write your own features using Python, Ruby, or Nu.

I’ve been working on integrating this in my own applications in bits and pieces for years. Over the weekend, I decided to slap together the various incantations that I’ve had in several projects into one unified interface. With it, it should be really easy for developers to provide support for many, many scripting languages. At least, I’m hoping it can.

I’m calling my project “PluginManager” and I’ve released code to support Python, Nu, Javascript, Applescript, Cocoa plugin bundles, Lua, and Ruby. I plan to add support for F-Script and will look into the possibility of also using Perl in the near future. This release is for programmers who want drop-in efficiency for loading scripts as plugins in their applications. I’ll be working on it much more in the near future.

View PluginManager on github.