Archive for May, 2009

Conference Triathlon – Euruko, Ruby on OS X, RailsWayCon

Thursday, May 28th, 2009 by Thilo Utke

Wow, this was the month of conferences. First we visited Barcelona for the Euruko: a great conference taking place every year in a different city. We attended it the 3rd time. The talks ranged from practical like “Cooking with Chef“, over entertaining like “Fun with Ruby (and without R***s), program your own games with Gosu” to just geeky like the lightning talk about “Vimmish and how much fun gramma parsers can be”. I really liked the 2 days 1 track format and the people I met there. And you can be sure that we will be in Krakow next year too.

5 days later I visited Amsterdam for Ruby on OS X, which I already blogged about.

And a little more than a week later, until yesterday, four of us attended the RailsWayCon here in Berlin, which tries to fill the gab that the RailsConf Europe left. The first day was reserved for whole day tutorial sessions.

The second day offered a lot of advanced topics to choose from in 3 tracks. I chose to hear more about Asynchronous Processing from Mathias Meyer and the nitty gritty details about Events from Lourens Naudé. The keynote about the Present and Future of Programming Languages by Ola Bini was also very interesting.

Upstream also took an active part at the conference: Alex gave his talk about CouchDB Frameworks for Ruby and CouchApp (using his new presentation tool boom_amazing) and I introduced MacRuby, the Ruby that plays nice with Objective-C.

On the third day Yehuda Katz revealed some more details about Rails 3. The talk by Michael Koziarski about Rails Performance was good for a reality check. In the afternoon everybody was tired after 3 days of conference and the talks lost quality. Still a very good conference with potential.

Notes from the Ruby on OS X conference

Monday, May 18th, 2009 by Thilo Utke

Edit: I updated some infos, to address things Eloy pointed out in the comment.

I had the opportunity to be at the Ruby on OS X conference in Amsterdam. As the name suggests, it was a conference focused on the state of Ruby on the OS X Platform. The talks generally gave a good background about the current status and where Ruby on OS X is going. All talks will be available in video format, according to fingertips. In the meantime, here are my conference notes for a quick overview. Though they vary very much in detail, depending on my personal interest and my ability to focus after getting to Amsterdam during the night before the conference.

The first talk was about LimeChat an IRC chat program by Satoshi Nakagawa written in RubyCocoa. Some LimeChat highlights are the compact interface, its unobtrusive operation, the always-accessible server list, the build in online paste service support and the customizable themes. Satoshi pointed out some edges between RubyCocoa and Objective-C. He mentioned necessary conversion between NSString and RubyString, because they aren’t comparable, the required NSMutableString for Unicode Characters and that the creation of Ruby threads causes interruption of the application loop. Further, he reported that the usage of ruby socket lib or net/http causes hang-ups, thus he used the Objective-C equivalent libs. On the other hand he pointed out that performance was good enough, memory usage and leaks weren’t an issue either, even during longer operation. Determining factor for memory usage was the complexity of the DOM tree in the WebView backed chat window. So no major problem here. LimeChat is currently being ported to MacRuby.

The second talk was held by Rich Kilmer who presented the state of HotCocoa and MacRuby. I watched and read similar talks by him online already, so I only wrote down some interesting bits. In the beginning he gave some insight into the relation between Ruby and Apple. For example ruby gems were changed for Apple in a way that is allow to install certain gems in an extra repository where they are protected from user access. Apple will ship the next OS X version with Ruby 1.8.7. He also stated very clearly, that RubyCocoa will still be supported by Apple in the future. Which makes not much sense to me, because since the appearance of MacRuby the development is effectively come to an halt. But, as Eloy stated in the comment, Apple promised to support it into the future, because developer have put lot of effort into applications based on RubyCocoa.

Then Rich introduced MacRuby. Laurent stated during this part of the presentation, that although memory allocation is a little slower in MacRuby, Objects don’t need more Memory than their pure Objective-C counterpart. After outlining the improvements of MacRuby, Rich came to his Cocoa-mapping layer HotCocoa. HotCocoa tries to provide sensible defaults for most Cocoa GUI Objects. It also provide short names for important, mostly rather long named Objective-C Constants. All the mapping files take care of themselves to include their corresponding framework. He than explains HotCocoas delegation feature, which allows you to provide delegate methods by defining its logic in a block. A documentation for all these mappings, which can be viewed only in lib/ruby/1.8/hotcocoa/mappings until now, will be available soon.

