Ruby, Concurrency, and You »
Created at: 14.10.2011 19:41, source: Engine Yard Blog, tagged: Open Source Technology 1.8 1.9 concurrency GIL implementations ironruby jruby macruby maglev MRI parallelism rubinius ruby threads
| Ruby Implementation | Concurrency | Parallelism |
|---|---|---|
| MRI 1.8 | ✔ | |
| MRI 1.9 | ✔ | |
| Rubinius 1 | ✔ | |
| Rubinius 2 | ✔ | ✔ |
| JRuby | ✔ | ✔ |
| MacRuby | ✔ | ✔ |
| Maglev | ✔ | |
| IronRuby | ✔ | ✔ |
A big topic in the world of Ruby this year has been how to get more out of Ruby, specifically, how to get more done in parallel. The topic of concurrency, though, is one fraught with misunderstanding. This is largely due to the complexities of not only thinking about multiple things at once, but the limitations of Ruby implementations and operating systems.
In this article, I’ll lay the groundwork for understanding the difference between concurrency and parallelism. Then, I’ll look at how a programmer experiences them.
Concurrency vs. Parallelism
This has been discussed many times, but I sometimes still have difficulty with it. Let’s first break down the definitions of these two words:
- Concurrent: existing, happening, or done at the same time
- Parallel: occurring or existing at the same time or in a simple way
Hmm, ok. Well, that hasn’t improved our thinking about these two topics. We need to dig deeper into how the world of computing applies to these words. Rather than looking at the abstract, let’s instead consider some real world examples.
A “Real World” Example
Let’s say you’ve sat down for the evening to complete tomorrow’s homework. This evening you’ve got both Math and History worksheets to fill out. Tonight for some reason, you decide to do one problem in Math, then one problem in History, then back to Math, etc until all the problems are done.
In the parlance of computing, you’re now doing your Math and History worksheets concurrently. This is because your Current task list includes 2 items: Math worksheet and History worksheet.
Now, clearly you the reader can see a problem here. By switching back and forth, completing your homework will probably take longer than if you did the complete Math worksheet then did the History worksheet. In other words, if you did the worksheets in serial.
So, if concurrent means “having multiple outstanding tasks at once”, then what is parallel? Parallel is the ability to make progress on multiple tasks simultaneously.
Let’s say you’ve been asked to read the book One O’Clock Jump by Lise McClendon. You also need to drive down to San Diego for Comic-Con. Thankfully you find that One O’Clock Jump is available on audiobook!
You can now listen to the book while driving. You’re simultaneously making progress on two separate tasks. This is the equivalent of parallelism in computing.
I hope that these real world examples help illustrate the difference between concurrency and parallelism. Now let's apply this newfound knowledge to Ruby.
Back to Ruby
One reason this problem can be difficult to understand is because Ruby only provides a single mechanism for concurrency. But, whether or not these Threads are parallel depends on a number of factors.
MRI 1.8
Let’s look at MRI 1.8 (and MRI forks such as REE) to begin with, because it has the simplest model. MRI 1.8 uses a technique known as “green threads” to implement Threads. This means that every once in a while (around 100 milliseconds), the program says “oh, I should let another thread run now!” This saves the current info into the current thread and restores another thread. This is exactly like our homework example above. We can have as many things as we’d like in our task list, but we can only make progress on one of them at a time.
There is a wrinkle in the concurrency/parallelism game that I haven’t mentioned before now. This wrinkle is IO, namely how Threads interact when waiting for some external event. MRI 1.8.7 is quite smart, and knows that when a Thread is waiting for some external event (such as a browser to send an HTTP request), the Thread can be put to sleep and be woken up when data is detected. This simple consolation improves the usage of Threads so much that for a very long time the MRI 1.8.7 model was good enough for all Ruby programs.
MRI 1.9
Switching back to Ruby implementations, let’s look at MRI 1.9. As has been previously reported, MRI 1.9 removes the “green threads” we had in MRI 1.8 and uses native threads to implement the Thread class. Now, what are these “native threads”? These are are units of concurrency that the underlying operating system is aware of. A big reason to switch to use native threads is that it vastly simplifies the implementation of Threading. The operating system handles the low level parts of saving and restoring Thread information in a completely transparent way. Additionally, letting the OS know what parts of a program should be concurrent allows it to use the full resources of the computer to make that happen. In this modern world, that means using multiple cores.
Up until now, all we’ve talked about with Ruby’s Threading model was about concurrency, the ability to have multiple outstanding tasks at once. Now when we add in the idea of multiple cores, we can finally talk about parallelism. When a computer includes multiple cores (which is pretty much every computer now), those cores can run different code simultaneously, providing true parallelism. When a computer only has one core, there is no true parallelism, instead there is just simple concurrency, even at the OS level. The OS manages all the processes and threads in the system the same way you handled your Math and History worksheets, doing one for a little while, then grabbing another one.
Back to multiple cores though. Now that there is the opportunity to run things truly in parallel, we have to look at if Ruby can take advantage of that. Since MRI 1.9 uses OS threads, it can actually spread out your Ruby Threads to multiple cores!
Unfortunately, MRI 1.9 prevents the Ruby code itself from running in parallel by requiring that any thread running Ruby code hold a lock. This lock is commonly knows as the GIL (Global Interpreter Lock) or GVL (Global VM Lock).
There are a few reasons the GIL to exists, but for this discussion we will say that it’s because the non-Ruby parts of MRI 1.9 are not thread-safe. This means if data were manipulated by multiple threads at the same time, the data could become corrupt. The important thing for this post is how it applies to parallelism: the GIL inhibits parallelism within Ruby code.
MRI 1.9 uses the same technique as MRI 1.8 to improve the situation, namely the GIL is released if a Thread is waiting on an external event (normally IO) which improves responsiveness. MRI 1.9 also includes an experimental API that C extensions can use to run some C code without the GIL locked to utilize parallelism. This API is very restrictive though because no Ruby object may be accessed in any way while the GIL is not held by the current thread.
That about sums up the situation with MRI 1.8 and 1.9 with regards to concurrency and parallelism. Both provide concurrency of Ruby code, but neither provide parallelism of Ruby code.
Rubinius
Let’s take a quick look at other Ruby implementations where things are a bit different than MRI. I’ll start with Rubinius, since it’s the one I’m most familiar with. Rubinius 1.x also had a GIL and worked pretty much the same as MRI 1.9. With the upcoming 2.0 release though, the GIL will be removed, allowing Ruby code to run fully concurrent and fully parallel. We think this opens up a lot of uses for Ruby (parallel algorithms, etc) that Rubinius couldn’t handle well previously.
JRuby
JRuby layers the Thread class on top of Java’s thread class, so the threading model is whatever the JVM supports. That being said, OpenJDK is the primary JVM; it puts a Java thread directly onto an OS thread with no GIL. Thusly, JRuby almost always has full concurrency and parallelism available to it.
MacRuby
MacRuby also uses Cocoa’s NSThread as its abstraction, which runs without a GIL. So, this is another fully parallel implementation.
Maglev
Maglev runs directly on top of a Smalltalk VM and thusly layers the Thread class on top of a concept called Smalltalk Processes. In this case, the GemStone VM implements Processes in the same way as MRI 1.8, namely via “green threads” that don’t expose concurrency to the OS, and therefore, have no parallelism.
IronRuby
Lastly, IronRuby layers Thread directly on top of CLR’s threads without a GIL.
Conclusion
I hope that this helps to clear up what concurrency and parallelism are and how the different Ruby implementations address them. Having this understanding is critical for discussing and understanding topics such and thread-safety of libraries and performance of applications.
In future posts, we’ll look to build on this knowledge to help you make the best use of Ruby!
more »
Objective-C for Ruby developers, un not-so-petit interlude (1/2) »
Created at: 24.03.2010 23:52, source: Phusion Corporate Blog, tagged: macruby
Bonjour les amis! Welcome back to to this second installment of our tour de MacRuby! In the previous article, we went over the basics of XCode and Interface Builder. With this preliminary knowledge, we were quickly able to write our very first Cocoa application using MacRuby as well as understand the importance of Camembert!
Indeed, that was quite an interesting experience as it showed not only how easy it was, but hopefully, it also showed how fun this was as well. If I’ve been unable to convince you of this in the last article, I certainly hope I will be able to do so in this article as we will compare the MacRuby way with the traditional “Objective-C” way.
Assuming you are already well familiar with Ruby, it’s important to go over some basics of Objective-C seeing as Cocoa and its documentation assume this language. Basic understanding of Objective-C is therefore a must when it comes to developing Cocoa applications.
At a first glance, Objective-C and Ruby couldn’t be more different from each other than humanly possible. Where Ruby is beautiful and elegant, Objective-C seems to be convoluted with square brackets. Looking past the syntactic differences though, you’ll be able to see that they really don’t differ that much from one another.
For instance, both Objective-C and Ruby are strongly typed object oriented programming languages. They both support dynamic dispatching via message dispatching, i.e. objects being able to respond to messages and effectively run the corresponding code for that message during runtime.
Realizing these similarities, Laurent Sansonetti — black-belt Patrick Hernandez imitator at Apple Inc. — set out to unify these two worlds, resulting in MacRuby. With MacRuby one can access the Cocoa library as if it were an integral part of Ruby itself. This in contrast to RubyCocoa which acts as a bridge between Ruby and Cocoa.
At its core, Objective-C is a strict superset of C, meaning I’m using fancy words to say that at its core, it’s still C. More specifically, this means that any C program should work with an Objective C compiler but not the other way around.
Seeing as Objective-C can pretty much be considered a thin layer on top of C, you’ll still have to deal with tedious things like forward declarations (seperation of declaration and definition), macro’s, memory pointers and prior to Objective-C 2.0, manual memory management. Let’s see… in Ruby, you have to deal with pretty much none of these. With the “Ruby is better than X
” doctrine in mind, let’s go over some of the things that make up Objective-C.
Selectors
In Cocoa jargon, selectors denote method names/identifiers. In Objective-C, a method call on an NSMutableDictionary instance (think Ruby Hash) to set an object for a particular key would look something like this:
[myMutableDictionary setObject:foo forKey:bar];
As you’ve undoubtedly noticed from looking at this code, method names in Objective-C seem pretty different from Ruby to say the least. Indeed, unlike Ruby, Objective-C allows for the method name to accomodate the parameters in such a way that we invoke a method, it looks like we have to provide the parameter names too, not only their values. This allows the Cocoa API to be very descriptive based on the method name alone.
In particular, the signature for the above method is actually:
-(void)setObject:(id)anObject forKey:(id)aKey;
As mentioned before, this is very different from how you would define a method like this in Ruby, which would look something like:
def set_object_for_key(anObject, aKey) #... end
Or overload an operator should you be so inclined to impress the ladies:
def []=(key, object_value)
#...
end
In the Objective-C signature, we see that the method signature starts with a minus symbol denoting that this is indeed an instance method. If we were to use a plus here instead, it would denote a class method, i.e. a method that would operate on a class-level as opposed to an instance level.
So to drive the point home:
@implementation SomeClass
+(id)foo {
//...
}
@end
would mentally translate to the following in Ruby:
class SomeClass
def self.foo
#...
end
end
In addition to the above, we also had to provide type information for the return value and the parameters of the function in Objective-C. Here, the type following the minus sign denotes the return type. In the setObject:forKey: case, we have void, which means that our method returns “nothing”. The (id) in the parameter list signifies that it’s an object of “an arbitrary type”. In C parlance, we could compare this to a void pointer, but in Objective-C we use (id) mainly for Objective-C objects.
Drawing our attention back to the aforementioned syntax comparison (i.e. setObject:forKey: and set_object_for_key), this is basically what RubyCocoa does when bridging the API’s and it shouldn’t be too hard to realize that this will become quite hard to read once the argument list grows. In particular, one could in such a case easily get confused with regards to which nth argument is responsible for what.
In order to retain the descriptive nature of Objective-C methods for arguments, MacRuby had to introduce a similar mechanism to keep Cocoa as readable as it would be in Objective-C.
In MacRuby, the above method invocation would look like this:
myMutableDictionary.setObject(foo, forKey: bar)
As you can see, we can still clearly see that the object here to be set is foo and that bar is the key.
Seeing as selectors identify a method, they can be used in conjunction with message dispatching to vary method invocation during runtime. Indeed, this is very similar to Ruby’s send method.
In particular, Objective-C’s:
[apple performSelector:@selector(eat:) withObject:camembert]; // Equivalent to [apple eat:camembert];
Would be equivalent to Ruby’s:
apple.send(:eat, camembert)
Note that in the Objective-C example, we’ve made use of the @selector directive to refer to a method by name. In Ruby, we could simply use a string or a symbol.
The alert reader will have noticed that the same mechanism can be used to set up the target-action mechanism we’ve seen in Xcode and Interface Builder. Instead of dispatching an action of a button via Interface Builder to an action method, we could also write:
[myButton setAction:@selector(myAction:)]; [myButton setTarget:myController];
In case of a click event, this will perform the myAction: selector on the myController object.
Declaration, Implementation, Linking
Earlier on, we made mention that Objective-C could be considered as a thin layer on top of C, and in a more formal sense, that Objective-C should be considered as a strict superset to C. This should become a little bit more apparent too when we consider some of the traits it has inherited from C in order to work cooperatively with it. We elaborate on this for the purpose of allowing you to get a deeper understanding when looking into existing Cocoa/Objective-C code and applying this to MacRuby.
Like C, any C function invocation you make in Objective-C to a either a variable or method needs to be declared prior to its use. These declarations are required for the compiler to build up a so-called symbol table, which it uses to determine scope, type and sometimes the location in memory of the symbol. Indeed, tedious yackshaving stuff we don’t need to bother ourselves over in Ruby! Objective-C method invocations are dynamically dispatched through message dispatching and it is therefor not strictly necessary to declare the receiver’s type upfront. For example:
id foo = [[Foo alloc] init]; [foo someArbitraryMethod];
The example above this line will compile just fine as it is syntactically correct, but can break during runtime if foo is unable to respond to someArbitraryMethod. Compare that to the situation when we provide the actual type upfront too:
Foo *foo = [[Foo alloc] init]; [foo someMethod];
By doing this, we’re saying that foo points to an object in memory of type Foo. With this information, the compiler can now check during compile time if someMethod is defined and declared in Foo, basically making sure foo can respond to the method. It is for this reason that I’d like to recommend limiting the use of id over the actual type as the compiler may be able to provide additional assistance.
The declaration of a class is put in so-called header files (.h files, e.g. MyClass.h), whereas the implementation itself is put into implementation files (.m files, e.g. MyClass.m). The implementation file is then expected to #include (or #import) its header file to get its declarations. As the @interface directive denotes in a typical Objective-C header file, we concern ourselves with exposing the interface of the class within this file by declaring it for use for others. When we compile a class’ implementation file (and its included header file) in this manner, we end up with a so called object file. This object file contains our compiled class code.
Other files depending on this class are expected to include its header file (and thus obtaining its interface) and let the linker hook up the compiled implementation (object file) to it during compilation. The ultimate end result should be the executable itself.
How different this process is indeed from Ruby, where the interpreter does not need us to do this kind of yackshaving at all. Of course, a compiled variation usually performs a few magnitudes better than an interpreted version, but the latter no longer strictly applies with MacRuby’s ahead-of-time and/or just-in-time compilation. Indeed, we can just compile our Ruby code to native and get similar performance to a compiled Cocoa/Objective-C application, sans the yackshaving! C’est parfait!
To drive the point home, a declaration for an Objective-C class in a Cocoa application usually looks something like this:
#import <Cocoa/Cocoa.h>
#import "Cheese.h"
@interface Camembert : Cheese {
int age;
Smell *smell;
}
@property (readwrite, assign) int age;
@property (readwrite, retain) Smell *smell;
-(id)initWithAge:(int)age smell:(Smell *)smell;
-(void)someOtherOperation;
@end
First off, we see an import pre-processor directive which will include the Cocoa header file. Angular brackets here denote that it will look for this file from in the system directories (where these are also configurable through compiler flags).
Also note that the #import directive differs from the #include directive in that #import will take care of including the provided file no more than once. This will prevent multiple declarations for the same symbols to occur, which normally would result in compiler errors. So called include guards would normally be necessary in the header files to prevent this from happening in the case of #include.
Then, we see the interface declaration of the class Camembert, in particular, it being declared as a subclass of Cheese. For the latter, we had to import the header for Cheese too. Note here that the use of normal quotes denotes that the compiler should look for this header file within the user specified directory. By default, this includes the current working directory, but we can specify these directories with compiler flags if we would really need to.
Within the accolades, we are expected to declare our instance variables. As any good Camembert, we expect it to have a distinct smell and age. Thus, we declare an age of type integer and a smell of type Smell as our instance variables. The asterisk at smell denotes that this is a pointer, which we’ll elaborate on at a later stage.
Then, we see the following two property directives:
@property (readwrite, assign) int age; @property (readwrite, retain) Smell *smell;
Even though scary looking, you should already be familiar with something like this within Ruby, be it in the form of attr_accessor, attr_reader and attr_writer.
Like the aforementioned Ruby attr_* family of methods, the @property directive can generate a getter and/or setter for a particular instance variable of our class. Consider:
@property (readwrite, assign) int age;
Here, we say we want our instance variable age to be available with read and write access (getter and setter), and we want the argument to be assigned to the property. This should eventually expand in code like the following if we were to use the “@synthesize age;” directive in the implementation file:
-(void)setAge:(int)a {
age = a;
}
-(int)age {
return age;
}
A similar process takes place for the smell property, provided we use “@synthesize smell;” in the implementation file:
-(void)setSmell:(Smell *)s {
if(smell != s) {
[smell release];
smell = [s retain];
}
}
-(Smell *)smell {
return smell;
}
You will have undoubtedly noticed the use of release and retain. Even though Objective-C 2.0 comes with garbage collection, we can opt to not use it, giving up convenience in favor of performance and efficiency. Platforms like the iPhone by the time of this writing for example do not support GC yet, and so, we have to fall back on a manual memory management technique called manual reference counting for these platforms. Release and retain are our means to this. Under a garbage collected environment like MacRuby’s, these methods however do nothing as the GC will take care of memory management.
The concepts to manual reference counting are actually very similar to those of garbage collection: an object becomes unreachable if we have no references to it, i.e. the reference count of an object is 0. We say that that object is no longer live and is considered to be garbage. As such, we can get rid of that object. MacRuby utilizes a garbage collector called AutoZone to achieve this, the same one that we can use in Objective-C 2.0.
If we don’t use a garbage collector in Objective-C however, we have to manually determine what objects are live and what objects are considered to be garbage. For Objective-C objects that are allocated on the heap, i.e. objects that would otherwise persist in memory throughout the lifetime of the application if not explicitly deallocated, we employ a technique called manual reference counting: every time we need a reference to an object, we call retain on it to bump up the reference count of the object by one. When we no longer need it, we decrement the reference count by one with a corresponding release call on the object. When the retain count reaches zero, the object is no longer referenced and will be discarded.
In the case of setSmell, we see that we first try to determine whether or not we’re dealing with the same smell objects. If we have two distinct objects here, we first discard the current smell and then retain the new smell. If we were not to release the current smell, the current smell object’s reference count would not be decremented and could possibly never reach 0. This would result in the object not being released from memory, causing a memory leak. Conversely, not retaining the new smell object could cause the new smell to prematurely reach a reference count of 0 and get released too soon from memory.
Not everything in memory needs to be maintained in such a tedious manner though. Stack allocated objects, i.e. values allocated on the stack that only persist through the current scope, will get popped automatically once their scope ceases to exist. For example:
-(void)foo {
int myStackAllocatedVariable = 6;
// Do some processing...
// Do some more processing...
// myStackAllocatedVariable should be popped.
}
Here, myStackAllocatedVariable will get popped from the stack after it reaches the end of the function.
Besides retain and assign, we also have copy, which should be pretty self explanatory by now. Think Object#dup in Ruby
. That was undoubtedly quite a bit to soak up and should hopefully underline the strengths of MacRuby for not putting you up with this in the first place!
Finally, after the accolades, we see the declarations for our methods. In particular, we see:
-(id)initWithName:(int)age smell:(Smell *)smell; -(void)someOtherOperation;
Where the second method is just a plain method, we consider the semantics of a method prefixed with init to be a constructor by convention.
After allocating memory for the object via the alloc method, we need to initialize the object to the desired state through a constructor. The process to achieve this in Objective-C is very similar to that of Ruby actually, even though you might not realize that at a first glance.
In Ruby, we allocate and initialize an object through calling its “new” factory class method. The workings of the latter can be described in pseudo code as the following:
class Object def self.new(*args) self.alloc.initialize(*args) end end
Here we allocate an object using its alloc class method and initialize it by calling initialize on the object, passing it the arguments we got through the “new” invocation.
In Objective-C, we would do the following to allocate the object and invoke its default constructor:
Camembert *camembert = [[Camembert alloc] init];
To utilize our custom constructor, we would do:
Camembert *camembert = [[Camembert alloc] initWithAge:3 smell:someSmell];
Instead of having a “new” class method for every possible initialization, it is common practice in Objective-C to just chain the calls like this instead. One could consider it as a way of overloading constructors in a more distinct and descriptive way.
Now that we’ve covered the declarative part, let’s discuss a possible implementation for our Camembert class:
#import "Camembert.h"
@implementation Camembert
@synthesize age;
@synthesize smell;
-(id)initWithAge:(int)a smell:(NSSmell *)s {
if(self = [super init]) {
[self setAge:a];
[self setSmell:s];
}
return self;
}
-(void)someOtherOperation {
NSLog("I really should have a better implementation.");
}
end
As we’ve already discussed in the previous section, the @synthesize directives will expand our @property directives to setters and getters.
In the class definition, we’ve also given a sample implementation of the constructor initWithAge:smell:. This should be pretty self explanatory, save perhaps the if(self = [super init]) part which is idiomatic in Objective-C. This is the part where we make sure that the super constructor gets invoked prior to initializing the current subclass as we’d normally expect in object oriented languages.
A constructor in Objective-C is not a special method however that takes care of this for us implicitly like in e.g. Java: from a code point of view, it’s just a regular method with special semantics. It is for this reason that it’s usually a good idea to invoke the super constructor before doing anything, seeing as an alloc will only allocate the memory for the class, but makes no guarantees as to how it will initialize it.
The following code invokes our synthesized setters, and as you can see, their selectors are already prefixed with set (and get).
[self setAge:a]; [self setSmell:s];
Finally, we see:
-(void)someOtherOperation {
NSLog("I really should have a better implementation.");
}
You should be able to tell what the signature is about by now, but I wanted to highlight this part in particular as it shows a very useful function in the form of NSLog which allows you to write messages to the console in a convenient way. This is of course very useful for debugging if you don’t want to dive into GDB.
MacRuby<3
I think you’ll agree with me that the above is very similar compared to the MacRuby way, minus the yackshaving of header and implementation files:
class Camembert < Cheese
attr_accessor :age
attr_accessor :smell
def initialize(age, smell)
# If you're subclassing a Cocoa/Objective-C super class,
# you may want to do a super invocation here etc... too.
# Can you guess why?
@age = age
@smell = smell
end
def someOtherOperation
NSLog("Born!")
end
end
Pointers
When we store data in memory, e.g. an object, we may want to retrieve it at some later point. Luckily for us, memory is addressed, meaning we can access certain parts in memory via their address provided the operating system allows us to. Here, pointers are used to store these addresses of data in memory of a certain type.
To drive the point home with an analogy, we use the example of a book (in particular, the MacRuby book Matt Aimonetti is currently writing for O'Reilly which yours truly under the pseudonym of "Ninh Bui" will review
).
The pages of the aforementioned book contain the actual data on the topic of MacRuby and are assumed to be numbered. Here, the page numbers can be considered to be the memory addresses of the data. Now suppose a friend of yours would like to know more about Cocoa bindings. You now either have the option to copy parts of the book (copying data) or provide the book with a page number instead elaborating on the topic. Similar to computers, copying data is often unnecessary and I think you'll agree that that is definitely the case in this situation. It is for this reason that instinctively, you'd want to pass a page number and book instead of copying parts of the text by hand.
If we were to use a piece of paper to write down a specific page number for a friend, that piece of paper could be considered to be a pointer and in particular, it's a pointer to information on Cocoa bindings. Your friend can now look up the information from your book using the given page number, basically engaging in the process of dereferencing the pointer by looking up the actual data the pointer references. On computers, it's pretty much the same deal: given a pointer, you can look up the actual data in memory that the pointer references.
If this was hard for you to follow, just remember that this is really not that different from a reference in Ruby. Instead of dealing directly with memory addresses, we just get the object that was stored there instead.
For MacRuby, it's important to understand that when you see an Objective-C method like for example:
-(void)foo(NSMutableDictionary *dict) {
// Do stuff with dict
}
You are expected to pass it an object of type NSMutableDictionary. In MacRuby that would be its Hash counterpart:
foo({:haiz => :baiz})
There is a small exception though in MacRuby that allows you to get pointers to primitives but considering the unlikeliness that you'll need it, I'd kindly like to refer you to the Pointer class for more information on that.
Stay tuned for part 2
That was undoubtedly quite a lot of information to deal with in one blog posting indeed! And we're not even done yet, as we still haven't even discussed Categories and Protocols. These are fundamental for understanding the concept of delegates in Cocoa.
MOAR!
These blog posts are just a small example of the knowledge that is available at Phusion. If you're interested in learning more about topics like e.g. Ruby, Passenger, Scaling, C/C++, Databases and so on in an in-depth manner, feel free to contact us for information on consultancy, training and speaking engagements.
more »
Creating our very first Mac application with Ruby, how exciting! »
Created at: 12.03.2010 15:09, source: Phusion Corporate Blog, tagged: macruby
People always ask me why I never find a programming language for the Mac and settle down down down. C’est absolument incroyable indeed as the answer should be pretty straight forward to those who have already written an application for the Mac using Objective-C.
As a matter of fact, in France, raising such a question is like asking whether or not Camembert goes well with French fries or not. The answer to this question is obvious as it’s a known fact that Camembert goes well with everything. Seeing as not everyone is blessed with a taste for fine French cuisine and/or is from French héritage however, I’ll try to give an approximation in this blog.

