Projects

What's New in Leopard?

Now that Leopard, the next release of Mac OS X, is available to everyone, you may wonder what changed from the Ruby developer's perspective.

Note: The Ruby installation of Mac OS X Leopard is progressively updated via software updates. Check out  the blog for updated information regarding changes. The version numbers in this article may not correspond to the latest version available.

Ruby

Ruby itself was upgraded to 1.8.6 p36, which was the latest stable release that we could grab. We additionally merged patches for important bugs that were discovered after p36, but could not be part of an official Ruby patch release at that time (they actually were, but after our deadline).

Ruby in Leopard was framework'ized. It is now available in /System/Library/Frameworks/Ruby.framework. Compatibility with the previous directory layout is preserved, /usr/bin/ruby and /usr/lib/ruby are for example symbolic links that point inside the framework:

$ readlink /usr/bin/ruby
../../System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby
$ readlink /usr/lib/ruby
../../System/Library/Frameworks/Ruby.framework/Versions/Current/usr/lib/ruby
$ readlink /usr/lib/libruby.1.dylib 
../../System/Library/Frameworks/Ruby.framework/Versions/Current/usr/lib/libruby.1.dylib

The Ruby libruby.1.dylib library, which contains the core of the interpreter, is available as a 4-way fat universal binary, for the ppc, i386, ppc64 and x86_64 architectures. You can therefore embed Ruby in a 64-bit application. All C extensions are also available for both 32-bit and 64-bit architectures, except Tk which cannot go 64-bit. The Ruby interpreter launcher, /usr/bin/ruby, was therefore left 32-bit only to not break scripts that use the Tk extension, or any other 32-bit only dependency.

Ruby C extensions will by default compile 2-way fat, for ppc and i386. You can set the ARCHFLAGS environment variable to configure the build of an extension, if for example it links against a non-universal library (like the mysql.com binaries which are delivered per processor architecture).

$ ARCHFLAGS="-arch i386" ruby extconf.rb   # Will build for Intel 32-bit only.
$ make
$ sudo make install

You can also set ARCHFLAGS to configure the architecture flags of a gem build. Keep in mind that in Leopard, sudo doesn't transfer environment variables to the privileged process, so you may have to spawn a root shell.

Ruby libraries or extensions that you install manually, will go in /Library/Ruby/Site/1.8, which is empty after the installation, but part of the default Ruby load path before others. You can therefore install any Ruby library or extension without worrying about incidentally modifying things in /System.

The md5 and sha1 C extensions, part of the Ruby standard library, were modified to use the new /usr/include/CommonCrypto API instead of OpenSSL's libcrypto, for performance reasons.

The readline C extension, also part of the Ruby standard library, is now installed. It uses /usr/lib/libedit.dylib as an alternative readline implementation.

The examples that are packaged with the standard Ruby distribution are now available in /Developer/Examples/Ruby/Ruby.

IRB

Now that readline support is available, IRB has command-line editing and history support.

IRB was modified to look at /etc/irbrc as the last possible place for a configuration file. Leopard ships an /etc/irbrc file that provides a default configuration for all IRB sessions, that requires RubyGems, activates auto-completion, switches to the simple prompt, and sets up a permanent history facility.

If you have a custom IRB configuration file in your home directory, or supply one to IRB from the command line, /etc/irbrc will be ignored. IRB currently doesn't support the load of multiple configuration files.

Gems

RubyGems 0.9.4 is available by default, with the following pre-installed gems:

actionmailer (1.3.3)
actionpack (1.13.3)
actionwebservice (1.2.3)
activerecord (1.15.3)
activesupport (1.4.2)
acts_as_ferret (0.4.1)
capistrano (2.0.0)
cgi_multipart_eof_fix (2.2)
daemons (1.0.7)
dnssd (0.6.0)
fastthread (1.0)
fcgi (0.8.7)
ferret (0.11.4)
gem_plugin (0.2.2)
highline (1.2.9)
hpricot (0.6)
libxml-ruby (0.3.8.4)
mongrel (1.0.1)
needle (1.3.0)
net-sftp (1.1.0)
net-ssh (1.1.2)
rails (1.2.3)
rake (0.7.3)
RedCloth (3.0.4)
ruby-openid (1.1.4)
ruby-yadis (0.3.4)
rubynode (0.1.3)
sources (0.0.1)
sqlite3-ruby (1.2.1)
termios (0.9.4)

As you can see, Rails is available by default, along with Capistrano, Mongrel, and many other very useful libraries.

Like you discovered with C extensions, RubyGems in Leopard uses two gems repositories:

$ ruby -r rubygems -e "p Gem.path"
["/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8", "/Library/Ruby/Gems/1.8"]

You will find that the /System repository contains all the pre-installed gems, while the /Library one will be empty by default. This is where gems you install will go.