Further, he explained the HotCocoa command line tool. Which, like the Rails script command, generates some infrastructure to build and deploy MacRuby apps from the command line. This infrastructure will be extended soon by providing a more MVC like directory structure. Another addition will be the support of a virtual file system which allow to ship self contained applications and hide the source code. At the end of his talk he mentioned the possibility to bring MacRuby code to other platforms with the use of a ahead of time compilation.

Without further ado the talk about Rucola by Eloy Duran followed. Rucola is a CLI focused MVC framework for RubyCocoa. It provides rake tasks for compiling, testing, bundling and update feed setup. Like known from Rails, it supports multiple environments. For the ease of development it offers generators for various purposes e.g. for test stubs. It also provides libs to help with testing. Rucola will also be available in MacRuby.

After the lunch-break John Shea talked about his experience with MacRuby and game programming. He just needed 2 hours to implement Tetris in 2D with NSView. Doing this in OpenGL was a little harder. He showed different other games made by him which use OpenGL and were implemented mainly with MacRuby (99%). OpenGL can be used through CoreGraphics Interface with MacRuby. That way, he achived to display 100K polygons including textures with 58.1 Frames. Also some nice particle effects implemented with MacRuby where shown. As limiting factor when using MacRuby he pinpointed the garbage collection and the method dispatch performance. Latter should be fixed with MacRuby 0.5 as Laurent stated later.

The following talk by Manfred Stienstra was about testing Cocoa Apps with the Rucola framework. As a testing framework it uses test spec together with mocha for mocking.

One major point of the talk was how to test controllers. Rucola provides methods to generate fake outlets to test the controller against. But this didn’t work with Objective-C controller. Thus as another mean a small compiler in Rucola can be used to compile and return a controller from a nib file. Working fake outlets for Objective-C Controllers will be supported as expected on MacRuby though.

Sometimes an existing application loop is required. Manfred suggested to setup and run this loop in a separate thread in the background while testing. Also the issues of UI testing came up. A practical approach was to load the nib file and inspect the content.

A less technical, but still not less interesting talk about shipping OS X desktop applications with an interpreted language was given by Koen Bok from Sofa. At first he talked about shipping the source with the product. In his experience it is better to face the legal and commercial risk by protecting the code by law than invest time and money in obfuscation. So you will be legal prepared, if problems arise, which didn’t happen so far to Sofa. The second part was targeted specifically at people who came from web development to the Mac. You should be prepared to be still a second grade citizen on the OS X platform. As Ruby people we should use our advantages of mature frameworks and tools we know from our work with e.g. rails. Third, the user experience is a major factor on OS X with a higher baseline than web applications. Thus more work is required e.g. for Drag and Drop behavior or keyboard shortcuts. Also snappiness is an important factor for the user experience at OS X. So optimizing speed/snappiness is an optimization of the user experience. The iPhone is a good example to learn from. As for the general interface design it is a good idea to have a designer in the team, or as Koen stated it. Get a Designer!

The last official talk was about Gosu, an easy-to-use game development library and Rubenstein, a satirical re-implementation of Wolfenstein in Ruby with the help of Gosu. Julian Raschke, the creator of Gosu and Ninh Bui from phusion and the author of Rubenstein, held the talk. First Ninh explained some theory about Raycasting for rendering a 3D game. Then he looked at some optimizations, like splitting the space in discreet elements of pixels to speed up the Raycasting. At last he explained how he used Gosu for texturing in Rubenstein.

Then Julian got into detail about Gosu. The library consists only of 9 classes and has a really easy to use API. It is around for 3 years already, and the main focus stayed on the easy usability. It is available for Mac, Linux and Windows (gem install gosu). Julian showed some games created with Gosu and talked how it helps to interact with other frameworks, e.g. open-gl for 2D/3D effects or Chipmunk for physics simulation. At last both demoed Rubenstein, hilarious. That marked the official end of ruby on OS X.

At the Hackfest after lunch Laurent Sansonetti, the brain behind MacRuby, showed some internals about the currently experimental 0.5 branch, which is based on LLVM. He talked about its current state, which mile stones they reached already to make MacRuby 0.5 installable, and showed some dark corners of ruby code, which make the job so hard.

I also got a glimpse on a new iPhone game from Julian made with Gosu, which looked pretty good. But before you get too excited about the thought of ruby on the iPhone, it was made with C++ version of Gosu. The Game will be officially released soon.

Later I joined Cristi, Eloy, Julian, Laurent and others for a beer and a night out in Amsterdam till I caught my train back to Berlin early in the morning.

Ruby on OS X was totally worth the effort to get there spontaneously. This rather long day I learned a lot about Cocoa and MacRuby, met very nice people, as on every ruby conference so far, and got an impression of Amsterdam that made me want to visit the city again, but than with more time.