For this, we need to emphasize the differences of developing Mac applications with and without MacRuby.
After setting up MacRuby as described in our previous blog post and having set up Xcode, it is now time to create our very first Mac application in Ruby. In this series of articles, we assume that you have the latest version of OS X installed on your Mac. By the time of this writing, that is Snow Leopard and it is important to emphasize this seeing as some Cocoa API methods have been deprecated or added since its last iteration. Without further ado, allons-y!
Creating a new project
After starting up Xcode:
- Select File
- Select New Project
A dialog window as shown below should appear.

From this window
- Select MacRuby application
- Click on Choose…
A file save dialog should now appear as displayed below.

In this window:
- Type in BornToBeAlive as our project name.
- Click on Save.
A new window should now appear representing the newly created project in the Xcode environment.

By the time of this writing our environment is setup to target OS X 10.5 (Leopard). As mentioned before, we’re going to target OS X 10.6 (Snow Leopard) seeing as we want to utilize the most mature Cocoa API and platform. As such we need to set this target environment to OS X 10.6 in the overview popup menu.

Now that that’s been dealt with, we can finally really start working on our application.
Designing our Interface
Before we’re going to write even a single line of code, let’s first start off by designing the user interface to our application. To do this, we first need to discuss how our programming environment deals with this kind of information.
Certain information about our interfaces, in particular the one’s we’ve created using Interface Builder (the UI design application of Xcode) are usually stored in bundles called NIB files.
As of Xcode 3, these are actually stored in files with the xib file extension as opposed to the nib file extension. Worry not however, as they are just different formats for storing the same information: where xib files appear to be represented as XML text files, a nib file is an archive. More importantly however, the difference between xib and nib files are that the former will be compiled within the executable and will not appear in the final .app bundle.
In general, Xcode will ultimately know what to do with these files and how to treat them. It is for this reason that we’ll refer to both formats as nib files and basically assume no distinction between them.
In the Groups & Files panel, expand the NIB Files group.

