ruby inside

Syndicate content
Updated: 19 weeks 6 days ago

Coderpath: Weekly Ruby-Focused Interview and Discussion Podcast

Tue, 04/20/2010 - 20:43

Coderpath is a weekly podcast by Ruby developers Miles Forrest and Curtis McHale where they typically interview a different Ruby developer and discuss some of their current work. Most of the episodes are in an interview format and guests so far include a handful of Ruby developers you'll know (such as DHH and Ryan Bates).

The latest episode is a 35 minute interview with Wayne E Seguin, the developer of Ruby Version Manager. Before that was yours truly, sounding like a total crackhead. Coming up next week is Obie Fernandez of HashRocket.

Here are the episodes so far:

Naturally, you can subscribe via iTunes or use their direct podcast feed with your favorite podcatching software. You can also follow the podcast on Twitter, which is useful because they often request questions to ask people before recording the show.

Interesting Ruby Tidbits That Don’t Need Separate Posts #30

Mon, 04/19/2010 - 18:47

The latest installment of our series of roundup posts, covering some of our latest findings in the world of all things Ruby. These items wouldn't make it in as separate posts, but they should be of enough interest to Rubyists generally to make it a worthwhile browse for most readers.

Camping 2.0 Released

Back "in the day", a gentleman and scholar called Why The Lucky Stiff built a teeny, tiny webapp framework called Camping. It was like an extremely light mix of Rails and Sinatra, except that Sinatra didn't even exist at the time. In late 2009, Why went missing and still hasn't reappeared, but Magnus Holm picked up the torch and has released Camping 2.0. It retains Camping's original flavor and hardcore spirit (it's only 3072 bytes in size!) but adds Rack support and simpler routes, amongst other things.

JRuby 1.5.0 RC1 Released

The JRuby team has announced the release of JRuby 1.5.0 release candidate 1. It comes 5 months after JRuby 1.4.0's release and features the most fixes of any of JRuby's development cycles. There are also a handful of new features and improvements, including better Windows and UNIX-specific support, standard library and RubyGems updates, Rails 3 focused fixes, performance improvements for Ruby-to-Java calls, and JIT compilation caching.

Ruby There: Ruby Events Listings

Ruby There is a new Ruby and Rails events listing site from Scottish Rubyist, Keavy McMinn. You can already submit events of your own or just check out what's coming up. We'll do a full post about it soon once Ruby There's listings have been integrated with Ruby Inside, as we plan to show Ruby event listings on all our pages. As an aside, Keavy is a great Rails developer and is currently taking on new work.

Isy: Yet Another Ruby Webapp Framework

Whenever I post about a new Ruby webapp framework on Ruby Inside, I typically get a response or two along the lines of: "Who cares? Yet another Ruby webapp framework? What's wrong with Sinatra and Rails?" Well, if that isn't you, you might be interested in Isy, a new webapp framework that's component-based and stateful.

Psych: Event-Based JSON and YAML Parsing

Aaron Patterson (a.k.a. tenderlove) of Nokogiri fame has written a blog post about building an event-bsased Twitter stream parser with Ruby 1.9.2 and Psych. Typically in Ruby, JSON and YAML parsing are done in an "immediate" fashion where you pass in the data and you get a Ruby representation back out. Event-based parsing instead uses callbacks to process JSON and YAML asynchronously.

PDF::Writer Deprecated - Prawn 1.0 Under Development

Prawn is a pure Ruby PDF generation library that abstracts away a lot of the PDF-specific nonsense into a form that makes it easy to produce PDFs from Ruby code. Its creator, Gregory Brown, has retired the older PDF::Writer library in order to focus on the development of Prawn 1.0. Gregory is keen to lay down a spec for Prawn 1.0's API and he's put a draft spec out there for everyone to comment on. If generating PDFs from Ruby is important to you or your app, you might want to get involved in this effort, as Prawn is sure to remain the #1 PDF generation library available to us for some time.

For Sale: RubyPlus.org

Bala Paranj is selling his much-celebrated rubyplus.org Ruby screencasting site. He claims it has 12,000 members and he's selling the site to fund the growth of his Zepho Inc company (which is focusing on a British accent training iPad app). Questions and offers can be directed to Bala at bala.paranj at zepho.com.

While we're in a mercantile mood, perhaps I should also mention I own rubyonrailswebhosting.com, railswebhosting.com, rorhosting.com, railstraining.co.uk, rails-training.co.uk, and ruby-training.co.uk.. and if anyone has any serious or semi-serious offer for any of them (I'm more than happy to sit on them, so it'd have to be worth it), contact me (see the Anything else section for my e-mail address).

IronRuby 1.0 Released: Microsoft’s 3 Years With Ruby Pay Off

Wed, 04/14/2010 - 00:18

Three years after Microsoft first announced it was dipping a toe into the Ruby implementation waters, IronRuby 1.0 has been released. IronRuby is Microsoft's attempt at bringing Ruby natively to the DLR that runs on top of .NET (and Mono), and with version 1.0, it has finally reached maturity with Jimmy Schementi calling it the "first stable version."

IronRuby 1.0 is available to download in two different forms - a .NET 4.0 Windows installer or ZIP file, and a .NET 2.0 SP1 Windows installer or ZIP file. The .NET 4.0 version has faster startup times and is more feature complete (in terms of .NET integration) but the .NET 2.0 SP1 version will run on the Mono cross-platform, open source .NET platform.

The IronRuby team are pushing stability and maturity as big themes for the 1.0 release. Their progress is certainly encouraging. As of today, IronRuby passes 85.95% of RubySpec (as opposed to MRI Windows Ruby's ruby.exe score of 97.84%) with most of the gap in the library tests. IronRuby does particularly well with the language tests (98.31% pass vs 99.89% for ruby.exe). IronRuby promises Ruby 1.8.6 compatibility (mostly) and supports Rails 2.3.5.

We recently presented a walkthrough of using IronRuby and Silverlight to get Ruby in the Web browser and did an interview with IronRuby developer Jimmy Schementi so we're not going to go into detail here - check out those posts for more in-depth IronRuby knowledge.

New snippets that may also be of interest include an article on using FlexMock with C# types and a demo of how to embed Ruby files in a .NET assembly using embedded resources. The latter is particularly interesting as it allows Ruby source to be encoded and hidden away not only from other developers, but cranky sysadmins ;-)

Thanks to David Lake for help with this post.

awesome_print: A New Pretty Printer for your Ruby Objects

Wed, 04/07/2010 - 11:19

awesome_print is a Ruby tool that provides "pretty printing" support for your objects. It's a bit like p, pp or, if you prefer, puts obj.inspect, but with significantly improved, contextual, colored output. Its creator and maintainer is Michael Dvorkin of Fat Free CRM fame.

Being able to see "inside" Ruby objects on the fly can prove useful whether you're debugging some code your tests did not dare reach or you're just playing around in irb. The most common way to examine objects is with p or the inspect method, but these don't format their output in a particularly easy-to-read way. pp - part of the standard library - is a pretty printer that improves matters but it still leaves a lot to be desired. awesome_print takes it all to the next level.

A visual comparison between pp and awesome_print proves compelling:

awesome_print's most compelling features are showing you the index of array elements within its output, inheritance for the classes of embedded objects, and color coding. Further, it's highly customizable, with the ability to set indent levels as well as the colors for each type of data shown.

To get up and running, gem install awesome_print and then require 'ap' and use ap in place on anywhere you'd usually use p. Yep, that's it.

Padrino: A Webapp Framework Wrapped Around Sinatra

Thu, 04/01/2010 - 16:58

Hot on the heels of Sinatra 1.0 comes the official release of Padrino (or GitHub repo), a webapp framework that provides an extra layer of functionality on top of Sinatra (like helpers, generators, admin interface, and internationalization). Padrino is Sinatra 1.0 compatible.

Developers Davide D'Agostino, Nathan Esquenazi and Arthur Chiu love Sinatra and its development philosophy, but want to provide a deeper, standardized layer of functionality on top of the typical Sinatra stack. True to form, Padrino extends Sinatra with a wealth of extra features:

  • Namespaced route aliases
  • Nested routes
  • Controllers
  • i18n / Internationalization
  • Mailer system
  • Django-esque admin interface
  • Unified logging
  • Tag, asset, for, and tag helpers for use in views
  • App, model and controller generators

Most of these features can be added to Sinatra already, either manually or by selecting from a wide assortment of independent plugins. Padrino, on the other hand, provides a standard suite of functionality that, hopefully, will continue to be improved as a whole over time. It feels a lot like Ramaze but with the similar functionality wrapped around Sinatra instead.

The Padrino team have done a great job putting together its official Web site and there's a lot of documentation to peruse. They've also put together a guide to contributing to the project if you want to get your hands dirty. There's also a 12 minute screencast:

A Walkthrough of Ruby In The Web Browser using IronRuby and Silverlight

Thu, 04/01/2010 - 11:07

With Microsoft's IronRuby and Silverlight, Ruby can become a first-class citizen in the browser on Windows, Linux and OS X.. think <script type="text/ruby"> - yes, it's possible! This walkthrough will get you started with using Ruby in the browser for HTML and vector-graphics-based applications. IronRuby enables Web developers to use Ruby to write client-side browser applications and even reuse code between the server and the client.

Background

IronRuby is a Ruby 1.8.6-compatible implementation, with ever-increasing support for 1.9 features that runs on Microsoft's Common Language Infrastructure. The CLI blesses IronRuby with some powerful features like an efficient just-in-time compiler and sophisticated garbage collector. However, certain runtime-specific Ruby features are not supported on IronRuby, like continuations which interact with the runtime, certain performance-bogging parts of ObjectSpace, and the native Ruby C API. To support native-code interop we are planning on supporting FFI in the future (though today you can use the Win32API for Win32 calls, and the platform invoke APIs for the rest).

IronRuby runs on the .NET framework (2.0 SP1+) and Mono(2.0+), so IronRuby runs on a ton of platforms, including Mac OS and Linux. IronRuby also runs in the browser on Silverlight and Moonlight, a fairly-complete-but-tiny runtime which allows you to build "rich internet applications" ... basically anything doing vector-graphics, webcam, audio, etc, in the browser.

Getting Started

Note: All code shown in this article can be found on GitHub.

To develop browser applications with IronRuby, you just need a Web server, text-editor, Web browser, and Silverlight installed for your browser to use:

1. Download and Install Silverlight for Mac or Windows

You'll notice these installers are larger than advertised (7MB Windows, 13MB Mac): these are the "developer" versions since they contain error-message strings rather than just error codes, which is all the "consumer" versions have.

2. Set up any Web server, text-editor, and Web browser

I'll be using the latest version of Firefox for the Web browser, the Apache Web server (which is part of Mac OS), and TextMate as the text-editor; on Windows you can use IIS (or any Web server of your choice) and any text-editor of your choice (notepad.exe is already installed, but I'd suggest E-TextEditor, InType, or even gVim for the more courageous). Silverlight officially supports IE, Firefox on Windows, and Firefox and Safari on Mac OS, but Opera and Google Chrome on both operating systems are known to work. See the system requirements page for more details.

