From: Lennon Day-Reynolds Date: 2004-07-02T02:01:53+09:00 Subject: Re: Why I don't use Ruby. Obviously, there have already been a number of useful comments about irb, the Ruby interpreter; it is an invaluable part of my development and test cycle, as I'm sure it is for many other Ruby users on this list. As for the issue of persistent heap images, I agree that such a feature would be quite useful, especially when coupled with an interactive interpreter. I've worked in groups that used Common Lisp as their primary development language, and I have to say that distributing an application was almost embarassingly easy when compared to, say, compiling and linking C sources, or installing a Ruby application with diverse library and version requirements. For those who haven't had the pleasure, let me give a brief explanation. Most implementations of Common Lisp (as well as many Scheme dialects, Smalltalk implementations, and other functional/research languages) include the ability to perform a dump of the entire runtime heap memory space into an "image" file. That snapshot essentially contains the working state of the system, much like the dump of RAM a laptop saves to disk for "hibernation" mode. The value of this feature for distribution comes from being able to then transfer this image file to another system, load it into another instance of the runtime there, and resume working where you left off previously. Most implementations also allow you to specify a new toplevel entry point, allowing you to effectively pick a 'main()' function of your choosing when creating the image. The "Prevayler" family of object peristence models are, in effect, a limited (though incremental, rather than bulk) version of this idea. By building such peristence into the core runtime, though, you can trivially distribute new versions of both the core language, and applications built on top of it. However, there are issues with this approach. Unlike most Lisps and Smalltalks, Ruby is not a self-hosting system; the core runtime is implemented in C, and depends heavily on the system libraries and memory model of the underlying operating system. By using native structures like file handles, dynamic libraries, and virtual memory management pervasively, Ruby has more or less bound itself to the lifecycle and call conventions of a "native" application. However, it should be entirely possible to experiment with a limited form of the global-image class of persistence. There are two main paths I could see working. The more obvious would be performing a standard Marshal.dump on every object in the heap, saving the state of any serializable objects to disk (and allowing them to perform any cleanup necessary prior to shutdown). Less trivial, but potentially more interesting, would be to allocate new objects within mmap'ed address space, (effectively bypassing the native virtual memory system) which would allow a 'dump' operation to simply be implemented as a 'sync' on that space. Updates could be incremental, and have near the same performance as the native OS does with VM paging. Anyone with more language implementation experience care to weigh in on the feasibility of such a hack? I know that several "academic" languages already implement such functionality, and that as a garbage-collected language, Ruby should already have most of the infrastructure necessary to build it again. Okay, enough rambling. Back to work. Lennon