New Couch Potato: simple, testable, opinionated.

Sunday, May 17th, 2009 by Alexander Lang

After my talk about Ruby CouchDB frameworks at Scotland on Rails where I dismissed a few of of the libraries available (including my own Couhch Potato) as not fitting the CouchDB way of doing things, I have been hacking away the past few weeks working on a complete overhaul of Couch Potato.

As a first result I have just released version 0.2 of the framework. Its new goals are simplicity, embracing the CouchDB semantics and testability. In order to achieve this I had to introduce some major changes:

I disconnected models from the database – there are no more save/get/find methods in the models. Instead you can hand the models to a database object that will save/load documents for you – this allows for unit tests that are completely disconnected from the database

I have dropped associations and thrown away all the ActiveRecord like view creation/querying, replacing it with a new, more CouchDB like system. That new system is lighter, simpler and easier to extend.

The following paragraphs will show you how to work with the new Couch Potato.

Saving / loading models

As I said I have decoupled the models from the database, a model doesn’t have permanent access to the database anymore. Instead you instantiate a database object yourself and tell it to load or save a model object. This change isn’t so much about CouchDB as it is about testability. Having the database separated means you can now have true unit test of your models without talking to the database. Here is how you save/load models:

class Book
include CouchPotato::Persistence
property :title
end

CouchPotato::Config.database_name = ‘my_db’ # in Rails this is done for you
db = CouchPotato.database

book = Book.new :title => ‘The Passionate Programmer’ # good book
db.save! book # saves the book or raises an exception

db.load book._id # the original book

The database is responsible for running the model’s validations and lifecycle callbacks, saving the document to the database and afterwards setting the _id and _rev on the model. This way a lot of the persistence related logic is removed from the models making them more lightweight and most importantly easier to test (see below).

New Views

Overhauling of the views had two main goals:

  • provide a simple and extensible way for saving/querying views that works the way CouchDB works
  • since models don’t have access to the database anymore, find a new way to query them

Here is how you create and query a simple view:

class Book
view :by_title, :key => :title
property :title
end

db = CouchPotato.database
db.view Book.by_title # no parametters
db.view Book.by_title(:key => ‘The Passionate Programmer’, :descending => true) # just use any of the parameters CouchDB accepts

The way views work is now essentially reversed (inversion of control, rings a bell?). Instead of the view method calling the database the new view method creates a specification for a CouchDB view. The view is passed to the actual database in order to query CouchDB. Again this makes testing easier (see next section) but it also gives Couch Potato a clean interface in order to make creating views easier through abstractions. There is now a hierarchy of view specification classes that you can use to more easily create and query views. The above example used the CouchPotato::View::ModelViewSpec which is the default. This spec creates a view whose map function emits one (or an array of) attribute of the model and returns full documents.

Other view specs let you create more customized views, for example the RawViewSpec, which lets you define your own map/reduce functions and return the raw CouchDB results hash.

class Book
view :title_length, :type => :raw, :map => “function(doc) emit(doc.title.length, null)}”
property :title
end

db.view Book.title_length # returns something like {:rows => [{:key => 25}]}

For more examples see the Documentation in the CouchPotato::View::*ViewSpec classes.

Testing

As I have mentioned repeatedly decoupling the database from the models makes testing easier. With the new Couch Potato you can unit test your models without hitting the database once. First of all that makes your test lightning fast, and secondly it allows you to more easily test for example your lifecycle callbacks because you can call them directly passing them a stub or mock database.

Here’s an example: (with RSpec)

class Book
property :title
property :slug
end

describe Book, ‘create’ do
it ’should generate a slug’ do
book = Book.new :title => ‘The Passionate Programmer’
book.run_callbacks :before_create
book.slug.should == ‘the-passionate-programmer’
end
end

If you don’t like calling the run_callbacks method you can also use the actual database object but without a real connection to CouchDB. Couch Potato is based on the excellent CouchRest – a more low level CouchDB framework. The CouchPotato::Database constructor expects an instance of a CouchRest database which we can replace with a stub:

describe Book, ‘create’ do
it ’should generate a slug’ do
book = Book.new :title => ‘The Passionate Programmer’
db = CouchPotato::Database.new stub(‘couchrest database’, :save_doc => {})
db.save book
book.slug.should == ‘the-passionate-programmer’
end
end

For more details and examples please see the README, the RDocs and watch this blog. If you want to know all about Couch Potato I encourage you to read through its source code and specs – it’s not that much code actually. Note that all this is still work in progress and time will show how well all of this works. I would be happy to hear your feedback.