In order to add a new gem to the /System repository, you will have to explicitly point the GEM_HOME environment variable to it. Please note that you can uninstall or cleanup old gems that are in the /System repository.

The gem_server utility is not part of the client distribution of Leopard. It is only provided in the server.

DTrace

DTrace static probes were added in the interpreter engine. We actually took the amazing patches that the Joyent guys wrote for Solaris, and modified the code a little bit to make it work under Leopard and to address some small problems.

The probes that you can register to are the following:

function-entry
function-return
gc-begin
gc-end
line
object-create-done
object-create-start
object-free
raise
rescue
ruby-probe

You can read more about the probes in the Joyent's [ ruby-dtrace project] page.

[ Instruments], a new performance visualization tool in Leopard, has Ruby support built-in. You can make a new DTrace instrument, select Ruby as a probe type, pick one or more probes then start analyzing a random Ruby process.

There are a couple of DTrace examples that use the DTrace probes in /Developer/Examples/Ruby/DTrace.

RubyCocoa and BridgeSupport

[ RubyCocoa], an Objective-C to Ruby bridge, is now delivered with the system, in /System/Library/Frameworks/RubyCocoa.framework. The version that we ship is actually 99%-based on the public 0.12.0 release, modulo some Leopard-only specific changes, that will soon be pushed upstream. For more information regarding RubyCocoa, please check out the [ official website], or [ http://developer.apple.com] which should soon offer additional documentation.

The Ruby runtime was patched to provide threading hooks, that RubyCocoa uses to save and restore per-thread Foundation data when a Ruby thread switches in and out.

libffi is available in the system as a 4-way fat dynamic library, in /usr/lib/libffi.dylib.

Most of the system frameworks in Leopard are covered by the [ BridgeSupport] mechanism, making them freely available from RubyCocoa or [ PyObjC]:

AddressBook
AppKit
AppleScriptKit
ApplicationServices
Automator
CalendarStore
Cocoa
Collaboration
CoreAudio
CoreAudioKit
CoreData
CoreFoundation
CoreText
CoreVideo
DVDPlayback
DirectoryService
DiscRecording
DiscRecordingUI
ExceptionHandling
Foundation
ICADevices
IOBluetooth
IOBluetoothUI
InputMethodKit
InstallerPlugins
InstantMessage
JavaScriptCore
LatentSemanticMapping
OSAKit
OpenGL
PreferencePanes
PubSub
QTKit
Quartz
QuartzCore
ScreenSaver
ScriptingBridge
SecurityFoundation
SecurityInterface
SyncServices
SystemConfiguration
WebKit
XgridFoundation

Some of the libSystem's APIs, such as asl(3), notify(3), sandbox(7) and launchd, are also covered by a bridge support file, /System/Library/BridgeSupport/libSystem.bridgesupport.

The BridgeSupport generator is available by default, as /usr/bin/gen_bridge_metadata. You can use it to cover your own API. It is documented in gen_bridge_metadata(1), as well as the format it generates, in BridgeSupport(5). The exceptions format is not documented yet, but it will be very soon.

Both RubyCocoa and the BridgeSupport files come with any Leopard installation. You can find some examples in /Developer/Examples/Ruby/RubyCocoa.

Xcode and Interface Builder

[ Xcode] in Leopard comes with the RubyCocoa project templates, but also with a template to generate a Test/Unit target. Xcode also supports better Ruby auto-completion, driven by the BridgeSupport mechanism.

Interface Builder now officially supports Ruby. For example, you can write a Ruby class in Xcode, with outlets and/or actions, and everything will automatically appears in IB. IB uses RubyCocoa's rb_nibtool utility to synchronize the metadata. On the other way, you can manually define outlets and/or actions in IB, drag-and-drop them in an Xcode Ruby file, and the corresponding Ruby code will be pasted in it.

Scripting Bridge

[ Scripting Bridge] is a new Leopard framework that provides access to the AppleEvent infrastructure, on which AppleScript is based. Scripting Bridge will dynamically generate an Objective-C interface that corresponds to the scriptable dictionary of a given application. You can then send messages and control this application from Objective-C.

Thanks to RubyCocoa, it is also possible to use Scripting Bridge from Ruby. Some scripting elements are not yet accessible though, like enumerations, but most of the functionality should be available.

If Scripting Bridge doesn't fit your needs, a couple of Ruby to AppleEvent bridges exist too, [ RubyOSA] and [ rb-appscript]. Neither is bundled in Leopard, but it is possible to install them from RubyGems using a single command line instruction. RubyOSA is similar to Scripting Bridge, in that it is based on the application's scripting dictionary; rb-appscript uses a different and more general approach, which is particularly useful if you want to work around the scripting dictionary.

Please Report Bugs!

Please help us by reporting any issues you encounter! See the [Support] page for more information on how to send us some feedback. Make sure you read the [Troubleshooting] page first, as your problem might be already covered there.