In this panel
- Double click on MainMenu.xib
This action should result in Interface Builder firing up for this MainMenu.xib file. Various windows of Interface Builder should now be visible to you.
In the MainMenu.xib window:

You see a collection of objects and proxy objects that are necessary for describing our user interface. The objects displayed in this window are objects that describe our application’s user interface and are stored in a freeze dried manner, i.e. serialized. Upon loading the NIB file, they get thawed and instantiated again.
In light of this, it is considered good practice to store only one window object per nib file. This way, we only load in the windows when we really need them (thus conserving memory) and will keep our design more maintainable too as each window and its components will be contained by its own NIB file. The latter will allow us to possibly recycle NIB files too in other projects.
Strictly speaking, we also shouldn’t store a window in our MainMenu.xib as is now the case, but in order to load this in, we require a notion of delegates. The latter is something we’ll discuss in a later article so for now, we’ll keep the window object in MainMenu.xib.
For now:
- Double click on Window
This should put the focus on our initial window and via the inspector, we can edit some of its properties, such as the title of the window instance.
While having selected the Window in the MainMenu.xib window, in the inspector window:
- Select the first tab, so that the inspector window is displaying the Window Attributes.

- Edit the Title field to Born to be Alive

- Hit the enter key
Your window should now bare the title Born to be Alive. How exciting!

