
Apple just released a brand new, gorgeous looking Mac mini. This major upgrade brings us two different models: a desktop one and a server version (priced at $699 and $999, respectively).
Equipped with a HDMI port, the desktop edition of the Mac mini makes for a perfect Home Theater PC. It’s small and stylish, and as such is a great fit in your living room. Most of the reviews I’ve read focus on its use as a highly capable HTPC (despite its lack of a Blu-Ray drive).
However, I see the new Mac Mini in a different light. At $700 it is far too expensive for a HTPC, yet it’s ideal as an entry-level machine for web, Mac, and iOS development (it’s almost as cheap as a Hackintosh, minus the headache).
Mac Minis will do the job and be more than capable thanks to their adequate, albeit not spectacular, hardware specs. If my MacBook Pro were to die today, I would definitely consider purchasing one for development purposes. Would you?
Recently MacRuby 0.6 was released. The development team put a lot of emphasis on improving compatibility with Ruby 1.9, and the viability of MacRuby as a tool for developing Mac OS X applications. Focus on these aspects took precedence over performance, but I was still curious to see how well it performed when compared to Ruby 1.8.7 and Ruby 1.9, respectively.
This article showcases the results of a small Ruby shootout for Mac. I plan to publish a Windows one by next week, and then a week or two after that, a complete Linux shootout that will have many more implementations. Grab my feed or join the newsletter to avoid missing upcoming shootout posts.
The setup
The tests are a large subset of the Ruby Benchmark Suite. Each test was run 10 times, five to detect the best execution time, and five to detect the minimal memory consumption. All of the tests were run on Mac OS X 10.6.3, on my MacBook Pro 2.66 GHz Intel Core 2 Duo, 4 GB 1067 MHz DDR3 RAM, 320 GB 7200 rpm disk.
Stable implementations tested:
Disclaimer
Synthetic benchmarks cannot predict how fast your programs will be with one implementation or another. They provide an (entertaining) educated guess, but you shouldn’t draw overly definitive conclusions from them. Furthermore, the Ruby Benchmark Suite has many tests that don’t provide much insight when it comes to comparing implementations. They are there for legacy reasons and will probably be removed in the future. For the time being, take them with a grain of salt.
The results
Without further hesitation, here are the execution times for the tests (divided in A-L, M-Z). Timeouts indicate that the execution of a single run took more than 60 seconds and had to be interrupted. Bold values indicate the best performance for each test.


And here is the estimated memory usage:


Conclusions
MacRuby 0.6 is faster than Ruby 1.9.1 at times, but it can also be significantly slower. Overall, as things stand now, its performance appears to be between that of Ruby 1.9.1 and Ruby 1.8.7, with several outliers and a greater variance compared to those two implementations. Memory wise, MacRuby appears to be significantly more “memory hungry” than the other implementations (even though this wasn’t all that much of a surprise to me).
I’m interested in seeing how future releases that will be focused more on performance will affect these preliminary results. For the time being however, don’t let this outcome discourage you from using MacRuby 0.6, which is the first release that’s considered stable for Mac OS X development.
Download: CSV Files
PS: If you are looking for a fun and easy way to get started with MacRuby, check out ThinkCode.TV’s screencast on the subject.
Update (July 3, 2010): The following box plot compares the various implementations for the tests for which all the implementations were successful. Only times for the largest successful input number were used in those tests where multiple input numbers were tested.