3. Write Ruby in HTML pages

Here's a simple "Hello, World"-style Ruby application in the browser:

Open the text-editor, place this code into it, and save the file to a convenient location where your Web server can access it; I'm saving mine to ~/Sites/ruby.html, since that will let me access it from http://localhost/~<username>/ruby.html (IIS users will have to put the file under C:\inetpub\wwwroot, which will let you access it from http://localhost/ruby.html) When you visit the site in a Web browser, you will see "Ruby says hello!":

Note: if you just see "Loading ..." for a very long time ... did you already install Silverlight? There is no install detection in these examples. If you're on a slow connection, make sure files aren't still being downloaded (see below). And this will not run direct from the file system due to Silverlight's security sandbox, so make sure you access it through a Web server.

Behind the scenes

That's it! It's very simple to get started with IronRuby in Silverlight, especially versus using ActionScript in Flash, or even the other languages like C# or VB.NET in Silverlight. Let me briefly explain what is going on behind the scenes to make IronRuby work so transparently with Silverlight.

The first script-tag runs dlr-<releasedate>.js which sets up a hidden Silverlight control on the page to download IronRuby and run any Ruby script-tags. The IronRuby binaries are downloaded to the browser cache, so they are not re-downloaded for any other application, unless the browser cache is cleared or is invalidated (Fig 2 and 3). These binaries set up the Silverlight control to process Ruby script-tags and execute them with IronRuby.

Note: IronRuby is not currently part of the Silverlight installation because keeping IronRuby open-source is a priority, and Silverlight is a closed-source project. The ability to download the binaries on the first load lets IronRuby stay as a separate project.

The specification for how all this works is in the Silverlight - Back to Just-Text paper; it is also a great source of documentation for the IronRuby-specific features, over and above what Silverlight already provides.

It's worth pointing out that the entire application is just text; Silverlight IronRuby applications are made up of script-tags which have inline ruby code, or point to a ruby file on the Web server, along with other supported file-types referenced by script-tags to use vector graphics, archives of Ruby libraries (like the Ruby standard library, or a Gem), or even .NET assemblies.

Vector Graphics

A similar "Hello, World" example can be done with Silverlight's vector-graphics as well:

The vector-graphics markup is called XAML, providing a simple XML-based markup language for defining any vector-graphics, like a user-interface. However, visual elements defined with XAML can also be defined through code; for example that <TextBlock> tag could have also been created from Ruby code, so you can decide to use XAML or just Ruby code to build vector-graphics:

t = TextBlock.new t.name, t.text, t.font_size = "message", "Loading ...", 14

XAML is useful as there are great designer tools like Expression Blend which generate XAML that is directly consumable by Silverlight. However, if designers-tools aren't your thing, the Magic library provides a very clean Ruby DSL for building user-interfaces.

In-Browser Ruby Console

A lot of Ruby development happens at an interactive Ruby command-prompt, and there is no exception with running Ruby in the browser. Turning on the Ruby command-prompt is simple; just enable the "console" setting for this page, and a Ruby command-prompt will appear at the bottom of the page, letting you run code against the active application:

document.message represents the DOM element with the id property of message (document.get_element_by_id("message") also works) and the click DOM event is hooked with the block, which changes the innerHTML of the clicked element. You can play around with code in this console window, and then when your satisfied move it into the actual HTML file.

Everything in Silverlight is usable through Ruby, just like it was originally written in Ruby. The is possible because IronRuby is directly integrated with the CLR. For example, you can see what methods are on the first DOM object in the HTML body by using normal Ruby idioms. For more information on what APIs are available in Silverlight, see the Full Silverlight 3 Documentation.

2D Drawing

A good way to get acquainted with new technology is to focus on an area and have some fun; here I'll be using the 2D drawing libraries in Silverlight to make some "art". The first example is ruby-squares.html, which draws 200 randomly size and randomly colored squares.

However, that's not all the Ruby code running in the app; in the HTML file you'll notice four script-tags before the code shown above. These files provide various helpers for working with Silverlight from Ruby.

repl.rb provides a way of enabling the command window through code, along with controlling when it's visible based on the query-string (ruby-square.html doesn't show the console at all, ruby-square.html?console will open the IronRuby Console panel, and ruby-square.html?console=off show the console with all panels hidden).

wpf_ext.rb contains some helpers to make dealing with Silverlight's graphics libraries nicer from Ruby. This is only a fraction of the functionality that wpf_ext.rb normally provides, as this file was truncated for the article.

sketch.rb sets up Silverlight for 2D drawing, calling those setup and draw methods described above at the appropriate times; largely influenced by ruby-processing.

bouncer.rb bounce any Silverlight object around a Silverlight canvas; I'll use this directly in the drawings. To experiment with it, run $sketch.toggle_bounce from the command-window to begin bouncing all the objects on the screen around. You can also re-run $sketch.setup to add more objects:

Speaking of ruby-processing, ruby-circles.html is one of the ruby-processing examples which I showed running in a Windows desktop app at RubyConf 2009, but can also run on the Mac through Silverlight.

Flickr Photo Viewer

While 2D animations are a fun way of exploring Ruby in the browser, they don't really capture what making a "real-world" client-side web application would be like, with more standard user-interactions like clicking links and typing into text boxes. A simple Flickr photo viewer should do the trick though; using Flickr's Web service to search for images and displaying them on the page:

The first thing this application needs to do is react when the "search" button is pressed. Ruby blocks (as well as procs) are used to handle events from the HTML page:

The create_request method takes the text in the textbox and makes a Web request to the appropriate Flickr Web service URL. When the request is complete, the applications shows the images Flickr returned:

The show_images method parses the response from Flickr into Ruby objects, and then the application's view render the photos with ERB:

view.rb - rendering HTML from ERB templates