Let’s add a Label to this window proclaim this message of life even bigger. To add cocoa components to our window, we need to drag and drop them from our Library panel to the window we want to add them to.
In the Library panel:

- Set the focus on the search field at the bottom of the Library panel.
- Type in Label. Notice that as we type character per character, the components get filtered based on our query.
Your Library panel should now display a few options for labels and should look something like the following:

Note that my Library panel will most likely display more options here in terms of labels as I’ve also installed the BWToolkit palette too. We won’t be using any of those components for our MacRuby applications though, so it’s safe for you to ignore them for now.
Now it’s time to actually add the Label component to our window. As mentioned earlier on, we do this by simply dragging and dropping the Label icon from our Library panel to the window we want to add it to. Doing so should result in something similar to the following:

Great! Let’s rename the newly added Label to something more fitting. In the window displayed above:
- Double click on the newly added Label. This should now open up the ability to edit value of this Label.

- Type in Born

- Hit the enter key.
Your window should now look something like this:

Wouldn’t it be fun if we would have a button that we could press to unveil the full message of life? Let’s do just that by adding a button to the window we’re designing.
In the Library panel:
- Type Button in the search box at the bottom of the Library panel. In a similar fashion as the label, it should filter away the components that do not match the Button search description.

Whoah, so many buttons! Let’s just stick with the first shiny one for now.
- Drag and drop the first button that appears in the filtered selection to our window. Depending on where you dragged and dropped the button to, your window should now look something like this:

- Double click on the newly added button to be able to edit its title.

- Type in Unveil full message

- Hit the enter key.
Your window should now be shaping up pretty nicely and look something like:

We can actually build this project at this stage and see what we’ve just designed in the form of a real application! Indeed, the standard MacRuby cocoa template has set up most of the boilerplate to get us started. At a later stage, we’ll dive into the details of the bootstrapping process, but for now let’s just assume that it set it up all correctly and save our changes by selecting File->Save from the Interface Builder main menu.

Compiling is not the task of Interface Builder, but the task of Xcode so let’s switch back to Xcode. In the project window, click on the Build and Run button in its toolbar.

After compiling for a few seconds and linking all the dependencies, your new application should launch in your OS X dock, and in particular, the window you just designed should show up.
Clicking on the Unveil full message button doesn’t do a lot though, but that should come as no surprise seeing as we’ve only been designing the interface up to this point. We haven’t yet specified what should happen if one presses the Unveil full message button button.
In terms of Model-View-Controller (MVC) (a separation of concerns design pattern Cocoa relies heavily on), we need a controller to handle this kind of user input.
Writing our very first controller in MacRuby
As mentioned in the previous section, Cocoa was designed with the MVC paradigm in mind. Within this paradigm, we need some kind of controller layer to process the input provided by the user. This input ranges from keyboard events to mouse events. For our intents and purposes, we’re interested in handling mouse events on our Unveil full message button. In order to be able to do that, we need to create a controller that will be able to deal with that.
Also, we may want to process events employed by the user onto the window itself. This would normally require a NSWindowController instance. Taking in mind we want to process events from components within the window as well, we could choose to create a separate controller for these components as well, but that would likely make things overly granular, especially for the simple scenario we’re currently dealing with.
So in place of the latter, we can also just choose to consolidate the ability to process the events of a window and its components all together into a subclass of NSWindowController. This allows us to handle the general case of controlling an NSWindow as well as specify our own actions for handling the components contained by our NSWindow.
To do this, in the Groups & Files panel, expand the BornToBeAlive project as displayed below by clicking on the triangle next to it.