Tomorrow the iPad goes on sale in the States. Announced in January, the iPad sits squarely between a laptop and an iPod Touch. Large lines are expected to form in front of Apple Stores across America; ants scurrying to grab their crumbs.
What is uncertain is whether this release is going to be much ado about nothing or more an event that will revolutionize the computer market.
Among the iPad shortcomings are the following:
Your first impression might be that we are dealing with a flop like the Apple TV or similar niche products that are popular with Apple fans, but lack the transformational power and impact on society that have been shown by the iPod or the iPhone.
Much of the iPad’s criticism comes from a fundamental misunderstanding of the target use of this product. Those who consider the iPad a replacement for their laptop will no doubt be disappointed by the performance and restrictions of this device.
One also needs to take into consideration the iPad’s target audience. Many assumed that the target audience was primarily composed of geeky early adopters, programmers, and more in general, people with a technical mindset.
Far from telling my readers that they shouldn’t indulge in the prohibited pleasure of possessing an iPad, it seems clear to me that the Gaussian function has its maximum elsewhere, amongst students, casual users, and the general public, who want a device from which to check their email, surf, and play from their couch, kitchen or local coffee shop. A computing device that is small enough to carry in a purse, but large enough (with its 9.7" diagonal) to easily display websites and applications, without causing one to squint their eyes.
Seen in this light, the iPad has a solid reason for being, despite all of its limitations. Imagine a computer that is accessible and easy to use, and doesn’t require IT support from your nephew to fix (or remove a virus). In other words, a portable device that simply works. It only does a few things, but it does them in a manner that provides a pleasant experience to the average user.
The iPad’s field of application isn’t very restricted either. It can be seen as a portable console for casual gaming, a digital frame to show photos set to a soundtrack, or a quick presentation tool at a small business meeting. It’s a multimedia tool for listening to music and watching videos and lectures. Finally, the iPad is also a magazine and ebook reader. Some may rightfully argue that the e-ink technology is easier on the eyes for extensive reading, but the iPad has a vibrant color screen, and is able to display complex PDFs as well as ePub books sold directly from the brand new iBookstore.
The design, as is customary for products designed by Jonatahn Ive, is minimalistic, sleek and easy on the eyes. Starting at $499 (as shown in the figure below), the price point is rather competitive, so as to be able to reach a wide, international audience.

All things considered, it’s easy to imagine that the iPad will be a commercial success with the potential to transform how millions of consumers approach the Internet, gaming and book reading. This is far from certain, but I suspect that the iPad will be the iPod of the laptop world.
My suspicion is further supported by the ecosystem that surrounds this form of lightweight computing. Teachers will love the possibilities that such a device opens up, where students can now have a more interactive and multimedia-driven experience (particularly if ad hoc applications are created for this).
Book and magazine publishers already love the idea of selling books through the iBookstore, a refuge from the totalitarian price policies imposed by Amazon. This could in turn, really increase publishers’ investment in the digital world.
Programmers will be able to explore new ideas and create applications that are specifically tailored to the iPad user interface and user experience. The many advantages, and few disadvantages, of this approach are well known thanks to the iPod Touch and iPhone experience.
While restrictions are obviously limiting, they can also foster creativity. Among a sea of silly gag applications, there were also truly innovative apps designed for the iPhone. I would expect nothing less from applications developed using the same tools and distributed through the same channels, but targeted to a device that has much larger screen and processing capabilities.
Personally, I don’t know if I will purchase an iPad or not, after all I spend far too many hours in front of a traditional laptop already. But I clearly see a brilliant future for this new Apple product, despite its limitations and the closed approach to hardware and software that has become typical of Cupertino’s company.
What about you, are you headed to the Apple Store?
There is major news in Rubyland today. MacRuby’s team just released their fist beta of version 0.5 (an experimental, still incomplete version of Ruby), which brings JIT, removal of the dreaded GIL (Global Interpreter Lock), native threads, GCD (Grand Central Dispatch) for multicore computing, and a whole new set of features found in the release announcement to the table.
The most important new feature is the presence of a compiler. That’s right, thanks to this release, Ruby code can now become highly optimized executable code. How awesome is that? I can sense that you’re pumped by this news, so why not head over to MacRuby.com and download the installation file for yourself? After you’ve done that, the next thing you’re going to want to do is run a small test like the following:
$ macrubyc world_domination.rb -o world_domination
Can't locate program `llc'
Oh noes! llc is a tool that ships with the LLVM (upon which MacRuby is built), however it’s not included with MacRuby’s installer (it will be in the future). But fear not my friends, there is a solution:
$ svn co -r 82747 https://llvm.org/svn/llvm-project/llvm/trunk llvm-trunk
$ cd llvm-trunk
$ ./configure
$ UNIVERSAL=1 UNIVERSAL_ARCH="i386 x86_64" ENABLE_OPTIMIZED=1 make -j2
$ sudo env UNIVERSAL=1 UNIVERSAL_ARCH="i386 x86_64" ENABLE_OPTIMIZED=1 make install
If your machine does not have 2 cores, remove the -j2 option from the fourth line or adjust the number accordingly.
The compilation phase may take a couple of centuries, depending on your machine’s speed, but it should eventually build the LLVM.
llc will be placed in your PATH, and you’ll finally be able to compile Ruby code and obtain an executable to help you carry out your world domination plans.
$ macrubyc world_domination.rb -o world_domination
$ ./world_domination
MUAHAHAHAHA!
Now that Mac OS X 10.6 is out, it’s time to leave the world of 32 bit computing behind. The pre-installed Ruby interpreter will run in 64 bit mode by default, so you may need to pay attention when installing some C-based gems. The ibm_db Ruby gem for DB2 can easily be installed or updated to the latest available version by following these simple steps:
$ sudo -s
$ export IBM_DB_LIB=/Users/<username>/sqllib/lib64
$ export IBM_DB_INCLUDE=/Users/<username>/sqllib/include
$ export ARCHFLAGS="-arch x86_64"
$ gem install ibm_db
You can verify that the installation was successful my running the following:
$ irb
>> require 'ibm_db.bundle'
=> true
Please let me know if you encounter any issues, I’d be glad to help you.
Earlier today I headed over to the local Apple Store to purchase a copy of Snow Leopard, the newest version of Apple’s operating system. There was a decent line up, as I expected. Not the kind of line up you’d encounter with the launch of a new iPhone, but it was fairly busy for a Friday morning. When I arrived, I took my place at the end of the queue where rumors were swirling around about the store having sold out of single copies of Snow Leopard in its first hour. Luckily, that was just a rumor as I suspected, and they still had a few copies left. So I got my copy for $39.99 (CND) including taxes and left.
The installation was pretty much automatic and took roughly an hour. No versions to select from, no serial numbers to insert, no online activations, and a price that “keeps honest people honest”. Yes, it’s just an update, but $25 (US) for an improved operating system is definitely a fair price. Microsoft are you listening? My first impression is that Snow Leopard is a very polished version of Leopard and it’s darn fast. Well done Apple.
DB2 users may be wondering if it is safe to install this version of Mac OS X 10.6 or if their existing installation will go awry. I’m happy to report that DB2 Express-C 9.5 FixPack 2 for Mac works fine on Snow Leopard. Both pre-existing installations and brand new installations of DB2 work properly, I can attest to that. So install away my friends!

Recently I sold my old, damaged MacBook Pro on eBay, and in doing so I claimed that there was a chance that it could be repaired (by Apple) for free. But how, you may be wondering, could I make such a bold claim? Was it all a strategy to over-sell my broken laptop? Not in the least. Back when I first found out about this Apple’s KB article, the contents of which appeared as though they would entitle me to a free repair, I headed straight to the Apple Store at the Fairview Mall in Toronto. I’d had a fairly positive customer care experience there just a week before, and I was rather optimistic that they’d repair it for me.
After I arrived at the Genius bar, I had to wait for quite a while before having the displeasure of dealing with an uncooperative “genius”, a young guy whose unfriendly attitude far outweighed any technical know-how he may have had. He immediately denied any knowledge of video issues on MacBook Pros from 2007 and only agreed to check my laptop after I’d showed him a printout of the knowledge base issue mentioned above. He essentially humored me in a rather reluctant way, and after a very short while told me that my laptop didn’t qualify for the free repair. Annoyed by this guy’s lack of care regarding my problem, I left the store.
Around the time when this situation arose, I had already visited the Genius Bar several times regarding various matters and was feeling a bit tired of dealing with a broken laptop. Ultimately I gave up on my old MacBook Pro (my first Mac ever) and when it was economically possible, I purchased a replacement laptop. Though my old MacBook Pro had cost me time and money, I felt that its tale was done and over with once I brought my new laptop home. That is until the day I decided that someone else could get more use out it than I was (as it was just sitting unused in my office), and that I could get a few bucks by selling it on Ebay. The old Mac’s auction wrapped up with a selling price of $578. It was bought by a fellow from Ontario, who was a very pleasant person to deal with.
If fact he was so kind that he sent me a follow-up regarding his own attempt to get the laptop fixed. Here’s what he wrote:
Just a quick update. The testing on the Macbook Pro was conducted this week, and found to conform to the warranty exception Apple identifies with the nVidia chip problem. A replacement is being installed now, but likely won’t be ready until next week. While you’re probably more content to wash your hands of the whole matter, I’d seriously consider a complaint against the apple store you took it to, and more specifically against the “genius” who served you, given he was clearly no genius at all, and likely cost you significantly in time and money as a result. Hope you’re having a good day.
I am genuinely happy for the guy. He took a risk by buying a broken laptop from me, trusted my story to be true (as it was!), and ended up scoring a working laptop that’s (now) worth far more than what he paid for it. His bet paid off and I wish him all the best.
The truth of the matter is that, as he says, I’m glad to “wash my hands of the whole matter”. At this point there is little Apple would do, even if I made a fuss about it (which I’m not going to, of course). Next time I walk by that particular Apple store, I may have a word with the manager (regarding the Genius I’d dealt with), but that’s about it.
The moral of the story is not that Apple’s customer care sucks or rocks. Apple Genii are just people, some are very good, others exceptionally bad, and most of them are somewhere in between. The take-home lesson for me here was that when dealing with Apple, if you get turned down by one store, you shouldn’t stop there! Take the time to visit a couple more and to persue the matter as far as you can.
A few days ago I placed my old MacBook Pro up for auction on Ebay, with a starting price of $200 and no reserve. While the auction has generated interest, so far there has been only one bidder. The auction ends in a little over two days. If you are interested, please read the description carefully and then bid with confidence. Despite being damaged, a laptop like this is still worth a few hundreds dollars due the sheer amount of working parts in it (CPU, memory, hard-drive, LCD matte screen, new battery, MagSafe adapter, remote control which works with new models too, etc…). It could be used as an extra Mac in your arsenal if utilized through Remote Desktop or repaired. There is also a chance that it could be repaired for free by Apple (though of course I cannot guarantee this point).
Counting rows is an ubiquitous operation on the web, so much so that it’s often overused. Regardless of misuse, there is no denying that the performance of counting operations has an impact on most applications. In this post I’ll discuss my findings about the performance of DB2 9.5 and MySQL 5.1 regarding counting records.
For those of you who are not into science fiction, let me clarify that the odd title of this post is a tongue-in-cheek reference to the great novel, Do Androids Dream of Electric Sheep?.
I connected to the database, created the table, imported the data and benchmarked counting operations using ActiveRecord in a standalone script. Here is the code I used:
#!/usr/bin/env ruby
require "rubygems"
require "active_record"
require 'benchmark'
ActiveRecord::Base.establish_connection(
:adapter => :mysql,
:username => "myuser",
:password => "mypass",
:database => "mydb")
ActiveRecord::Schema.define do
create_table :people, :force => true do |t|
t.string :name, :null => false
t.string :fbid, :null => false
t.string :gender
t.string :profession
end
end
class Person < ActiveRecord::Base
end
# This can be sped up by performing an import instead
Person.transaction do
File.open("person.tsv").each_line do |line|
line = line.split(/\t/)
p = Person.new
p.name = line[0]
p.fbid = line[1]
p.gender = line[6]
p.profession = line[17]
p.save!
end
end
n = 100
Benchmark.bm(26) do |x|
x.report("Count all:") { n.times { Person.count } }
x.report("Count profession:") { n.times { Person.count(:profession) } }
x.report("Count females:") do
n.times { Person.count(:conditions => "gender = 'Female'") }
end
x.report("Count males w/ profession:") do
n.times { Person.count(:profession, :conditions => "gender = 'Male'") }
end
end
Please note that importing records in a huge transaction containing hundreds of thousands of INSERT operations is far from the most efficient way to import. Massive imports of data using the load/import facilities provided by each database is the way to go (also see the ar-extensions plugin). The lengthy import wasn’t benchmarked here though, so it isn’t determinant for this article.
people.tsv is a 92.7 MB tab separated values file that contains 875,857 records from the Freebase project (in my file I removed the header line, leaving only records).
For those who are not familiar with ActiveRecord, the queries executed behind the scenes are (in order):
SELECT count(*) AS count_all FROM people
SELECT count(people.profession) AS count_profession FROM people
SELECT count(*) AS count_all FROM people WHERE (gender = 'Female')
SELECT count(people.profession) AS count_profession FROM people WHERE (gender = 'Male')
While the table definition (for MySQL) is:
CREATE TABLE `people` (
`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`name` varchar(255) NOT NULL,
`fbid` varchar(255) NOT NULL,
`gender` varchar(255),
`profession` varchar(255)
) ENGINE=InnoDB
As easily verified by enabling logging with:
ActiveRecord::Base.logger = Logger.new(STDOUT)
Without much further ado, here are the times I obtained on my last generation MacBook Pro 2.66 GHz with 4 GB DDR3 RAM, and 320 GB @ 7200 rpm hard disk, running Mac OS X Leopard:
MySQL:
Count all: 42.467522
Count profession: 52.130935
Count females: 54.575469
Count males w/ profession: 64.046631
DB2:
Count all: 5.818485
Count profession: 7.714391
Count females: 8.556377
Count males w/ profession: 9.656739
Or in graph form:
That’s an impressive difference. To be exact, in this example DB2 was between 6 and 7 times faster than MySQL. In the case of COUNT(*), DB2 counted almost a million records in 58 milliseconds, or in about the blink of an eye according to Wolfram Alpha.
For those who are skeptical, please note that DB2 was not manually fine-tuned in any way. The client codepage was set to 1252 to allow Greek letters, and the log size was increased to permit such a huge transaction during the import. That’s it, no optimizations were attempted. This is DB2 Express-C out of the box. It looks like smart androids count electric sheep with DB2 after all.
The advantages of DB2 over MySQL when dealing with a massive volume of traffic are well known (and not limited to performance either), but DB2 can dramatically improve performance even for your average web application. And DB2 9.7, which will be released this month, increases the performance and the ability to self-tune itself to the available resources and required workload even further. If you’d like to try DB2 Express-C for yourself, you can download it here. It doesn’t cost you a dime to obtain and can be used for development, testing and production absolutely free of charge.
Before leaving on a recent business trip to Italy I begun working on a TextMate bundle for DB2. Here I’ll introduce it in the hope that it will interest some TextMate and DB2 users.
Installation
There are two simple prerequisites for using this bundle: 1) Install DB2 as a regular user (not root); 2) Source the db2profile by, for example, adding . ~/sqllib/db2profile to your shell profile (e.g., in ~/.profile). Both of these will ensure that your user is able to issue DB2 commands.
To install the bundle, you can run the following (assuming you have git installed):
sudo mkdir -p /Library/Application\ Support/TextMate/Bundles
cd /Library/Application\ Support/TextMate/Bundles
git clone git://github.com/acangiano/db2-textmate-bundle.git "DB2.tmbundle"
Alternatively, you can download this file, unzip it and then double click on the DB2.tmbundle that was extracted. Of course, the previous method has the advantage of being able to easily update the bundle through git pull.
If TextMate is running while you executed the previous step, you may want to also execute the following line:
osascript -e 'tell app "TextMate" to reload bundles'
This is equivalent to selecting Bundles ? Bundle Editor ? Reload Bundles from within TextMate.
Using the bundle
If you followed the instructions above, at this point you should see a DB2 menu under Bundles:

TextMate is a text editor, and as such it expects you to have an open document, in order to execute commands from this bundle. The good news is that an empty, untitled, open by default window will suffice.
As you can see from the image above, you can start the DB2 server, stop it, run an arbitrary query or DB2 command and open up the Information Center for DB2 9.5 in your browser. Below the separating line there are also two submenus, Database and Tables.
Let’s consider Database first:

Within the Database menu we can connect to a database (this step is required before being able to query a database), disconnect, create a database, drop it, and create the SAMPLE database that ships with DB2 so you can get some practice.
Likewise, while it’s at a very early stage of development, we have the Tables submenu:

So far we can list the tables within the database we are currently connected to, and drop an existing table.
You can use the Shift-Command-D combination to bring up a convenient contextual menu of the most common tasks, while you are within a document (unless you are editing an HTML file, in which case that combination brings up Safari):

The result of each command executed is flashed to the user in the form of an informative tooltip:

Conclusion
The aim of this bundle is to provide a more convenient way to work with DB2 without having to switch between your coding editor and the command line. It’s admittedly just a “seed”, a very early effort, but I sincerely hope that even at this stage it can be useful to some people. Being an open source project that’s released under the MIT license, you are free to contribute to it and more than welcome to fork it on Github as well.
Over the weekend I recorded a screencast on how to install DB2 on Mac OS X. You can watch it below:
The blog post I reference within the video can be found here. Yes, that’s an Italian accent. I hope you don’t mind it.
Over the years the inadequacy of Ruby’s main implementation has led to the creation of several alternatives. The greatest common divisor between these is an attempt to improve the performance of Ruby, both in terms of time and space. But every Ruby implementation has another, deeper reason for being. For example, Ruby 1.9.1 is a refactoring of the language that provides the chance to incorporate several much needed features into a relatively fast virtual machine, whereas JRuby’s truest value lies in its ability to interact with the Java ecosystem. Likewise IronRuby (which is admittedly at an earlier stage in its development) is attempting to plug a dynamic language like Ruby into the .NET world (as per its predecessor IronPython).
While MacRuby is a younger, lesser known implementation, it has the potential to become a game changer – at least for Mac developers. Based on Ruby 1.9, MacRuby’s main aim is to provide programmers with the ability to write Mac OS X applications in Ruby, making Ruby a first class Cocoa programming language. In what may sound like an utopistic effort, MacRuby strives to provide the high level abstractions, power and syntax sugar of Ruby, without the characteristic performance hit of its main implementation.
Rather than relying on a mix of Objective-C and Ruby (through a bridge like RubyCocoa), developers can use MacRuby which integrates with Mac OS X core technologies and acts as an alternative language to Objective-C. To be exact, Objective-C’s runtime and generational garbage collector are at the heart of MacRuby, but from an API standpoint, programmers can write code in Ruby, instead of in the more verbose and low level Objective-C. MacRuby maintains the ability to integrate with Objective-C code, but doing so is often unnecessary thanks to a framework known as HotCocoa, which is a Ruby wrapper around the Cocoa API.
MacRuby applications end up being succinct, easy to write and straightforward to maintain. Their look and feel is exactly the same as those of applications written in Objective-C, because they are actually native Cocoa applications. In fact, MacRuby objects are Objective-C objects which use Core Foundation data types and services. The current version, MacRuby 0.4, even allows you to package applications as self-contained .app, without having to redistribute MacRuby itself.
Sponsored and developed by Apple, MacRuby 0.4 is a stable release that can be – and already is – used to write desktop applications. But MacRuby’s real promise lies in its experimental branch. This rewrite will become MacRuby 0.5, as announced by the MacRuby team earlier today (along with a new, nice looking site). This future version of MacRuby is freakishly fast and uses the LLVM to generate code for the Objective-C runtime. The layer composed of LLVM, ObjC Runtime, Generational Garbage Collector and Core Foundation make this specific Mac OS X release possible. To this layer, add in Ruby 1.9′s AST parser and Standard Library, and you get MacRuby 0.5 as it stands today. In the future it’s likely that applications built with MacRuby will be compiled into binary code, like Objective-C ones, thus removing the issue of protecting one’s source code in commercial applications.
To really understand the value of MacRuby, consider the following Hello World program that uses RubyCocoa:
require 'osx/cocoa'; include OSX
app = NSApplication.sharedApplication
win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(
[0, 0, 200, 60],
NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask,
NSBackingStoreBuffered, false)
win.title = 'Hello World'
button = NSButton.alloc.initWithFrame(NSZeroRect)
win.contentView.addSubview(button)
button.bezelStyle = NSRoundedBezelStyle
button.title = 'Hello!'
button.sizeToFit
button.frameOrigin = NSMakePoint((win.contentView.frameSize.width / 2.0) - (button.frameSize.width / 2.0),
(win.contentView.frameSize.height / 2.0) - (button.frameSize.height / 2.0))
button_controller = Object.new
def button_controller.sayHello(sender)
puts "Hello World!"
end
button.target = button_controller
button.action = 'sayHello:'
win.display
win.orderFrontRegardless
app.run
And compared to the equivalent MacRuby and HotCocoa program:
require 'hotcocoa'
include HotCocoa
application do |app|
win = window :size => [100,50]
b = button :title => 'Hello'
b.on_action { puts 'World!' }
win << b
end
The first approach reminds me of Objective-C, the second is a pure Ruby DSL.
The question on many readers minds is probably, how fast is it? To begin with, the start-up time is negligible which is a good quality for desktop applications to have. Using the YARV tests that ship with the experimental branch, let me show you the numbers I obtained on a Mac Pro with two Quad-core Intel Xeon 2.8 GhZ and 18 GB of RAM. The tests were also run on much less “beefier” hardware with analogous results.
All the usual disclaimers apply here. These are just a few very basic micro-benchmarks that should give you a “feel” for how two VMs stack up against each other; but don’t read too much into this and don’t expect it to be a scientific report on the performance of the implementations that were tested. Also keep in mind that MacRuby 0.5 is currently an experimental release, and while it’s able to pass RubySpec’s language specifications, it is not a complete implementation so far. The team is taking incompatibility issues seriously though and will make sure MacRuby will be able to run any Ruby code.
The following table summarizes the results of these benchmarks for Ruby 1.8.6, Ruby 1.9.1 and MacRuby 0.5:

This table shows the ratios between Ruby 1.9.1 and MacRuby 0.5, respectively, against the Ruby 1.8.6 baseline. When you see a number 4, for example, that means that the given implementation was four times faster than Ruby 1.8.6.

And here is a direct comparison between Ruby 1.9.1 and MacRuby 0.5. In this case, a number 4 (for example) would mean that MacRuby was four times faster than Ruby 1.9.1 for the given test:

The following chart should help you better visualize the results shown in the first table (click on it to enlarge the picture):
Even when you consider the disclaimer above and the trivial nature of the benchmarks themselves, it’s clear that at this stage of the game, MacRuby 0.5 is built for speed. the fastest Ruby implementation around. MacRuby literally dominates Ruby 1.9.1. On “average”, according to these limited tests the experimental branch of MacRuby appears to be roughly 3 times faster than Ruby 1.9.1 (YARV), and in some cases even faster than that. You should definitely find this impressive.
For full disclosure, I’d like to explain the most likely reasons behind the four tests in which MacRuby is slower than Ruby 1.9.1:
MacRuby is a serious project that fits in, and serves the flourishing market of Cocoa applications well. Its experimental branch is a major rewrite that, grants this implementation the title of fastest Ruby in the West that, much like Unladen Swallow for CPython, could become a very fast alternative to Ruby 1.9.x and JRuby. It’s mainly aimed at the desktop world, and as such the question of when it will work with Rails, is less pressing than it was in other early Ruby implementations. What’s certain is that Ruby is going to become a first class “scripting” language and a common choice for desktop applications on Mac. And should the difference in performance still remain in future, stable versions, it’s not hard to imagine that Apple’s server segment could also benefit from this, when Rails support becomes available.
Update (2009-04-04): I’ve modified a controversial statement since, technically speaking, while it is true that a very fast, incomplete implementation is promising and worth getting excited about, it cannot be considered the fastest Ruby implementation until a great degree of compatibility has been reached. This doesn’t diminish the value of MacRuby in any way, but rather draws a more accurate conclusion about the data that’s available today. It’s also worth noting that the few benchmarks that have been mentioned here are only part of the story. Speed aside, MacRuby’s aim and potential for Mac development still stand.
The image at the top of the post was generated by James Reynolds with HotCocoa::Graphics, a Processing-like library that uses Mac OS X’s graphics capabilities and makes them available to MacRuby.
A little over a week ago IBM released a new version of the DB2 beta for Mac OS X Leopard, following up on valuable feedback that we’d received in response to earlier versions. This version is important because it resolves a reported issue that was occurring when building drivers for languages like Ruby and PHP. Hence, I highly encourage you to download the latest DB2 for Mac now and save yourself the hassle of this issue.
The installation procedure is fairly straightforward, but I’ll spare you from having to read the “Installing and setting up DB2 for Mac OS X” PDF by providing some easy steps here.
Install DB2 on Mac
Step 1: Increase your system’s parameters by creating or editing /etc/sysctl.conf. Add the following parameters, save the file, and reboot your machine.
kern.sysv.shmmax=1073741824 kern.sysv.shmmin=1 kern.sysv.shmmni=4096 kern.sysv.shmseg=32 kern.sysv.shmall=1179648 kern.maxfilesperproc=65536 kern.maxfiles=65536
Step 2: Download and extract DB2 Express-C for Mac OS X. To extract the file you can run tar -xvzf db2exc_952beta_MAC_x86_64.tar.gz from a terminal. cd into the extracted folder by running cd exp.
Step 3: Run sudo ./db2setup and follow the wizard that appears. (Note that this step assumes that you have Java 1.6 installed.)
If you’d like specific instructions on installing Ruby and Rails, take a look at my previous post about this subject.
Give us your feedback
Try out DB2 on your Mac, experiment with it, and let us know what you think. Tell us what are your impressions, what you like, what you dislike, and what you’d want to see in future releases. Write me at cangiano{{AT}}ca.ibm.com, and I’ll be happy to hear from you. If this release is particularly important to you and you’re able to speak on behalf of your company, do feel free write as well, we are definitely looking for testimonials – and such letters could prove to be free exposure for your company as well. If you use DB2 on Mac in an interesting way, let us know about it. We truly value your opinions and are looking forward to hearing about how DB2 on Mac affects you.
As pre-announced in my two previous posts, DB2 for Mac OS X Leopard is finally available for download. It’s now official, DB2 on Mac is here.
Reflections on DB2 on Mac
Several people, including myself, would happily ditch their virtual machines and start introducing DB2 into their native Mac development stacks. But this milestone represents much more than the immediate implications would have us believe. A few years ago, the idea of giving away DB2 for free would have been met with rejection. Yet, DB2 Express-C came along, and unlike the other “express” databases, it’s a true production-ready DB2 version that can be used free of charge.
Likewise, the idea of having a DB2 version for Mac was unthinkable up to a few years ago. Yet today we finally have a copy of DB2 Express-C for Mac OS X that’s available for download. Aside from this being an acknowledgment of the growing importance of Mac as a development and business platform, I feel it underlines IBM’s ability to change. The desire that a few of us mac addicts had, coupled with reasonable pressure from the community, was sufficient enough to make DB2 on Mac a reality. This matters and appeals to both the developer and the technical evangelist in me.
In the list of downloads, you’ll notice that the Mac download is only 138 MB, versus the 412 MB of Linux’s 64-bit. The reason for this difference is that DB2 Express-C for Mac currently ships in English only, and at this stage it doesn’t include either DB2 Text Search or the Java based tools like the DB2 Control Center. This lighter package is, in my opinion, a welcome side effect of this brand new beta release.
Getting started with DB2 and Rails on Mac OS X
Since the first download went live on Friday, a newer release that includes a guide for installing DB2 on Mac OS X was published and it incorporates a few changes that will make the lives of developers easier, as they approach building and using drivers (e.g. the ibm_db Ruby gem). If you downloaded this beta version over the weekend, do not worry: just grab – and execute – this shell script (e.g. sudo fixlib.sh). If you are downloading DB2 on Mac now, you won’t need this script of course.
Once you’ve downloaded DB2 for Mac OS X Leopard, please proceed to read this PDF guide, which will tell you everything you need to know (and more) about installing DB2 on your Mac, as well as providing extra details. It’s best not to skip over reading this document, as the installation on Mac OS X requires a few more steps than simply running the setup wizard.
With DB2 installed and started (sudo db2start), and the SAMPLE database created (db2sampl), you’re ready to start playing with this power horse. For details about SAMPLE’s structure you can read this article in the InfoCenter.
To run the DB2 console (known as the Command Line Processor or CLP for short), run:
$ db2
To connect to the SAMPLE database, from within the CLP run:
db2 => connect to sample
Unless you get an error, you should now be ready to query the database. For example, run the following query:
db2 => select count(*) from staff
Then to exit from the CLP, simply run:
db2 => quit
If this sanity test worked well you can proceed with installing the ibm_db gem (which includes the Ruby driver and the Rails adapter for DB2). To do so, run the following, adjusting the path to your own username of course:
$ sudo -s $ export IBM_DB_INCLUDE=/Users/acangiano/sqllib/include $ export IBM_DB_LIB=/Users/acangiano/sqllib/lib32 $ export ARCHFLAGS="-arch i386" $ gem update --system $ gem install ibm_db $ exit
The ibm_db gem will be installed on your system and is ready to be used. To verify that this is the case, run a small Ruby program with the following code:
require 'rubygems'
require 'ibm_db.bundle'
conn = IBM_DB.connect("sample","my_username", "my_password")
if conn
stmt = IBM_DB.exec(conn, "select count(*) from staff")
count = IBM_DB.fetch_array(stmt)[0]
puts "The staff table contains #{count} records."
else
puts "Connection error: #{IBM_DB.conn_errormsg}"
end
If everything is fine and dandy, you should see the message “The staff table contains 35 records.”.
Now that Ruby can talk with DB2, we can move on to Rails. Assuming you have Rails 2.2.x installed, run the following to create a sample bookshelf application:
$ rails books -d ibm_db
This generates a Rails application (as usual) with a config/database.yml file customized for DB2. You’ll notice that unlike with MySQL, the database names are not books_development, books_production and books_test. The names are truncated by default due to the fact that DB2 currently only allows for database names that are up to 8 characters long. Feel free to change the development database in database.yml simply to ‘books’.
As a Rails developer you may also be accustomed to running rake db:create to automatically create the development database, yet this feature is not available for DB2 at this point, so instead you can create the database using the db2 command, as follows:
db2 create database books
DB2 allows you to specify all kinds of options for the creation of databases, but in its simplest form, the line above will work just fine.
Once the development database has been created, you should be able to use Rails with DB2 as you normally would with other database management systems. For example, you could scaffold a resource as follows:
$ ruby script/generate scaffold Book title:string author:string isbn:string description:text loaned:boolean
Start the webserver with:
$ ruby script/server
And then visit http://localhost:3000/books to perform CRUD operations on book records.
At this stage, the only caveats are that you’ll have to use the db2 command, rather than ruby script/dbconsole, and that you won’t be able to use the rename_column method in your migrations. On the plus side, you’ll have the XML datatype (t.xml in your sexy migrations) at your disposal, to natively store XML documents and retrieve them through XQuery and SQL/XML.
I really hope that you’ll enjoy DB2 on Mac! Don’t be afraid to ask for help, if you need it, in the DB2 Express-C forum. Oh and we are trying to get the word out there. Your help is highly appreciated. You can promote this story on Twitter, Hacker News, Reddit, DZone, StumbleUpon and Digg.
Disclaimer: The opinions expressed in this post are mine and mine alone, and do not necessarily represents the opinions of my employer, IBM.

This is not an official announcement, but I must share the news with you. DB2 Express-C for Mac OS X Leopard will finally be shipping out (before Christmas), in all likelihood it could be as soon as early next week. You may recall how more than a year ago I blogged about how the work on porting DB2 to the Mac had started. It took admittedly longer than expected but DB2 on Mac is coming, and is absolutely free of charge, of course. The team is still playing with the bubble wrap, but DB2 on Mac is a reality.
What took IBM so long? DB2 is a database management system that’s highly optimized for each platform that it’s available for, so that it can take full advantage of the operating system at hand. In other words, porting DB2 from one platform to another, is not so trivial. The task is made more challenging by the extremely high standards set by IBM. You may be familiar with the whole scandal surrounding MySQL 5.1, which was released despite known fatal bugs. Something like that is simply not acceptable to IBM. Each release of DB2 has to go through a huge amount of regression and performance tests – for months. If the product does not pass all these tests and others, then DB2 is not shipped.
On top of this, a few months ago the decision to ship DB2 Express-C 9.5.2 (rather than 9.5) was made, and as you probably know, DB2 Express-C 9.5.2 was only released a little while ago for other supported platforms. So the first piece of good news is that you’ll get the latest version of DB2 on the Mac. It’s going to be a 64 bit version and will require Leopard to work:
$ db2level DB21085I Instance "acangiano" uses "64" bits and DB2 code release "SQL09052" with level identifier "03030107". Informational tokens are "DB2 v9.5.0.2", "s081205", "DARWIN64", and Fix Pack "2". Product is installed at "/Users/acangiano/sqllib".
The second good thing is that unlike MySQL 64 bit, you won’t have to jump though hoops to build the Ruby driver due to the fact that the database is 64 bits and Ruby ships on Leopard as 32 bits. We ensured that gem install ibm_db would work out of the box, so you don’t have to.
According to Apple, my personal Mac is broken for good (the video chip is dead), which is very bad timing. But I installed DB2 and played around with it on a work Mac Pro machine. I had some fun with Ruby and Rails as well. This is great news for many categories of developers, including those who have been trying to convince their managers to get them a MacBook Pro but didn’t have much of a case due to the lack of availability of a DB2 version. Now, you’ll have a good excuse to get yourself a Mac.
Stay tuned for the official announcement and keep in mind that this is going to be a beta (perfect for development purposes) and extra features and performance improvements will be added in future releases.
Disclaimer: The opinions expressed in this post are mine and mine alone, and do not necessarily represents the opinions of my employer, IBM.
The long awaited Ruby virtual machine shootout is here. In this report I’ve compared the performances of several Ruby implementations against a set of synthetic benchmarks. The implementations that I tested were Ruby 1.8 (aka MRI), Ruby 1.9 (aka Yarv), Ruby Enterprise Edition (aka REE), JRuby 1.1.6RC1, Rubinius, MagLev, MacRuby 0.3 and IronRuby.
Just as with the previous shootout, before proceeding to the results, I urge you to consider the following important points:
All of the Ruby implementations that were able to run the current Ruby Benchmark Suite have been grouped together in one main shootout. This group consists of Ruby 1.8.7 (p72, built from source, and installed through apt-get), Ruby 1.9.1 (from trunk, p5000 revision 20560), Ruby Enterprise Edition (1.8.6-20081205), JRuby 1.1.6RC1 and Rubinius (from trunk), all of them were tested on Ubuntu 8.10 x64, plus Ruby 1.8.6 (p287. from the One-Click Installer) on Windows Vista Ultimate x64. The hardware used for this benchmark was my desktop workstation with an Intel Core 2 Quad Q6600 (2.4 GHz) CPU and 8 GB of RAM. JRuby was run with the -J-server option enabled and by specifying 4 Mb of stack (required to pass certain recursive benchmarks). The best times out of five iterations were reported, and these do not include startup times or the time required to parse and compile classes and method for the first time. Several of these new tests also have variable input sizes.
The MagLev team provided me with an early alpha version of MagLev for the purpose of testing it in this shootout. Since this VM is not mature enough yet to run the Ruby Benchmark Suite, I used custom scripts against an old version of the Ruby Benchmark Suite on Ubuntu 8.10 x64. MagLev was tested, along with Ruby 1.8.6 (p287), on the same machine as that of the main shotoout, though the benchmarks were different (even when they had the same names as the ones in the main shootout).
MacRuby 0.3 and Ruby 1.8.6 (p114) were tested on Mac OS X Leopard using the previous version of the Ruby Benchamrk Suite. Since my MacBook Pro died (sigh), for this benchmark I used a Mac Pro, with two Quad-Core Intel Xeon 2.8 Ghz processors and 18 GB of RAM.
IronRuby (from trunk) and Ruby 1.8.6 (p287) were tested on a previous version of the Ruby Benchmark Suite on Windows Vista x64 on the same quad-core used for the main shootout. The MagLev, MacRuby and IronRuby numbers reported here were the best times out of five iterations, and include startup time. IronRuby on Mono was not tested because I couldn’t get it to work on my machine, despite having tried several IronRuby versions and two different Mono versions. Please also notice that Ruby 1.8.6 (p287) was tested twice on Windows, once for the main shootout against the current Ruby Benchmark Suite, and a second time to compare it with IronRuby, against the old benchmarks.
Note: As tempting as it is, do not compare implementations that belong to different shootouts directly to one another. It would be very disingenuous to directly compare VMs tested with different benchmarks and/or different machines. The only comparisons that make sense are the ones within each of the four groups.
The following table shows the run times for the main implementations. The table is fairly wide, so you’ll have to click on the image to view the data in a new tab.
Green, bold values indicate that the given virtual machine was faster than Ruby 1.8.7 on GNU/Linux (our baseline), whereas a yellow background indicates the absolute fastest implementation for a given benchmark. Values in red are slower than the baseline. Timeout indicates that the script didn’t terminate in a reasonable amount of time and was (automatically) interrupted. The values reported at the bottom are the total amounts of time (in seconds) that it would take to run the common subset of benchmarks which were successfully executed by every virtual machine. When our baseline VM generated an error, others were used, starting with Ruby 1.8.7 on Vista (for color coding purposes only).
The following image shows a bar chart of the total time requested for the common subset of successfully executed benchmarks (those whose names are in blue within the tables):

More interestingly, the following table shows the ratios of each Ruby implementation based on the baseline (MRI):
The baseline time is divided by the time at hand to obtain a number that tells us “how many times faster” an implementation is for a given benchmark. 2.0 means twice as fast, while 0.5 means half the speed (so twice as slow). The geometric mean at the bottom of the table tells us how much faster or slower a virtual machine was when compared to the main Ruby interpreter, on “average”. Just as with the totals above, only those 101 tests, which were successfully run by each VM, where included in the calculation.
More concisely, here is a bar chart showing the geometric mean of the ratios for the various implementations tested:

I prefer to let the data speak for itself, but I’d like to briefly comment on these results. Just a few quick considerations.
Working off of the geometric mean of the ratios for the successful tests, Ruby MRI compiled from source is twice as fast than the Ruby shipped by Ubuntu, and by the One-Click Installer on Vista. The huge performance gap between ./configure && make && sudo make install and sudo apt-get install ruby-full should not be taken lightly when deploying in production. These numbers also reveal what most of us already knew: Ruby is particularly slow on Windows (800-pound gorillas in the room, or not).
Performance-wise Rubinius has more work left to be done to catch up with Ruby 1.8.7 and other faster VMs, particularly if we take into account the number of timeouts. But it has improved in the past year and I think it’s on the right track.
Ruby Enterprise Edition is about as fast as Ruby 1.8.7 compiled from source, which is reasonable considering that it’s a patched version of Ruby 1.8.6 aimed at the reduction of memory consumption (a parameter which wasn’t tested within the current shootout).
Speaking of excellent results, Ruby 1.9.1 and JRuby 1.1.6 both did very well. It looks like we finally have a couple of relatively fast alternatives to what is a slow main interpreter. According to the results above, and with the exception of a few tests, on average they are respectively 2.5 and 2 times faster than Ruby 1.8.7 (from source), and 5 and 4 times faster than Ruby 1.8.7 installed through apt-get on Ubuntu or Ruby 1.8.6 installed through the One-Click installer on Vista. Again, this does not mean than every program (particularly Rails) will gain that kind of speed, but these results are very encouraging nevertheless.
There has been a lot of buzz about MagLev since Avi Bryant’s first benchmarks were shown a few months ago. Here we finally see it being put to the test. The table below shows the times obtained by running MagLev and Ruby 1.8.6 (p287) against MagLev’s set of benchmarks based on the old Ruby Benchmark Suite:

And here are the ratios:

You’ll notice how MagLev swings from being much faster than MRI to being much slower. I believe there is much room for improvement, but at almost twice the speed of MRI, these early results are definitely promising.
These are the times for MacRuby 0.3 on Mac OS X 10.5.5:

And of course, the ratios against the MRI baseline:

MacRuby is relatively new, so these are not bad results. More work is required, but it’s a good start.
Finally (I promise these are the last ones), here are the two tables for IronRuby and Ruby 1.8.6:


IronRuby is slower than Ruby 1.8.6 on Windows, which in turn is much slower than Ruby 1.8.7 on GNU/Linux. This is not very surprising. This project has been focusing on integrating with .NET and catching up with the implementation of the language by improving the RSpec pass rate, as opposed to performing any optimizations and/or fine tuning (as per John Lam’s presentation at RubyConf 2008). We’ll measure its improvements in the next shootouts.
Overall I think these are great results. Ruby 1.8 (MRI), with its slowness and memory leaks, belongs to the past. It’s time for the community to move forward and on to something better and faster – and we don’t lack interesting alternatives to do so at this stage.
I hope that for the next shootout, MagLev, MacRuby and IronRuby will be able to run the benchmark suite, so that they can all be tested and directly compared with each other. I also hope to include Tim Bray’s XML benchmark, some sort of “Pet Shop” sample Rails and Merb application and, above all, include memory usage statistics.
You can find the Excel file for the main shootout here. That’s all for now. Feel free to comment, subscribe to my feed, share this link and promote it on Hacker News, Reddit, DZone, StumbleUpon, Twitter, and Co. Putting together this shootout was a lot of work, so I definitely appreciate you spreading the word about it. Until next time…
Update (December 10, 2008): This article has been updated to correct a couple of major issues with yesterday’s results. I adjusted my commentary as well, in light of the corrected figures.
Update (February 7, 2009): Thanks to Makoto Kuwata, a Japanese version of this article was published in the Rubyist Magazine.
Two days ago my MacBook Pro’s screen turned black. Following what I assume was an unsuccessful firmware upgrade, my laptop stopped displaying anything on its LCD. It would boot, greet me with a chime and I could even login and adjust the volume, all without seeing a thing. After researching the issue online, I ended up trying many possible solutions all to no avail. Some people managed to resolve what seemed to be a similar issue with a Firmware Restore CD (but a second Mac is required to burn such a disk).
After way too much tinkering, I decided it was time to schedule an appointment at the Apple Store. Luckily for me, they opened a new store in Toronto at the Fairview Mall, which happens to be within walking distance from my apartment. The reservation process was done online quickly and easily.
When I arrived at the store with my laptop, I was greeted by a couple of happy folks and then directed towards the Genius Bar. I was asked to wait and sit at the bar, but I don’t think it was more than a couple of minutes before my turn came along. Rachel, the Genius assigned to my case, was very empathic and friendly, and in the 40 minutes I was there, she pretty much tried everything possible to get my laptop back on its feet. It was a hard nut to crack though, so she asked if it would be OK for her to help another customer while my computer was doing some processing. While she didn’t really need to ask, it was a nice thing to do on her part.
Part of the reason why my laptop was hard to fix was that its internal optical drive doesn’t work. This makes a simple “use a restore CD” operation much harder because it requires convincing my Mac, with a blank display, that another CD device should be used to boot and restore the firmware (in this particular case a MacBook connected via Firewire).
Despite the fact that my laptop has outlived its warranty and doesn’t have Apple Care, I was never made feel like I was wasting their time, and the Genius definitely attempted as many approaches as possible to get the screen to work again. We started talking about the possibility of getting the optical drive fixed and how much would it cost me.
As we neared the end of exploring the possible solutions to my computer’s issue, I calmly mentioned in chit-chat, how I was somewhat disappointed that my first MacBook Pro gave a number of problems in its short life span. In particular, I casually mentioned that I had to replace the MagSafe because it melted and how the battery health became rather low in the span of just a few months. In fact, after little more than a year, its health was so bad that my Mac would shutdown in a couple of minutes if not connected to a power outlet.
Guess what? Rachel popped my battery out of the laptop and placed in a different one to check it out. It turned out that my battery was part of a problematic batch and as such I was entitled to a brand new battery (it costs $159 otherwise). So she proceeded to replace the battery on the spot, free of charge. I didn’t ask for the battery, but she paid attention to what I was saying and figured out that she could offer me a replacement battery given that the original was defective. Long story short, we couldn’t get the laptop to work, but she gave me a restore CD, just in case I wanted to try out a few more things once home (I own a USB CD drive).
In theory I could have been disappointed. After all, my visit didn’t fix the problem at hand, my expensive laptop seemed to be good as a door stopper, and repairing this thing could potentially be less advantageous than just buying a newer unit. Yet, as I arrived home, I told my wife that my next laptop would definitely be an Apple.
The reason for this is that I saw a genuine effort to help me out, an unheard level of care for the customer and an willingness to do what’s right, even if it costs the company some money. The whole experience was very positive and I felt that the premium cost of Apple’s products is easily justified by this kind of support.
For the record, between knowing rEFIt menu’s by heart, the restore CD, and the external drive, once home again I managed to somehow roll back the old firmware and reinstall the new one. So the end result is that I have a new battery that I desperately needed and a working laptop that I need even more.
This is just an anecdote, but it helps to explain the loyalty of an increasing number of Mac users. Perhaps I’m easy to please, but in my opinion, Apple Stores are a textbook example of how retail outlets should be run and I now feel much more confident about purchasing Apple products in the future.
Following my last post, a few people asked me to create a Pygments TextMate bundle. Ask and ye shall receive (on GitHub).

Install Pygments following these instructions.
First method:
sudo mkdir -p /Library/Application\ Support/TextMate/Bundles
cd /Library/Application\ Support/TextMate/Bundles
git clone git://github.com/acangiano/pygments-textmate-bundle.git "Pygments.tmbundle"
If TextMate is running while you perform the update, execute the following:
osascript -e 'tell app "TextMate" to reload bundles'
This is equivalent to selecting Bundles -> Bundle Editor -> Reload Bundles from within TextMate.
Second method: Download this file, unzip it, and double click on Pygments.tmbundle.
By the way, add the following to your stylesheet if you’d like to see a scrollbar when displaying very long lines of code. This adds a nice border as well:
.highlight { border: 1px solid silver; padding-left: 5px; margin-bottom: 0.5em; overflow-x:auto; }
Like many, I don’t use TextMate just for coding. All of my posts are first drafted in my trusty editor before being published. One of the problems that I had, and that others probably face too, is the less than smooth process of publishing properly highlighted code in posts and HTML pages. A few solutions exist, including embedding gist snippets, using “Create HTML from Document” in TextMate, or adopting JavaScript libraries or WP plugins. But when it comes to highlighting code, for me Pygments is simply unbeatable.
Pygments is a Python library but ships as a command line tool as well. However, switching between TextMate and the command line is not as convenient as I’d like. So on the weekend I pulled out my big sharp razor and started yak shaving. The result of that brief session is a hack that delivers the integration of TextMate and Pygments, so that code can be easily converted to HTML in order to beautifully present it.
First, let’s see how I use it. When I select a snippet of Ruby code in TextMate and press ⌃⌥1 a snippet of code is transformed into the proper HTML. ⌃⌥2 is for Python snippets, ⌃⌥3 for any other language, and ⌃⌥4 for any language as well but with the option of adding line numbers. In practice, this means that I use 1 and 2 most of the time and these shortcuts are easy enough to remember. Note that this is not necessarily the best arrangement, but it works well for me. I could, if so inclined, associate all 4 commands to the same shortcut and be prompted by a menu every time this combination is pressed, obtaining something along the lines of the image shown below:

Should I ever forget these 4 shortcuts, I can take a quick look at the Text bundle menu shown below. I placed these commands under the Text menu, since they are globally available for textual formats, whether I’m composing HTML, Textile, Markdown or ReST; but this is entirely arbitrary and I suspect that many would consider the HTML menu instead or place a “Convert to HTML” entry in the menu of the specific language.

Ruby and Python deserve their own command because they are the languages whose code I publish the most, but pressing ⌃⌥3 (or 4) prompts a long list of languages to choose from as shown below (the image is cut to reduce its length):

The following are a series of steps that you can take to reproduce the same results as mine. The HTML required to present the code nicely in this section was generated from within TextMate. In other words, I’m eating my own dog food.
Step 1: If you haven’t done so already, install Pygments. You can get it from the official site.
Step 2: Within TextMate click on the menu entry: Bundles -> Bundle Editor -> Show Bundle Editor and click on the triangle to open up Text in the left pane.
Step 3: Click on the +- button in the lower left corner of the window and select New Command, then name the command Pygmentize Ruby (assuming that you want a command for Ruby).
Step 4: Ensure that each option for Save, Input, Output and Activation are the same as shown below (click to enlarge):
Step 5: Fill the Command(s) text area with the following code:
#!/usr/bin/env python
import os
import sys
from pygments import highlight
from pygments.lexers import RubyLexer
from pygments.formatters import HtmlFormatter
try:
code = os.environ['TM_SELECTED_TEXT']
except KeyError:
sys.exit()
formatter = HtmlFormatter()
print highlight(code, RubyLexer(), formatter)
Step 6: Repeat the process for Pygmentize Python, Pygmentize… and Pygmentize with line numbers… but select a different Activation key equivalent (replace 1 with 2, 3 and 4, respectively).
The command code for Pygmentize Python is as follows:
#!/usr/bin/env python
import os
import sys
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
try:
code = os.environ['TM_SELECTED_TEXT']
except KeyError:
sys.exit()
formatter = HtmlFormatter()
print highlight(code, PythonLexer(), formatter)
For Pygmentize… use the following:
#!/usr/bin/env python
import os
import sys
from commands import getoutput
from pygments import highlight
from pygments.lexers import get_all_lexers, get_lexer_by_name
from pygments.formatters import HtmlFormatter
try:
code = os.environ['TM_SELECTED_TEXT']
except KeyError:
sys.exit()
available_languages = ", ".join(sorted('"'+lex[1][0]+'"' for lex in get_all_lexers()))
chosen_language = getoutput("""echo $(osascript <<'AS'
tell app "TextMate"
activate
choose from list { %(languages)s } \
with title "Pick a language" \
with prompt "Select a language"
end tell
AS)""" % {'languages':available_languages})
os.system("osascript -e 'tell app ""TextMate"" to activate' &>/dev/null &")
lexer = get_lexer_by_name(chosen_language.lower())
formatter = HtmlFormatter() # linenos=False
print highlight(code, lexer, formatter)
And finally for Pygmentize with line numbers… use the almost identical script below:
#!/usr/bin/env python
import os
import sys
from commands import getoutput
from pygments import highlight
from pygments.lexers import get_all_lexers, get_lexer_by_name
from pygments.formatters import HtmlFormatter
try:
code = os.environ['TM_SELECTED_TEXT']
except KeyError:
sys.exit()
available_languages = ", ".join(sorted('"'+lex[1][0]+'"' for lex in get_all_lexers()))
chosen_language = getoutput("""echo $(osascript <<'AS'
tell app "TextMate"
activate
choose from list { %(languages)s } \
with title "Pick a language" \
with prompt "Select a language"
end tell
AS)""" % {'languages':available_languages})
os.system("osascript -e 'tell app ""TextMate"" to activate' &>/dev/null &")
lexer = get_lexer_by_name(chosen_language.lower())
formatter = HtmlFormatter(linenos=True)
print highlight(code, lexer, formatter)
Step 7: Click on Text and by dragging and dropping arrange the menu to include the Pygmentize commands as shown below (click to enlarge):
Step 8: At this point everything should work, whether you invoke the commands through a keyboard shortcut or through the Text menu. However, you will need to upload and include a Pygments stylesheet from within your site. To generate a stylesheet run the following from the command line:
pygmentize -S default -f html > pygmentize.css
In the above command, default is the name of the style. For example, the Python code you see in this article is styled with the style pastie (because I globally adopted that stylesheet for this site). For a comparison of the available styles check out this demo page.
Step 9: ????
Step 10: Profit!
I hope these hacked together commands can be useful to others. Feel free to customize them and improve upon them as it suits your needs.
UPDATE: I made a Pygments TextMate Bundle out of this.
Remember Ballmer shouting ad nauseam “Developers, developers, developers”? I’m sure you’ve seen the original video and even a few techno remixes. Whether he truly meant it or not, his message was correct: it’s all about developers. Any platform that doesn’t attract developers is bound to fail.
Microsoft is trying to make an effort to please developers by shifting to a more open attitude towards the development community. Their record is far from pristine, but at least they are making a concrete attempt not to piss off programmers who chose to develop for any of their platforms – efforts which are rarely acknowledged.
Apple, a company that is generally considered far from “sinister” or “evil”, on the other hand, is trying their best to alienate developers. This is a crucial and costly mistake, even if they are a hardware company whose interest is mostly centered around their phones at this stage.
Their first idiotic move was to place an NDA on a finished product like the iPhone SDK (including the final version). For the ecosystem surrounding a platform to flourish, it’s fundamental that developers are able to freely share their knowledge. This move has many repercussions including the inability to publish books on the subject, something that is clearly a stepping-stone when it comes to being able to reach a broad audience of programmers.
Apple then decided that it was a good idea to charge people for the privilege to develop for the iPhone: $99 (that’s a hundred bucks, we are not idiots and this is not a grocery store). Thousands of other developers would have likely given it a shot and tried to tap into this new platform (and market opportunity), or simply experimented with it to satisfy their intellectual curiosity. But putting a $99 price tag on the Standard Program will push away the silent majority of potential developers and surely most freeware authors. Why would Apple do this? For a few extra bucks? That is nothing short of nearsighted thinking which only benefits a company in the short term and does serious harm in the long run.
These were two blatant mistakes, but, if you can believe it, Apple managed to alienate developers further still. A few thousand people put up with the NDA on the SDK, with the cost of the Standard Program, and with the lengthy and bureaucratic process it takes to access the only viable distribution channel, the iPhone App Store. Some of them spent months trying to create excellent, innovative applications for the iPhone, only to see their work rejected for no good reason other than that it competed with Apple’s own products (e.g. Podcaster) or was inconvenient for their business partner AT&T (e.g. NetShare). How shortsighted is that? It’s almost as stupid as the RIAA, which has a habit of suing its own customers.
Following the uproar of complaints about this, Apple decided that the best way to deal with developers’ malcontent was to legally bind them to shut up. So now the rejection letters many developers are receiving are covered by an NDA as well.
How low will Apple go? I understand that a few developers are making a good deal of money from some popular applications, and that the iPhone is a hot product which may change the mobile world. I can even grasp that programming in Objective-C is fun. But how many developers is Apple alienating, how many great applications will never be written because programmers object in principle to developing for Apple’s platform?
I fail to see Apple’s usual business insight and only see blind greed, the kind that acts as a highly effective cautionary tale against developing for Apple’s platforms. This all comes at a time when Google is promoting a truly open platform, Android, which poses a few challenges due to the heterogeneous nature of the devices it will be deployed on, but is equally interesting from a technical standpoint. Google even went so far as to award ten million dollars in prize money through a contest that they held, to attract new developers and applications. Android is definitely welcoming new developers and it’s doing so free from glaring restrictions and limitations.
I suspect that many will put up with Java, to get a cup of freedom.