images.erb - an ERB template which creates HTML for displaying Flickr images

The erb method uses the exact same ERB that is part of the Ruby standard library, and what Rails uses by default in views. The ability to run the same libraries, such as ERB, or even your own application code, on both the client and the server is unique way of being "DRY". It can help to blur the line between your client and server code, since everything can be written in Ruby, and open up new ways of sharing code and being productive.

Learn More

I hope this article has inspired you to look at using IronRuby for your next project, be it in the browser or not. Here are more resources to get you going with IronRuby in the browser:

jimmy.thinking - My blog has a bunch of tutorials on some interesting things that can be done with Silverlight and IronRuby, including Testing with Ruby and Embedding IronRuby in existing applications (though that article is for a native windows application, the same principles apply to the browser). Also, if you just want an update of IronRuby in general, my latest blog entry about the project's status from RubyConf 2009 has all the latest information, as well as the other posts in that series.

Documentation PDF - Paper about how the IronRuby in Silverlight integration works.

ironruby.com/browser - Placeholder website for IronRuby in the browser; it currently has a redistributable download and some simple samples. Content from Gestalt's website is currently under transition to this site, but the samples on that site are still relevant, as well as the newly released Gestalt Widget Pack, built on the latest version of IronRuby.

Full Silverlight 3 Documentation - Covers everything you can do with Silverlight 3. Examples are in C# or VB.NET, but are straight-forward to convert to Ruby.

github.com/ironruby/ironruby - IronRuby source code; Silverlight specific sources are all here. You can open bugs on the CodePlex project page.

And when in doubt, contact the IronRuby mailing list - you can also post online through ruby-forum.

Supermodel: Simple ActiveModel-Powered In-Memory Models

Fri, 03/26/2010 - 17:59

Supermodel is a new library by Alex Maccaw that uses the Rails 3.0 ActiveModel library to provide ActiveRecord-esque in-memory "database" storage in Ruby.

Supermodel is best demonstrated with a basic example:

require 'supermodel' class Person < SuperModel::Base; end a = Person.new( :name => "Jim" ) a.save Person.find_by_name('Jim') # => #<Person> Person.all # => [#<Person>]

This is just the start! Out of the box, Supermodel supports validations, callbacks, observers, dirty change tracking, and serialization. It also allows you, with only a little magic, to go beyond ephemeral memory-only structures and marshall your SuperModel-based objects to disk or even to a Redis store.

A more complex example that includes randomly generated IDs and validations:

require 'supermodel' class Person < SuperModel::Base include SuperModel::RandomID attributes :name validates_presence_of :name end a = Person.new a.valid? # => false a.name = "Jim" a.valid? # => true a.save a.id # => "6481a4fcd834e567836587c6da"

It's early days for Supermodel, but I can see it becoming a big deal for Rubyists away from the Rails stack. The gemified version doesn't have support for relationships yet, but the edge version on GitHub has early support for belongs_to and has_many included.Alex has written the code in a well structured way and creating modules or subclasses to add support for interacting with other backends (such as, say, Tokyo Cabinet) doesn't look like it'd be too hard.

Supermodel shows a lot of promise and is what I was originally hoping ActiveModel was going to be. It provides just the right level of abstraction and separation from the database, but without losing the goodness we came to enjoy from ActiveRecord over the past few years.

Sinatra 1.0 Released: Major Milestone for Ruby’s Best Webapp DSL

Tue, 03/23/2010 - 21:15

In November 2007, we casually mentioned a new Ruby webapp library called Sinatra. It took a year to capture the imagination of the Ruby community as a whole and we eventually covered it in more depth but today we're proud to (exclusively) announce that Sinatra has today reached its landmark 1.0 release!

Impromptu release party in the official #sinatra channel on irc.freenode.net, anyone? :-)

Sinatra is well known in the Ruby community for providing developers with a simple way to put together Web apps big and small. The canonical ultra-simple example:

require 'rubygems' require 'sinatra' get '/hi' do "Hello World!" end

Sinatra's lead developers — Ryan Tomayko, Simon Rozet, and Blake Mizerany — have done a great job, along with about 50 other contributors, to produce a slick and powerful Web application DSL for Rubyists. Their ideas have even inspired similar frameworks in other languages (such as Sammy in JavaScript). Satish Talim put together a great piece, 20+ Rubyists are using Sinatra - Do you?, last year that got a good feel for how Sinatra's being used for Web apps both big and small by a collection of Rubyists.

What's New?

As an avid user of Sinatra 0.9, I asked Blake Mizerany what the biggest changes were going to 1.0:

I think the biggest changes are what we cleaned up. Tilt is a great new under-the-hood addition. Sinatra has matured; we're done messing around. It's super solid. The extension API has matured to something really killer. Extensions are ridiculously simple to create now - you can easily install helper methods, DSL methods, and install new routes on apps, and the user need only require 'sinatra/your-extension' - that's it.

Unsurprisingly, the official changelog also provides useful information to existing Sinatra developers.

A more significant longer-term change for Sinatra over the past year has been in how it integrates with Rack. In Sinatra Rack And Middleware, Ben Schwarz looks at how Sinatra interacts with Rack and how you can use Rack's middleware and multi-application features with Sinatra. A key aspect of this is the ability to produce "modular" Sinatra applications by subclassing Sinatra::Base to separate discrete applications or application portions:

require 'rubygems' require 'sinatra/base' class MyApp < Sinatra::Base get '/' do "Hello world!" end end

And then, in a Rackup file:

require 'my_app' run MyApp Installing and Trying Sinatra

If you're not yet using Sinatra and want to give it a quick try, you can install it with RubyGems:

gem install sinatra

Put the following basic example into a file, say example.rb:

require 'rubygems' require 'sinatra' get '/hi' do "Hello World!" end

Then run the Ruby file in the usual way, and a request to http://localhost:4567/hi should get you a "Hello World!" response.

Learn More Online and on IRC

The examples shown above are as basic as Sinatra gets, but it goes a lot deeper than that (such as embedding Sinatra apps inside Rails apps) and the Sinatra Web site has some great code examples of where you can go next. There's also solid documentation available and if you want to take a look at lots of existing Sinatra projects to get a feel for the patterns and techniques involved, there's a great list of Sinatra apps and extensions too.

Lastly, if you're interested in asking questions about Sinatra or just hanging out with Sinatra's developers and users, head along to the #sinatra channel on irc.freenode.net. There's usually between 50-100 people hanging out there.

IronRuby Q&A – What’s Down With Microsoft’s Ruby Implementation In 2010?

Tue, 03/23/2010 - 00:27

IronRuby is an open source Ruby implementation being developed at Microsoft with the .NET CLR in mind. It's reasonably mature and as well being a regular implementation, it provides the ability to use Ruby directly within the Web browser through Microsoft's Silverlight Flash-esque framework. Windows seems to get a bad rap in the Ruby community so we thought we'd turn the spotlight on some of the cool things IronRuby's doing nowadays.

Being based on the .NET CLR presents some unique challenges for IronRuby. So far IronRuby passes 86% of the RubySpec (compared to a 98% pass rate for the MRI on Windows) but this number is creeping up every week. To learn more, I caught up with developer Jimmy Schementi of Microsoft to ask some questions about the project and its workings.

grantmichaels: There are ~150 native extension gems for Ruby, some of which are prolific and often depended upon by other gems. Does your Ruby implementation support FFI (foreign function interface) at present, and/or how much of a priority is running native extension gems going forward?

Jimmy Schementi: IronRuby does not support the Ruby C API which extensions depend on today, and there are no plans to support it either; it’s too difficult to support 100%. However, we do have plans post 1.0 to support FFI, as native code interop from Ruby is very important to IronRuby; it'll make the implementation able to talk directly to native code when running on .NET or Mono. Keep in mind the Win32API is supported in IronRuby, so you can call Win32 functions without writing C#. Today IronRuby developers have to write some C# code which can interface with non-Win32 native code, through the platform invoke APIs, which turns out to be not any more work than using FFI would be, but it does require breaking outside of IronRuby. From there IronRuby lets you consume the C# code without an interop layer.

Passing RubySpec tests is fundamentally important for a modern, robust Ruby implementation. Has this compliance lowered the theoretical performance ceiling of your implementation considerably?

Of course, but can you think of another way? I think every language implementation will tell you that during the very early stages of development they were blazing fast, but as they got closer to implementing compliant Ruby functionality, performance suffered, or it just got harder and harder to keep the implementation at the same level of performance. But that's understandable for a language like Ruby; it puts the burden of cleverness on the language, rather than developer writing applications in Ruby.