In this expanded project outline view:
- Right click (or ctrl+click) on Classes
- Select Add->New File

A new window should now appear giving you the options of what kind of new file you would like to add.
- From the Ruby user templates, select Ruby File.
- Click on Next

This will open up a Save File dialog.
- Type in MyWindowController.rb as the name for the new Ruby file.
- Click on Finish.
Your window should now look something like this:

As decided upon earlier, we now need to implement our MyWindowController class in a consolidated way such that it can control both the window and the elements contained by that window. We will achieve this by implementing MyWindowController as being a subclass of NSWindowController, and in doing so, specialize the NSWindowController class for our window.
In the code editor, type in:
class MyWindowController < NSWindowController end
Tres bien! But how do we access the label to modify its value after a user has clicked on the Unveil full message button?
Well, according to the Apple cocoa documentation on NSWindowController, it is capable hold a reference to the window it controls/manages. Instinctively, we assume that through this reference, we could access the elements of the window.
Even though this is kind of true, the NSWindow class was designed for general cases as well and not just our specific window. This means that its design is well composed and that it will be rather tedious to acquire a reference to the element of the window we’re interested in manipulating. Most likely, it will involve a lot of chaining query calls which violates the principle of least knowledge.
To drive the point home, accessing an element in such a fashion in general will look something like: window.view.subviews[0]
A non-food solution to this would be to subclass our NSWindow to hold a direct reference to the elements we’re interested in manipulating, but that would require an assumption in terms of type seeing as our NSWindowController only deals with NSWindow and not OurSpecificWindow.
Taking all this into account, it’s probably just better to give our MyWindowController a direct reference to the element of the window we’re interested in manipulating.
In our particular case, we’d like to change the label’s string value after the user has clicked on the Unveil full message button to show the true message of life. This means we need a reference to the label within our MyWindowController and as such our code listing of MyWindowController now is:
class MyWindowController < NSWindowController
attr_accessor :my_label
end
In Cocoa, such a reference is usually referred to as an outlet, in our case, representing the metaphor of “being able to plug a label object into the outlet”. C’est bon indeed!
We now need to define the action to be taken when a user has clicked on our Unveil full message button. You might be wondering right now whether or not we also need a reference to the button from within MyWindowController as was the case for the label. This however, is not necessarily the case for us seeing as the button — an instance of NSButton — is an action emitter. More specifically, an NSButton inherits from NSControl and NSResponder allowing it to receive user input (e.g. mouse events) and convert these to action events and dispatch the latter to our code. We may touch base on this subject in more detail in a later article, but for now, suffice it to say that we don’t need such a property reference.
When the button receives a mouse event from the user that is of our interest, i.e. a click event, it will convert this event into a click action and try to dispatch the action message to our code. To that end, the button expects us to provide an object with an action handler method to handle the action on delivery. In Cocoa terminology, this object containing the action handler method is referred to as the target of the button.
An action handler method in MacRuby has a distinct method signature: it is a method with one parameter named sender. It is important to adhere to this rule for action handler methods as Xcode and Interface Builder will only then recognize them as being actions.
Let’s open up our code editor in Xcode for MyWindowController.rb and change the listing to:
class MyWindowController < NSWindowController
attr_accessor :my_label
def unveil_full_message_clicked(sender)
@my_label.stringValue = "42"
end
end
Here, we’ve added the unveil_full_message_clicked action, which will change the stringValue property of our label to the true message of life. Excellent! We’ve now set up all our code, and what remains now is to tell our button to who it should dispatch its action to.
We can setup this target-action for our button programmatic, but Interface Builder provides us with a visual solution for setting these up as well. For the sake of clarity and convenience, the visual solution that we’ll go over with in a few moments enjoys our preference for now.
Hooking our MyWindowController up to our window
In the previous sections we’ve gone from designing our window to providing an implementation for our MyWindowController class. They still need to be hooked up to one another however as they are now still disjoint entities that don’t know of eachothers existence. In this section, we’ll describe how we’ll be able to hook these things up visually using Interface Builder.
In Xcode:
- Double click on MainMenu.xib to open up Interface Builder for this nib file.
As we’ve discussed earlier, objects are stored in a freeze dried manner in our NIB file that get “thawed for use” when the NIB file is loaded again. In this case, we need an instance of MyWindowController to hook it up to our freeze dried window instance.
In Interface Builder in the Library Panel:
- Type in NSObject in the search field.

