Nu Language Event Dispatcher
Nu is an interpreted object oriented language built on top of Objective C, with its syntax and several of its mechanics coming from Lisp, whilst being inspired by Ruby's philosophy.
The Event Dispatcher example is one of my favorite when trying out a new language. I choose it because it's representative of a number of programming language core topics such as lists, maps, closures, OO, etc.
I recently spent a short while porting the IO Language Event Dispatcher example in Nu and will be going over my experiment in this article.
Bellow is the code for the
EventDispatcher
class.
(class EventDispatcher is NSObject (- (id) initialize is (set @listeners (dict)) self) (- (void) subscribe:(id)event callback:(id)callback is (unless (@listeners objectForKey:event) (@listeners setObject:(array) forKey:event)) ((@listeners objectForKey:event) << callback)) (- (void) notify:(id)event withArgs:(id)args is ((@listeners objectForKey:event) each: (do (callback) (callback args)))))
There are two prominent methods in this class, namely
subscribe
and
notify
.
The
subscribe
method takes two arguments, the event we're subscribing to and a callback to be invoked every time the specified event takes place. The
@listeners
dictionary is constructed using the
dict
directive, which is shorthand for creating an
NSCFDictionary
instance. For each event, we maintain an array of callbacks. Like
dict
,
array
is available for conveniently creating
NSCFArray
instances.
Whenever
notify
is invoked with an event and the relevant arguments, we iterate invoking any callbacks registered for the given event, passing the provided arguments to each.
There are two ways that I know of that will allow classes to act as event dispatchers, inheritance being the first.
(class Factory is EventDispatcher (ivars) (- (void) produce:(id)color is (puts "#{color} product produced") (self notify:"new product" withArgs:color)))
Here, we create a
Factory
class which extends
EventDispatcher
and we define a
produce
method which notifies listeners that have subscribed to the "new product" event.
Composition is the second, and my preferred, option.
(class Factory is NSObject (ivars) (- (void) produce:(id)color is (puts "#{color} product produced") (self notify:"new product" withArgs:color))) (Factory include:EventDispatcher)
Classes in Nu can be used in a manner similar to that of Module mix-ins in Ruby. Every object in Nu has an
include
method which will make a class's instance methods available in another class. The advantage here is that we didn't have to change
Factory
's
inheritance tree.
Following is a potential event listener that subscribes to the "new product" event and prints out a message every time the event is fired.
(class ProductWatcher is NSObject (- (id) watch is (factory subscribe:"new product" callback:(do (color) (puts "I see a #{color} product")))))
To run the example, we can instantiate a
Factory
and a
ProducWatcher
and fire a few events.
(set factory ((Factory new) initialize)) ((ProductWatcher new) watch) (factory produce:"black") (factory produce:"red") (factory produce:"blue")
The results look like this:
black product produced I see a black product red product produced I see a red product blue product produced I see a blue product
There are a lot of reasons as to why I have time for Nu, its combining 3 of my favorite languages not included, greatly simplifying Cocoa development for native Mac and iPhone applications and Objective C's excellent multi-core support to name but a few.