Keep in mind though, RubySpec is not for performance testing. And while the ruby-benchmark suite is a fine benchmark suite, the most beneficial performance improvements for IronRuby have come from analyzing and optimizing actual programs, like Rails, RSpec, RubyGems, Cucumber, IRB, etc. RubySpec did play a role here, as it helped make sure we didn't degrade in compliance while using the real applications for performance tuning. Also, we have analyzed MSpec (RubySpec's test runner) on IronRuby for startup and throughput performance.

Closures, continuations, and tail-call optimizations are often discussed in terms of programming language VM's. Which of these attributes are implementable at present, which are expected to be implemented, and which are not possible by design?

Closures aren't really a VM feature, as they are just a block of code executing in a context. As the Dynamic Language Runtime is a language-implementing tool, it does support closures, but IronRuby does not use them; they are forked in IronRuby, though we'd like to put our updates in the next version of the DLR.

However, the Common Language Infrastructure does provide a big part of what a closure is; the block of code, which is called a Delegate. Delegates are essentially function pointers, though they are first-class objects in the CLR, so the can be part of a method signature, stored on other objects, garbage collected, and have any other properties that objects have. Coupled with DynamicMethods, which allow for at-runtime IL (the CLR's intermediate language) generation and conversion to delegates, IronRuby is able to directly invoke CLR code, as well as expose Ruby methods as delegates for CLR code to use.

Although continuations are not part of the ISO CLI, though Mono now supports microthreading and coroutines on top of the CLI. which allows them to implement continuations. Microsoft's CLR does not support continuations, so IronRuby does not have support for the "callcc" today. IronRuby could support true continuations only when running on Mono, but only if IronRuby users pushed for it, and even then we'd really like to avoid different behavior based on the runtime.

IronRuby does not have any support for tail-call optimization. Tail-call optimization is supported by the CLR, but it's not automatic; IronRuby must detect this and correctly emit the opcode for tail-call optimizations, and even then the code needs to fit a specific criteria for the just-in-time compiler to recognize the opcode. However, the CLR's way of supporting it is not why IronRuby doesn't support it; in real Ruby code you'd probably never see tail-call optimization happening, so we haven't seen a need for optimizing this. Tail-call optimization's main benefit in functional languages is to reuse the caller's frame by replacing recursion with a loop, rather than creating a new frame for each recursive call. In Ruby this optimization would be irrelevant if a block or proc was used in the caller, since a new frame would be required for each.

How integral is dynamic feedback-based optimization to reaching a high level of performance? Do you feel it will be possible to maintain acceptable speed into the future without embracing these strategies or are there less well-known alternatives which are potentially more effective?

If by "dynamic feedback-based optimization" you mean "inline caching", then it is very integral to performance of IronRuby. The Dynamic Language Runtime, which IronRuby uses for a target syntax tree, code generation, and interop with the CLR, uses "polymorphic inline caching", which means it caches all call signature a method encounters, turning subsequent calls to the same method (with the same signature) into a cache lookup for a delegate representing the method.

What are your thoughts on the Ruby programming language in the context of distributed programming?

As the number of processors are becoming more and more crucial to the overall speed of CPUs, Ruby needs to make distributed programming a first-class concept in the language to ensure it's continued usage in this changing computing landscape.

The Ruby language is very expressive, and I have no doubt the distributed programming paradigm will fit seamlessly into Ruby's syntax. Ruby's first-class closures and syntactic-sugar around them (blocks) are a natural way of expressing parallel operations. Also Ruby's enumerators and future features like a lazy-array provide the right tools to make parallel programming even easier.

However, Ruby does not have native thread support, so anything that will run truly in parallel will need to run cross-process. While this will work great for MRI, other implementations will have to find ways to make this work well on their platform. I see this as place where the various implementations of Ruby can step up and provide a native runtime-based way of running programs in parallel. For IronRuby, we could utilize the Parallel Extensions libraries to build any Ruby-based parallel support on-top of. In fact, these libraries could be used directly from IronRuby today. For more information about writing parallel software on the CLR, there is a detailed paper as well as a good amount of examples.

Which of 1.8.7 and 1.9.x is your implementation compatible with?

IronRuby 1.0 targets compatibility with the latest patch-level of 1.8.6. IronRuby does have a "-19" flag to enable any Ruby 1.9 features implemented along the way, but it will be disabled for the 1.0 release.

IronRuby 1.x will drop 1.8.6 support and only target the latest version of 1.9. There won't be a specific version which targets Ruby 1.8.7, but those features will probably be the first set of things implemented in the 1.x branch. IronRuby 1.0.x will be a servicing branch for IronRuby 1.0, and that branch will continue to only support 1.8.6.

Do you think further acceptance of Ruby is driven equally by spending man-hours working on performance and by meeting an international body’s specification?

As a Ruby implementer, I welcome a specification for Ruby that everyone agrees on as what makes Ruby the excellent language it is, as long as it doesn't hinder adding future features to the language. Having a specification will probably make it easier for implementations to achieve acceptable performance, because they can design their system with all the requirements of Ruby in sight.

What are your team’s goals for the next quarter, the next year?

IronRuby 1.0 will be released withing the next quarter, with the goals of improving startup significantly, getting RubySpec passing at over 95% across the board, and ensuring compatibility with popular application test suites and scenarios. We will also invest some time in taking advantage of the new features in .NET 4 and Silverlight 4, as well as a push to ensure compatibility with the latest version of Mono.

For the next year, the IronRuby team will focus on 1.9 compatibility, explore tooling options in Visual Studio 2010, and support Ruby and Windows developers to make IronRuby a premier Ruby implementation for Windows.

Besides any obvious platform niche, why might someone benefit from electing to use your Ruby Implementation?

When you ignore the platform niche all implementations of Ruby are pretty similar. In fact, it's the underlying platform that gives one flavor of Ruby advantages over another. For example, MRI has extremely fast startup compared to other flavors, but lacks the rich graphical libraries that Java and .NET have. In the end it’s all about what’s most important to the Ruby user, and in IronRuby’s case there are lots of platform-related benefits, some of which include .NET's integration into the native Windows GUI system, running Rails on Windows through IIS — along-side other ASP.NET website, running in the browser through Silverlight, and the Parallel Extensions library I mentioned earlier.

How much of an advantage is it that you aren't also responsible for maintaining the VM?

Well, for starters it's one less place we have to be responsible for bugs, though working-around any bugs is our responsibility. We don't have to worry about VM issues across different platforms, as the CLR and Mono take care of that for us. Mono is extremely fast in fixing any bugs we discover, like a matter of days, which definitely beats fixing them ourselves. From a ecosystem point-of-view, other things that built on-top of the CLR get interop with Ruby code for free, like running in the browser through Silverlight/Moonlight, and CLR-based debuggers (like MDbg, Visual Studio, and MonoDevelop).

Windows Vista and aboves with .NET pre-installed, most Linux distributions pre-install Mono or it's readily available via packages, and Mono is also easily installable on Macs. Despite that, a number of Rubyists somewhat disregard IronRuby for having any relationship whatsoever to .NET. Are they throwing the baby out with the bathwater?

I'd say so, but they don't necessarily need to "switch" to IronRuby; all Ruby implementations have their own uses. Ruby is unique in that it runs almost anywhere, giving Rubyists a plethora of tools to choose from to solve their problems, while still writing code in Ruby. In fact, this ubiquity makes Rubyists more valuable developers. As Ruby becomes a more accepted language for .NET shops to use, Ruby developers will be in high demand.

[job] Northwestern University (Chicago, IL) is looking for a Rails developer at the Feinberg School of Medicine on their downtown Chicago campus. Experience with BDD, Agile, and CI essential.

MessagePack: Efficient, Cross Language Binary Object Serialization

Sat, 03/20/2010 - 14:18

MessagePack GitHub repo is a new binary-based object serialization protocol and library built with efficiency and speed in mind. Developer Sadayuki Furuhashi presents it as a faster alternative to JSON that has similarly broad support across several popular languages.

Serialization is the process of taking an object (such as a string, hash, or even something of your own creation) and turning it into a single time of data that can be transmitted down a network connection, stored in a file, or similar. Protocols like JSON, YAML, and XML are commonly used for this purpose, but for the highest efficiency, binary protocols are an alternative. One option available to all Ruby developers (as it's in the standard library) is the Marshal library but this protocol isn't cross-language friendly (or even between some Ruby versions).

To demonstrate MessagePack's speed, the developer presents the results of a benchmark where 200,000 objects made up of three integers and a 512 byte string were serialized and deserialized once each:

While Ruby is the focus, there are also libraries for Python, Perl, C/C++, Haskell, and Lua ready to roll.

Installation and Example

To install MessagePack:

gem install msgpack

Example:

require 'msgpack' msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03" MessagePack.unpack(msg) #=> [1,2,3]

Best of RubyFlow: 12 Ruby Links From March 2010

Fri, 03/19/2010 - 15:45

RubyFlow is Ruby Inside's community driven sister site where you can post cool Ruby links you want to share (even of your own stuff). With 20–80 posts each week, there's too much to cover on Ruby Inside, but I want to provide a regular roundup of the "best of" RubyFlow. This instalment covers early March — enjoy!

And for comic relief (don't visit if you're easily offended):

EventMachine: Get Excited By Scalable Non-Blocking I/O

Fri, 03/19/2010 - 00:36

EventMachine is a simple(ish), fast, event-driven I/O library for Ruby. Its goal is to provide highly scalable I/O performance with an easy-to-use API wrapped around the nastiest parts of the process (since typical Ruby coding practices aren't particularly event-driven friendly). Aman Gupta has put together an awesome 114-page deck of slides (also available as a PDF) that walks through EventMachine with lots of practical code examples.

The presentation walks through:

  • Who uses EventMachine (a lot of big guys - Heroku, GitHub, 37signals, Engine Yard, PostRank)
  • What EventMachine is good for
  • Ruby's other I/O solutions (and why they suck)
  • What a "reactor" is
  • How to write asychronous code with EventMachine's API
  • How EventMachine provides event-compatible iterators and timers
  • EventMachine's message channels

Even though Aman's slides are meant to go alongside a live presentation, they stand well on their own and provide more than enough incentive to check out EventMachine is event-driven I/O is something that would benefit you, so stop reading this post and get flicking through Aman's awesome slides!

How To Build A Mac OS X App With XCode and MacRuby

Mon, 03/15/2010 - 14:30

Want to develop a Mac OS X app without getting waist deep in Objective C? MacRuby is the answer, and it’s now mature enough to use directly from XCode to build fully-featured Ruby-powered Mac apps. “Jean Pierre Hernandez” of Phusion presents a walkthrough of how to do it, step by step.

The tutorial walks through:

  • Creating a new project in XCode
  • Designing an interface with Interface Builder
  • Customizing form widgets
  • Writing a controller in MacRuby
  • Connecting the controller to the window

Any knowledge of XCode, Objective C, and Interface Builder will enable you to get through this walkthough a lot quicker, but it’s not essential.

Installing MacRuby and XCode

While it’s possible to install MacRuby by compiling yourself, it takes forever, so Jean Pierre recommends grabbing the latest stable binary release and going from there. It’s quick to install and doesn’t require any messing around at the command line. Also, if you haven’t yet installed XCode from your OS X discs, now’s the time – you’ll need XCode to get anywhere with this walkthrough. You can also download them from Apple.

Aside: Phusion Gets A New Homepage

As an aside, Phusion recently launched their all new official Web site. The grungey look and graffiti logo are gone, and have been replaced by shiny, modern 2010 gloss. They’re focusing on providing Ruby and Rails performance and underlying infrastructure services to companies who demand serious power from Ruby. Check it out.

How To Find Ruby User Groups

Tue, 03/09/2010 - 14:31

Ruby User Groups (RUGs, for short) are typically informal organizations put together to encourage Ruby developers with certain areas to get together, share ideas, and, often, to have some fun. If you're lacking for inspiration or want to get to know some Rubyists within certain parts of the world (or just around the corner, if you're lucky), heading to a Ruby User Groups' meeting can open a lot of doors. But how can you find them?

RubyUserGroups.org

RubyUserGroups.org is a new site by Joe Pym and Karl Doody (who run the West Midlands RUG) that presents you with a map (centered on your current location) with all of the local Ruby user groups located. If you're starting a RUG or your favorite one isn't listed, you can sign up an add it. There's also a giant list on the front page of all of the RUGs worldwide if you'd rather scroll through. There are RUGs as far afield as Tunisia, Cambodia and Madagascar!

Ruby.Meetup.com

Ruby.Meetup.com lists 104 RUGs, and the benefit of using Meetup.com is that many of them use the site to co-ordinate their events, so you find out when the next meetup is occurring, etc. Meetup's indexing of previous attendees also gives us an insight into the most popular RUGs: San Francisco, Silicon Valley, Los Angeles, East Bay, and NYC coming in top with 700-2000 registered followers apiece.

Rubyists.EU - European Rubyists Unite!

Rubyists.EU is an attempt to unite European Rubyists. It's a well designed site and as well as showing all of the known European RUGs on a map, there are FaceBook, LinkedIn, and Twitter feeds to keep track of, as well as an IRC channel and mailing list.

Vagrant: EC2-Like Virtual Machine Building and Provisioning from Ruby

Mon, 03/08/2010 - 21:52

Vagrant is a Ruby-based tool for building and deploying virtualized development environments. It uses Oracle's open-source VirtualBox virtualization system along with the Chef configuration management engine along with lots of Ruby goodness to automate the creation and provisioning of virtual machines for development purposes.

If you thought rolling out new VMs using Amazon EC2 was easy, Vagrant brings an even simpler system to your local development machine. From the command line, starting is as easy as:

sudo gem install vagrant vagrant box add base http://files.vagrantup.com/base.box mkdir vagrant vagrant init vagrant up

Be warned, though - as a 370MB download, adding that box image isn't a quick process! Once you've got it though, you can keep rolling out VMs based on it at will.

Note that VirtualBox is a separate dependency for Vagrant. Vagrant does not come with VirtualBox built in or anything like that. Download VirtualBox for your OS if you want to try Vagrant.

Beyond the basics of getting a VM running, Vagrant can take care of port forwarding, distribution, environment setup, SSH access, shared folders and, importantly, the provisioning of software onto the VM using Chef. If you want to automatically roll out a VM with Apache 2, Rails, Phusion Passenger, or the like, Chef and Vagrant will take care of it for you. This is powerful stuff!

In terms of documentation and having a straight forward official homepage, Vagrant sets a solid benchmark. There's a straightforward guide to getting started with Vagrant, lots of documentation, and a 12 minute getting started video/screencast. Great work guys!

In-depth JRuby Q&A: What Makes JRuby Tick in 2010?

Tue, 03/02/2010 - 16:00

JRuby is undoubtedly the most mature of the alternative Ruby implementations. Supporting Ruby 1.8.7 and 1.9.1 (mostly!) and JIT compilation, JRuby is already in use in mission critical Ruby apps and runs scarily fast on the JVM. In this interview with JRuby core member, Charles Nutter, we dig deep into what makes JRuby tick.

A great deal of conversation on IRC, as well as quite a number of lengthly emails, were eventually corralled into the following Q/A session between Charles Nutter and myself.

JRuby and Rails are the ideal solution for building new enterprise web applications. With JRuby's ability to seamlessly integrate with anything Java, and Rails' strong REST principles, these new applications will be 100% WOA compliant themselves, and also may trivially extend WOA compliance to the underlying Java systems. Rails makes it easy and inexpensive, and JRuby leverages the capacity, manageability and security of existing Java deployment farms.

— Tom Mornini (@tmornini)

The JRuby guys are doing the hard, bone-crunching work of exposing a high-quality Ruby implementation to millions of new developers. It's not glamorous work, but the work they've been doing has already changed the landscape of Ruby, and there's much more work still to come.

— Yehuda Katz (@wycats)

The JRuby / Charles Nutter Q&A

It's frequently mentioned that the HotSpot JVM has 500+ man-years invested, and you've mentioned not only how infrequently you experience faults within the JVM, but at once how quickly they are addressed by the Hotspot team. How much of an advantage is it that you aren't also responsible for maintaining the VM?

It is a tremendous advantage for anyone using an existing VM. Many folks don't realize how much effort is required to build a new VM from scratch. You need a reliable optimizing compiler that not only makes code run fast, but does not change the execution results of users' programs. You need memory management and garbage collection systems that limit pauses, keep memory usage within reasonable levels, and don't become performance problems for systems under load. You need safe and reliable native interfaces that protect the integrity of VM internals. If you can achieve those items, you may want real concurrent threading that doesn't cause the runtime to crash in unrecoverable ways. You may want tunable settings, like those added to REE to adjust garbage collection parameters. You will almost certainly want debugging and profiling interfaces that don't drastically impact performance. You may want management interfaces that allow you to monitor and configure the system at runtime. You may want security guarantees, so users can safely sandbox code and be certain it will remain within operating parameters. And ideally, you want experts working on all these subsystems. That's exactly what you get with the JVM.

And it goes even farther than that. There's not just one JVM, there's at least three in widespread use: Sun's Hotspot, the VM behind OpenJDK; Oracle's JRockit; and IBM's J9. Each one has whole *teams* of developers working on those subsystems. And each company has competed for years to make their JVM better than the others. There are JVMs for every platform in use; we've gotten bug reports from users on exotic systems like Z/OS and OpenVMS. There are VMs that run on the smallest embedded devices and on the largest many-core systems you can imagine (see Azul's JVM and hardware, running on hundreds of cores with hundreds of GB of memory). There have been JVMs on mobile phones for almost a decade. Every Blu-Ray player runs a JVM. There are JVMs literally everywhere.

It's impossible to measure how much effort we've saved by building atop the JVM ... but it's a tremendous amount.

Garbage collection in MRI Ruby has been singled out as a significant performance issue. HotSpot has been said to have a sophisticated and excellent garbage collection strategy. How important is garbage collection for all Ruby implementations? How important is it for JRuby specifically?

Ruby is an extremely GC-intensive language. Much of the performance improvement in the upcoming Rails 3 comes from reducing object churn and therefore reducing the amount of GC necessary. Another example of this is the success of REE, in large part due to performance-improving patches to the MRI garbage collector. There are many such examples, and as a result, you simply can't have a high-performance Ruby without a high-performance GC.

In JRuby's case, we can leverage the years of effort that have gone into the JVM GCs. On Hotspot, the JVM we generally test against, you have not one but as many as 5 different garbage collectors to choose from. There are collectors that optimize straight-line allocation and GC performance (like Hotspot's "throughput collector"). There are collectors that spread collection across cores to reduce pauses (the "parallel collector"). There are collectors that run nearly pauseless, running some collection phases concurrently with your application's code (the "concurrent collector"). There are collectors that focus on aggressively localizing objects of similar ages so they can be collected in groups (the G1 "garbage first" collector). These collectors can often be mixed and matched depending on how your application behaves (or how you need it to behave). And they all can be almost infinitely tuned and monitored.

JRuby's performance on numeric benchmarks serves as another example of how well JVMs manage memory...

One feature the JVM does not yet have is "fixnums". Fixnums, in the VM world, are the ability to treat certain numeric values as though they were objects, without them actually being objects. Usually, this is achieved by dedicating a range of memory addresses as "tagged integers", so that by masking off a few bits, you get the actual numeric value. This could, for example, reduce the cost of "boxing" integer values in java.lang.Integer objects to almost zero, allowing them to behave like objects but take up no memory on the heap and require no special attention from the garbage collector.

All the MRI-based implementations use "true fixnums", as do several of the alternative implementations. JRuby does not, since the JVM does not support fixnums yet. As a result, we have to actually allocate a fixnum object for almost every math operation or for each iteration of a numeric loop. Those objects take up heap memory and eventually have to be collected.

We've always accepted that we'd eventually be surpassed on numeric performance, since fixnums have a much higher cost for us. But even though some of the newer fixnum-supporting implementations have better numeric performance than JRuby, we're still able to come very close--even with all that fixnum object churn. Our numeric performance rarely impacts typical applications, and that's a testament to the performance of the JVM's memory subsystem.

(FWIW, there are several other JVM languages crying for "true fixnums", and I'd be very surprised if we didn't see an implementation within the next year.)

It's a very different sensation to develop with JRuby with regards to start-up time. How are people minimizing this impact in production today, and what might be done to improves this micro-benchmark in the future?

Start-up time is one of those areas JVM engineers have unfortunately neglected until recently. JVM engineering has, for most of its lifetime, focused on the performance of long-running applications. Indeed, the best performance of JRuby (and other JVM languages) comes after not just slow startup but after a substantial warm-up period. This works great for server-side applications, but client-side use--whether for test-driven development, command-line tooling, or quick scripting--can sometimes be painful to deal with.

There's also a culture clash here. Basically all JVM-based developers do their development inside an IDE, which often can run tests in the same JVM process from run to run. And JVM engineers have only recently started focusing efforts on startup performance (like the work Apple did with Java 1.5, which was built upon Hotspot).

But things are improving. JVMs that used to take ten or more seconds to start up may now take well under a second. That was unheard of 5 years ago. Additional work going into OpenJDK 7 and OpenJDK 6 updates promise to improve this further, and future research may even help reduce the warmup time required for maximum performance. Projects like JRuby have helped drive this work forward.

And we also understand the pain that slow startup can cause users. With each release we spend some time looking for ways to improve JRuby's startup. Indeed, we even use slower JVM settings by default because we want the user experience to be better (specifically, we try to force Hotspot-based JVMs to use the faster-starting but less-optimized "client" VM, with switches to turn on the optimizing "server" VM). With JRuby 1.3, we started shipping support for "Nailgun", a persistent background JVM you toss commands at (in order to reduce the spin-up and warm-up time for quick commands). There's more work to do, but we feel users' pain, and try to address it better with each release.

Macs ship with a JVM, it's readily available for Linux distributions via packages, and a number of Windows machine vendors have it pre-installed nowadays. Despite that, a number of Rubyists somewhat disregard JRuby for having any relationship whatsoever to Java. Are they throwing the baby out with the bathwater?

They certainly are, but we also accept that JRuby isn't for everyone. Maybe the startup time is a show-stopper. Maybe it's JRuby's less-than-perfect support for exact POSIX IO and subprocess behavior. Maybe it's the lack of support for C extensions. There are certainly reasons why JRuby wouldn't be the best choice for certain problem domains. But there's also tremendous potential for JRuby to bring Ruby to problem domains, organizations, and platforms that it might never have been able to reach. JRuby opens up a huge world of opportunity for Rubyists and brings Ruby to the huge world of JVM-based developers. It's such a beautiful match that I spent 20-30 hours per week on JRuby for almost a year before being hired by Sun ... all in my spare time, because I was so excited about the possibilities.

What really depresses me is that many of the folks dismissing JRuby are exactly the folks who could help us make Ruby a better option for developers on the JVM. We need Rubyists skilled in building DSLs, skilled in designing libraries, skilled in integrating systems. We need day-to-day Rubyists to show Java developers how much better things could be for them. We need the amazing Ruby community to help us bring Ruby to a much larger world. There's no time for platform bigotry ... we all want the same thing: Ruby everywhere!

What can you tell the common Rubyist about application platform layers like the ones provided by Torquebox and Glassfish?

Both Torquebox (JBoss's set of excellent Ruby wrappers around key server-side Java APIs and tools for deploying JRuby on Rails applications) and GlassFish (Sun Microsystem's modular Java-based server, with lightweight "embedded" JRuby deployment support and a few similar API wrappers) are examples of how the best parts of the Java/JVM ecosystem can be repurposed (and improved) using a little Ruby knowhow. In both cases, you get simple, one-shot deployment (of multiple applications, I might add), along with well-designed service APIs and management tooling.

We would love to see the "Torquebox approach" or the "GlassFish way" applied to other popular Java APIs for persistence, networking, web services, and more. We'll try to tackle some of the key libraries ourselves, but again we need help from the Ruby community. And in return we'll promise to faithfully support Rubyists and to continue improving JRuby.

Github used JRuby to allow for code obfuscation and I'm assuming to best integrate with the kinds of customers who would pay for it. Do you see this type of decision making driving JRuby adoption as Ruby becomes more commonplace in the enterprise?

As long as there's demand for Ruby, there will be demand for features unique to JRuby like easy deployment on Java services and compiled "obfuscation" like the Github folks needed. And these are only the beginning. JRuby can make it possible to write Ruby-based Android applications. JRuby can produce fully-compiled desktop applications in a single executable file that runs wherever there's a standard JVM. JRuby can integrate easily with other JVM languages and access the vast world of JVM libraries. And it can do all this while still being true to Ruby.

All we have ever wanted is for JRuby to be a powerful, useful tool for JVM users and Ruby fans alike. And anyone who has talked to us knows we put the needs of our users first. Why not become a JRuby user today?

Gartner Inc. predicts that Android will make up 14% of the smartphone market in the year 2012, second only to the Symbian OS that powers some popular Nokia phones. What can you tell us about working with Android via JRuby?

It's still early days for "Ruboto" (JRuby on Android), but there's a lot of potential. I've been hearing from a few people every week interested in using Ruby as their Android language of choice, so the demand is certainly there. And with the Android 1.6 and 2.0 updates, JRuby appears to work fully on Android without any modifications.

For an early example of what's possible, check out my ruboto-irb project on Github (link), which is basically an interactive Ruby session that runs directly on the device. You can do everything you would normally do with Ruby in IRB, plus construct and call Android core classes. It's great fun, and with a bit more work I could see JRuby being ready for production use on Android.

Recently I've noticed some dialogue with regard to JRuby and Maven. I've seen references to Maven v3, and also to "Polyglot Maven." Can you shed some light on the implications of this new interoperability for the everyday JRubyist?

There are two projects for JRuby and Maven integration.

The first is a prototype Maven server that looks and feels like a RubyGems source. By setting this server as a source (or passing it to the gem command), any Java library in the world is installable as a gem. Let me repeat that: ANY Java library in the world, installable as a gem. This means you can also use Maven artifacts as dependencies in regular Ruby gems, and it additionally means we won't have to re-release jar files into their own duplicate gems on the standard repositories. It's very exciting, and we hope to have it ready for JRuby 1.5.

The second project is part of the official "Polyglot Maven" work started by Jason van Zyl and the Sonatype folks. That project intends to provide standard DSLs for popular JVM languages, allowing you to use those languages in place of the XML-based POM files so many people hate. In addition, those DSLs would have access to Maven's workflow and data model classes, providing fully-scriptable Maven builds without a lot of the noise of a typical Maven project. This work is still in early days for JRuby; I've only committed a couple prototype scripts to the repository. We would love to have help here, since we're not really Maven experts.

Generic Q/A

There are ~150 native extension gems for Ruby, some of which are prolific and often depended upon by other gems. Does your Ruby implementation support FFI (foreign function interface) at present, and/or how much of a priority is running native extension gems going forward?

I believe that native extensions are the #1 thing holding the standard Ruby implementation (MRI) back. If you look at archives of the Ruby mailing lists going back for years, maintaining extension compatibility has always come at the expense of improving MRI. You want a better GC that's generational and compacting? Sorry, that wouldn't be compatible with current extensions without a big performance hit. How about real concurrent threads? Nope, without adding fine-grained locks or safepoints around all extension calls, you're sure to segfault somewhere.

JRuby does support FFI, and has for well over a year now. In fact, Wayne Meissner of the JRuby team is largely responsible for FFI being a viable alternative to C extensions, since he implemented the FFI gem for MRI and has been working closely with the FFI community ever since. We believe FFI, or mechanisms like it, are the best way to call C libraries from Ruby, regardless of the implementation, and we encourage people to use FFI if there's a native library they simply must use.

As far as real native extension support... anything's possible, but we have no plans to support MRI's C API in JRuby. The API is unfortunately very invasive, giving direct memory access to object internals in many places. In order to support this on JRuby, we would need to copy lots of data back and forth on every call, not to mention locking down extension calls per-thread completely to ensure they weren't stepping on each others' data. It might be possible to get a limited subset of the MRI extension API implemented for JRuby, but existing extensions would require some rework and performance would probably end up worse than FFI due to the amount of copying and locking required.

In general, the only 100% answer for JRuby is to port extensions to a JVM language or wrap existing JVM libraries (and there are literally tens of thousands of libraries available). FFI provides a good stopgap or bandaid for the problem, but it still requires us to load a native library which many deployment environments will disallow. Only pure-"Java" libraries (where by "Java" I mean "some JVM language") will have the best possible chance of running on all target systems.

Passing RubySpec tests is fundamentally important. Has this compliance lowered the theoretical performance ceiling of your implementation considerably?

Ruby is a difficult language to implement. JRuby is arguably the only production-quality alternative Ruby, and that quality has come after literally dozens of man-years of work. We've also managed to achieve production-level compatibility while turning JRuby into one of the best-performing implementations, so we have a solid understanding of the challenges involved.

There's no doubt about it: Ruby has lots of features that make optimization really hard. Being able to use a block as the binding to an "eval" call forces us to keep all of the block's surrounding state, even if the block itself doesn't need it. Backref and lastline references ($~ and $_ variables) require a called method to be able to modify the caller's context, even if the method itself never accesses those values. The ability to replace methods on core classes - even super-important ones like Fixnum#+ - means we have to always check for those modifications. Even simple things like "eval" and "send" force us to deoptimize more code than we'd like.

We have managed to work around many of these challenges, just like some of the other Ruby implementations, but many of them remain. In almost every case, we've tried first to get solid compatibility, optimizing later as much as we can. We plan to revisit those performance challenges in the future, learning from other dynamic language runtimes and other Ruby implementations about new ways to optimized. But right now we're pretty happy with JRuby's performance, which puts us at least on par with Ruby 1.9 for almost everything (and faster for many things).

Closures, continuations, and tail-call optimizations are often discussed in terms of programming language VM's. Which of these attributes are implementable at present, which are expected to be implemented, and which are not possible by design?

Closures are probably the easiest one. If you can save some local context and pass it around with a function reference, you've got closures. There's plenty of details, like making non-local flow control work (break or return inside a block), but in general they're not difficult to support.

Continuations and tail-calls unfortunately both require VM-level support to do well.

JRuby does not support Ruby's continuations because the JVM does not (yet) support continuations. In order for us to implement continuations atop the JVM, we would have to forgo standard Java method dispatch for all of JRuby, since any calls that would deepen the stack would make saving a continuation impossible. The performance impact of this would be tremendous: the JVM gets its performance because it's able to optimize normal chains of calls; by trampolining in and out of methods at the same stack depth, practically none of the standard optimizations would fire. We actually did try a "stackless" implementation in 2005, and I demoed it at RubyConf that year. It could calculate a recursive fib(1_000_000), but it ran so incredibly slow (orders of magnitude slower than what we have right now) that it simply wasn't feasible.

For tail calls, VM support is necessary to do a 100% job, but you *can* fake some recursive tail-call optimization by branching back to the top of a method body. We have not implemented any "tricky" tail-call optimization yet, but it's a possibility for future versions of JRuby.

And in both cases, there's some interesting work on the horizon. Both tail calls ("true" tail calls) and continuations are being developed against the Multi-Language VM subproject of OpenJDK, and both actually have working patches right now. There's a good chance that a future version of the JVM will have support for true tail calls, and a slim chance that delimited continuations (coroutines) might arrive as well. That's part of the beauty of JRuby: there's dozens or hundreds of JVM engineers out there working to make it faster, working to add features, and competing with each other. JRuby users directly benefit from all that work.

How integral is dynamic feedback-based optimization to reaching a high level of performance? Do you feel it will be possible to maintain acceptable speed into the future without embracing these strategies or are there less well-known alternatives which are potentially more effective?

Because we run on the JVM, we already benefit from a tremendous amount of runtime optimization. JRuby's core classes (Hash, Array, etc) are perhaps the fastest implementations of any Ruby, largely because they're all written in Java and benefit from the very best JVM optimizations available. At the end of the day, the vast amount of Ruby execution is in the core class implementations, so they really need to be as fast as possible, and Java is our "C" for doing that.

We also benefit from feedback-based optimization when running Ruby code, though we still have a lot of opportunity here. Currently, JRuby's Ruby compiler is fairly "dumb": it doesn't use runtime profiling *at all* and only does a few limited static optimizations. Now of course the JVM is able to pick up a lot of slack, using its own runtime profiling to make our "dumb" generated code run really well. But because we recognize that we need to help the JVM out a bit more, we do have plans to introduce more runtime feedback into our Just-In-Time compiler subsystem. Expect to see more work on JRuby performance in 2010.

There's also a Java 7 feature we've started to play with: fast dynamic invocation. JSR-292, the "invokedynamic" JSR, is adding a new bytecode called "invokedynamic" to the JVM. The invokedynamic bytecode allows us to wire up (for example) Ruby method invocation directly into the JVM's call protocols. As a result, the JVM can do all its usual inlining and optimization even across Ruby calls. Early results have been promising... even without a lot of optimization, the current invokedynamic implementation is 20-30% faster than our old call protocols. We've been working closely with Hotspot engineers throughout their development, and we're really looking forward to seeing how well JRuby runs on invokedynamic in the coming months.

Which of 1.8.7 and 1.9.x is your implementation compatible with?

JRuby 1.4 made the move to Ruby 1.8.7 compatibility, because we felt that 1.8.7 has become established enough (and because we were tired of getting bug reports about 1.8.7 features being missing). We also have done a lot of work on supporting Ruby 1.9, though that's still a bit of a moving target. We're hoping that in the first half of 2010 we'll be able to reach feature-parity with the upcoming Ruby 1.9.2. We'll definitely need help from the community.

Do you think further acceptance of Ruby is driven equally by spending man-hours working on performance and by meeting an international body’s specification?

I think performance is somewhat of a red herring, and as I mentioned before it can be a tremendous resource sink. We will, just like the other implementations, continue incrementally improving performance. But given JRuby's unique features, our current level of performance is good enough for us to focus on other areas for a while. We won't ignore performance, and we don't want to fall behind in the endless performance wars, but we have to balance features, compatibility, and stability at the same time.

As far as specification goes... I think it's only useful for entities that require specifications. If it's true that many organizations worldwide will refuse to adopt Ruby due to a lack of a specification, then time spent preparing such a specification is probably worthwhile. Since there's already such an effort, I sincerely hope it will help increase Ruby adoption.

What are your team's goals for the next quarter, the next year?

The number one goal for me is Java integration. Java integration means many things:

  • ability to generate *real* Java classes for Ruby classes, both at runtime and ahead-of-time
  • fast-as-possible Ruby-to-Java invocation
  • ecosystem integration, like our recent work to make all Maven artifacts in the world transparently installable as gems
  • platform integration, like making Rails work naturally as a Java-land web framework, and making Java-land frameworks like Hibernate fit naturally into Rails

I also want to return to performance work, most likely by continuing the work that Subbu Sastry has already begun on JRuby's new optimizing compiler. The potential here is to do a large amount of optimization before feeding bytecode to the JVM, allowing us to approach the performance of statically-typed languages over the same code. We want to make Ruby run as well as possible on the JVM, and I think the new compiler work will be a big part of that.

Besides any obvious platform niche, why might someone benefit from electing to use your Ruby Implementation?

Well, we've got several years of production users under our belt! The value of having real users for several years can't be understated, and we learned very quickly that getting a 1.0 release out is just the beginning.

JRuby Installation

If you've still not given JRuby a proper try, you can learn more at the official JRuby site or if you're using the RVM (Ruby Version Manager) you can be up and running on the latest main build (1.4.0) with:

rvm install jruby Recent Confreaks Presentations

You can watch the full keynote "JRuby State of the Union" by Charles Nutter and Tom Enebo here at Confreaks' site or you can go directly to the video (MPEG 4) file here.

Conclusion

During their respective funding periods, Sun and Engine Yard have both had a strong commitment to JRuby. For Ruby to thrive, it ultimately needs to be deployed in numbers that achieve a lasting critical mass. There is a reportedly massive amount of existing infrastructure based on the JVM, which makes JRuby a noteworthy stepping stone to many interesting destinations, and based on what we've discussed here, why would anyone obstinately ignore JRuby any longer?

New Relic RPM Officially Supports Rack and Sinatra – Finally!

Thu, 02/25/2010 - 01:50

New Relic's RPM, an application performance monitoring and reporting system, has today announced it has added full support for Sinatra and Rack-based Ruby applications to its traditionally Rails-centric service. It's been possible to hack in support for non-Rails apps into New Relic before, but this move brings them officially into the fold with all of the features only Rails apps used to be able to take advantage of.

New Relic's press release on the news includes a typically "press release sounding" quote from Ryan Tomayko, but as a key contributor to Sinatra and Rails, and as a GitHub employee, it seems worth quoting:

Rack has given Ruby web developers a tremendous amount of freedom to innovate and experiment with new ways of building web applications.

Developers are increasingly turning to Rack and lightweight frameworks like Sinatra for small utility apps or for latching performance critical features onto an existing site. The ability to monitor and profile these applications using New Relic RPM fills a huge visibility gap for us.

So there you go. New Relic have also updated the "agent" that's used to communicate between your apps and their servers and added some Ruby specific features including enhanced visibility in garbage collection, developer mode profiling, "enhanced" JRuby support, and Phusion Passenger queue time capturing (this sounds particularly useful for tweaking your stack).

As always, New Relic RPM is free to use at a "Lite" level and if you're a new user, they'll give you a week of "Gold" level features for free to sweeten the deal. You can keep running at Lite after that though if you don't want to pay. The "Bronze" plan starts at $50 per month (on an annual basis) per host but they also have an "on demand" Amazon EC2 style pricing structure starting from 10 cents per hour.

We've been keeping an eye on New Relic since early 2008 and they seem to have gone from strength to strength over the years. Early on, FiveRuns' RM-Manage was still a better option than RPM (in my opinion) but with FiveRuns going the way of the dodo recently, New Relic have become the main game in town when it comes to Ruby webapp performance monitoring (though Scout are giving them a run for their money in certain areas).

Building A Well Formed Number Handling Class From Scratch

Thu, 02/25/2010 - 01:21

Over on the Ruby Best Practices blog, Robert Klemme walks through the process of building a new numeric class from scratch in Ruby - taking into account all the gotchas and considerations that pop up along the way. Robert's task is harder and more involved than you'd initially suspect.!

Robert chooses to build a HexNum class that can represent integers that are then displayed as hex numbers. There are considerations to be made with handling conversions from existing numeric types and his new HexNum class, conversions to other types, supporting standard comparison methods, and overloading.

All of the above concerns are covered in the post with all the quality and detail you should expect from the RBP blog by now. This post in particular should prove interesting to most Ruby developers who feel happy digging deep (no, this isn't an article for beginners!).

[job] BeenVerified.com is currently looking for a Ruby and Rails developer to join their team in New York City. Alternatively, check out one of the other 12 jobs on our Ruby jobs board!

How Ruby Manages Memory and Garbage Collection

Wed, 02/24/2010 - 00:33

Garbage Collection and the Ruby Heap is a presentation given by Joe Damato and Aman Gupta at the recent LA Ruby Conference. You only get the slides for now (all 70 of them!), but they're very detailed and can almost work as a standalone concise e-book on Ruby's garbage collection system.

Joe and Aman take a look at C memory management vs Ruby and show the difference between the stack and the heap. As a garbage collected language, Ruby takes the easy route by putting everything on the heap and the presentation demonstrates how the MRI (Matz's Ruby 1.8) does this, as well as how objects are tracked within memory (right down to the underlying C structs).

MRI's garbage collection scheme isn't particularly well optimized (though Phusion's Ruby Enterprise Edition has made some tweaks) and the presentation demonstrates the viability of some other garbage collection schemes (as always, the issue is compatibility with native extensions).

The presentation finishes off with a interesting walkthrough of using memprof (a Ruby memory profiler) to debug a memory leak in Rails 3.

[e-book] The Rails 3 Upgrade Handbook by Jeremy McAnally is a 120 page guide on migrating your apps from Rails 2.x to Rails 3.0. There's a review of it on Rails Inside if you want to learn more.

5 Chapters of O’Reilly’s Ruby Best Practices – Free!

Tue, 02/23/2010 - 23:03

Ruby Best Practices is a book by Gregory Brown (and published by O'Reilly) that looks into the "Ruby way" of doing things in the Ruby language and, specifically, why Rubyists tend to write Ruby the way they do. It's an engaging book and we took a look at it and interviewed Gregory Brown about it just over a year ago.

Gregory always wanted to be able to give away his book with a Creative Commons license eventually and O'Reilly have kindly allowed him to start doing that, a chapter at a time. So far, the first five chapters are available to download at GitHub (in PDF format). Specifically:

However, it's not just a free for all! If you read these chapters, Gregory (the primary author of the book) implores you to comment and offer any advice or insights you might have on the relevant posts on the RBP blog.. he also suggests that if you really like it, you should buy a copy of the book somehow, if only to convince O'Reilly that this publishing model is a "Good Thing." Gregory claims that the book hasn't even made its advance back yet (how!?), which makes this gesture all the better.

To buy a copy, head over to O'Reilly for e-book and print copies or go to your usual bookselling site (Amazon.com are probably the cheapest as usual).

Kudos to Gregory and O'Reilly for this move.

urchinTracker();