- Drag and drop the Object from the panel to the MainMenu.xib window of Interface Builder. This will create a new freeze dried object in the NIB file that will be instantiated when the NIB file gets loaded in.

- Select the object.
In the Inspector panel:
- Click on the Object Identity tab.

As we can see, the object is of class type NSObject. We need to change this to be MyWindowController to let this object be an instance of that type.
- In the class identity field, type in MyWindowController.

Our object is now of type MyWindowController. Tres bien!
Now that we’ve created a freeze dried MyWindowController object, it’s time to hook it up to our window instance.
Recall from the code listing on MyWindowController that we have defined an accessor — i.e. outlet — for our label, but have not yet set this property. In particular, we need to set the my_label property of our MyWindowController instance to point to the label of our window. In Cocoa jargon, we need to “plug our window’s label into our MyWindowController’s my_label outlet”.
In the MainMenu.xib window of Interface Builder:
- Hold down the right button (or hold ctrl+click) on the MyWindowController object and drag your mouse to the label in the designer.

- Release the right mouse button above the label. A popup menu as displayed below should now appear showing you the outlets to which you can hook the label up to.

- Click on my_label in the Outlet popup menu to hook the label in the window up to our MyWindowController’s my_label property.
Our MyWindowController now knows what object it should refer to when we use @my_label in MyWindowController. What remains is to set up the target-action for our button to our controller’s action handler method. We’re almost there indeed!
To set the target-action for our button:
- Hold down the right mouse button (or ctrl+click) on the button in our window and drag to our My Window Controller object in the MainMenu.xib window as illustrated below.

