Archive for May, 2006
A Longish Post about Package Names and Versioning
So, I’ve created a bit of a mess with regards to the naming of different versions of FXRuby and am trying to decide how best to solve that problem.
When FOX 1.2 was released, Jeroen made a number of API changes in order to promote more consistent naming conventions. For example, classes with names like FXScrollbar and FXStatusline were renamed to FXScrollBar and FXStatusLine, and everything was moved into a C++ namespace. FXRuby 1.2 inherited these changes and, as a result, threatened to break a lot of code in the process. Your compiler will loudly tell you that you’ve misspelled a class or member function name in your C++ code, but such errors won’t be discovered until runtime in an interpreted language like Ruby.
In a perhaps poorly thought-out workaround to this problem, I renamed the Ruby extension from “fox” to “fox12″ when FXRuby 1.2 was released (see the discussion in the mailing list archives). Code that was written against the FXRuby 1.0 API would continue to require 'fox' and would continue to work as before, using the installed version of FXRuby 1.0. Code written against the FXRuby 1.2 API would instead require 'fox12'. And this approach more or less worked, and wasn’t all that confusing, considering that there were only two choices of FXRuby to pick from.
Fast-forward a few years, and we’ve now seen both FXRuby 1.4 and 1.6 releases. Neither of these releases made significant API changes as compared to FXRuby 1.2, and greater care was taken to promote backwards-compatibility. The confusing extension-naming convention was followed, however, which means that application programmers have to do some trickery in their code to ensure that a working version of FXRuby is require‘d into their application. Ideally, code that was written in the FXRuby 1.4 era should continue to work unmodified if FXRuby 1.6 is the only version that’s available, but that’s not the case — at a minimum, you’re going to have to go in and modify the require 'fox14' statement to read require 'fox16'.
RubyGems provides a mechanism (via the require_gem method) to deal with these versioning issues, but at the time we made this decision for the FXRuby project (back in the summer of 2004), that feature had not yet been implemented in RubyGems. And even if it had been available at that time, RubyGems wasn’t the de facto standard for Ruby library distribution that it is now, and it wouldn’t have made sense to depend on the user having installed FXRuby from a gem.
One of the happy side effects (well, happy for some) of the explosion of Rails over the last year and a half is that the acceptance and use of RubyGems has become much more widespread. I don’t believe RubyGems is part of the Ruby core (and probably doesn’t belong there yet), but it is part of the One-Click Ruby Installer for Windows, and anyone who uses Rails is likely to have installed RubyGems as well. So it’s reasonably safe, at this point in time, for me to assume that RubyGems is going to be available on any platform where Ruby and FXRuby are running.
So the question is, what’s the best choice going forward? Discussion on the RubyGems developers’ mailing list seems to indicate that the requiregem method is going away, and that it will be replaced (sort of) with a new gem method that “activates” a particular version of a Gem by placing its directory in Ruby’s $LOADPATH (but that doesn’t actually require anything.) On the other hand, that particular discussion has been going on since at least since May of last year and doesn’t seem to be quite resolved yet.
As O’Reilly might ask, “What say you?”
On Ruby’s Performance
Comments in a recent interview of Zed Shaw have sparked a new round of discussion concerning Ruby’s performance (see the thread beginning here). Unlike, say, the recent ruby-talk thread on whether stealing is a bad or good thing, this thread actually has a lot of useful information tucked away inside.
Some people noted that for them and their applications, Ruby’s performance is more than adequate. James Britt noted that if bottlenecks are identified, performance-critical code can be re-implemented as a C extension module. Ara Howard (among others) seconded this point, furthermore asserting that:
the key to speed is c, not a vm and, if you ask me, that quest is the white elephant – not ruby’s speed. projects like ruby2c, ruby-inline, ruby/dl, swig – those are the way to speed. putting a vm on top of ruby and trying to make it fast is like chopping and dropping your mini-van and heading to the track : you are going to get killed.
Of course, you can write inefficient code in any programming language, are there are often small changes that can be made to improve the performance of “pure Ruby” code. Sam Roberts and Simon Kroger observed that for some of Sam’s code, the combined effects of making lots of method calls and creating large numbers of objects led to a serious performance problem. As my friend Jeroen likes to point out, the fastest thing that you can do is nothing, and “your slowest Celeron can do nothing as fast as your fastest Pentium D.” Although Jeroen’s usually saying this in reference to optimizing graphics performance, the same rule would apply for code that is (for example) creating lots and lots of objects.
Finally, although a lot of the talk in this thread touched on Rite and YARV (the new virtual machine for Ruby) and how that will impact Ruby’s performance, of special interest is an offshoot of this thread, started by John Carter, that talks about things we could be doing now (while we’re waiting for Rite) to improve the out-of-box performance of Ruby, such as taking advantage of all possible compiler optimizations.
Automating PowerPoint with Ruby
I knew that Ruby had some support for Windows OLE Automation — I vaguely remembered skimming over that part in Programming Ruby, once upon a time — but I’d honestly just never had any need to use it.
Well, that changed today. A client needed some code, as part of a more complicated tool chain, to open a named PowerPoint presentation and then save it as HTML. Not a complicated request, to be sure, but something that suggested the use of PowerPoint’s Automation capabilities. After a little bit of futzing around, here’s the code that I came up with:
require 'win32ole'
class PowerPoint; end
ppt = WIN32OLE.new('powerpoint.application')
WIN32OLE.const_load(ppt, PowerPoint)
ppt.Activate
ppt.Presentations.Open('FileName' => ppt_filename)
ppt.ActivePresentation.SaveAs('FileName' => html_filename,
'FileFormat' => PowerPoint::PpSaveAsHTML)
ppt.ActivePresentation.Close
ppt.Quit
I’m sure that it could be done in even fewer lines of code if I knew what I was doing. For example, I don’t know whether the call to Activate is even required, but it doesn’t seem to hurt. The issue of how to access an application’s constants (like the ppSaveAsHTML constant used in this code) threw me for a bit since that topic’s not covered in Programming Ruby, but a quick look at the RDoc uncovered the solution.
Dr. Dobbs discovers Rails
The June issue of Dr. Dobbs Journal includes an article about an exciting new web framework called “Rails”.
Sigh. I remember when I used to read DDJ religiously. I remember when they were one of the first “big-name” software magazines to publish an article about Ruby. But for various reasons, the content of DDJ over the last few years has become increasingly irrelevant to me. Is this really the first time that they’ve covered Rails?
Google Notebook
People seem to be comparing the newly-launched Google Notebook to del.icio.us, but it seems that a better comparison would be to sites like Clipmarks, or perhaps 37signals’ Backpack.
A lot of the criticism of Notebook focuses on the fact that (so far) it doesn’t support tagging of clippings. You can maintain multiple notebooks, and when you “note” something you assign it to one of those notebooks; but a clipping can’t belong to more than one notebook (or category) at the same time. I’m not sure that that’s a showstopper for me, when I think about how I’m likely to use Notebook. It is true that for my del.icio.us bookmarks, I typically assign multiple tags to a bookmark, and I rely on those tags to help me “find” links that I’ve tucked away. With Notebook, however, I’ll have access to Google’s search technology to search in my notebooks, and I anticipate that I’ll be able to find the clipping that I’m looking for at least as quickly as I would have using tags.
Another problem with Notebook is that there’s no mechanism for providing a “feed” of your notebook for others to subscribe to. I’m guessing that this shortcoming will be addressed by Google in short order, and again, it’s not really a showstopper for me.
So have you tried Notebook yet? What are your impressions?