- Release the right mouse button. A popup menu should now appear displaying the controller’s action handler methods we can dispatch the button’s (click) action to.

- Click on unveil_full_message_clicked: to allow the button to dispatch the click action event to this method of our MyWindowController instance.
- Hit cmd+s to save our changes in Interface Builder.
- Return to Xcode. Make sure we’ve saved all the changes we’ve made to the files here too via cmd+s.
- Hit the Build & Run button in the toolbar as we’ve done before.
Congratulations, your very first MacRuby application should now be in working order! Go ahead, click on the button to unveil the full message of life!

Epilogue
For the sake of brevity — something I know is hard to believe looking at the volume of this first tutorial — we’ve omitted a few steps you’d normally like to take into consideration.
For instance, we’ve not connected the window outlet of MyWindowController (an outlet it inherited from NSWindowController) to our window instance to allow it to manage the window. Connecting this outlet occurs in a similar fashion as was the case with connecting the label outlet by holding down the right mouse button on the MyWindowController instance and dragging it to the window instance.

Releasing the right mouse button will display a popup menu outlining the outlets we can connect the window to. Clearly we should select the window outlet here.

We’ve also not yet discussed how we can adhere to the one window per nib file, moving the window object from our MainMenu.xib to its own nib file and load it in programmatically. As mentioned before, this will require knowledge of a programming concept called delegates which we’ll discuss in our next tutorial. This will also allow us to explain the concept of File’s Owner and so on, which will require us to refine some of the techniques we’ve explained up to this point.
For now, go out and celebrate your victory of writing your very first MacRuby application.
Homework Assignment
Port the following Born to be Alive application by Johannes Fahrenkrug to MacRuby! Post your GitHub links in the comments for extra street credit
Having a hard time being able to do so? Stay tuned for our next installment in the MacRuby series with moi as we’ll dive into objective-c for rubyists!
more »
A gentle introduction to MacRuby »
Created at: 12.03.2010 15:08, source: Phusion Corporate Blog, tagged: macruby
Bonjour les amis! My name is Jean Pierre Hernandez, I work at Phusion and indeed, am a direct relative of legendary super star disco god Patrick Hernandez.
Where Patrick was born to do disco, I was born to dabble in code, in particular with Cocoa. My brother would often use a cane to emphasize his graceful dance moves, and following suit, we’ll use Ruby to emphasize our élégance and love for fine Mac application development.
It brings me enormous joy to have you here on my blog, most likely resulting from a latent hate [[[towards] angular] brackets]. That’s okay, we’ve all been there, the important thing is we’ve found out that this torture is absolutement not necessary and that verbosity and masochism are still choices when it comes to developing delicious Mac applications. Not here however, as we’ll settle with no less than élégance and beauty! Painlessly incroyable indeed!
Before we’re able to start cooking on our first of many delicious Mac applications, we first need to set up the environment where all the magic happens.
As elegant and beautiful as MacRuby may appear to the developer, make no mistake, it’s also a beast when it comes to performance. Via techniques such as Just-in-Time (JIT) and ahead-of-time compilation, MacRuby applications can achieve performance comparable to native applications. Ahead-of-time compilation in particular is useful if you would like to keep your delicious mac recipes private to a larger extend.
In order to achieve all this goodness, MacRuby employs one of the most sophisticated compiler infrastructures at this moment in the form of LLVM. Depending on your needs and intentions with MacRuby you may want to choose to compile all these components from source by grabbing it from SVN or Git. Keep in mind that in the case of the latter, LLVM is still a moving target in terms of releases and is subjected to rapid API and feature changes. It is for this reason that MacRuby is forced to use specific builds as specified in the README.
Compiling LLVM and MacRuby from source can be quite time consuming and tedious. In particular, LLVM will take about 1 hour to compile utilizing both CPU cores on a unibody MacBook Pro. Luckily, our community is blessed with nice people who made sure we could also utilize already-compiled binaries and nightlies, the latter containing nightly edge builds of MacRuby. For the sake of stability, we’d recommend you to use the former instead.
Once you’ve installed these components, we can start cooking up our first cocoa application for the mac using Ruby, which is exciting indeed!
more »
Double Shot #629 »
Created at: 19.01.2010 12:27, source: A Fresh Cup, tagged: Double Shot macruby rails
Last night's fun: a failing hard drive. Fortunately I am obsessive about backups, so this is only nuisance, not disaster.
- Discovering Rails 3 Generators - Jose Valim rounds up some of the info that came out during last weekend's BugMash.
- Getting MacRuby's Compiler to Work - Came in handy when I went a bit install-happy with rvm yesterday.
more »


