[Borges-users] dynamic code loading
Слепнев Владимир
slepnev_v at rambler.ru
Sat May 8 13:32:34 EDT 2004
Hi,
in the last couple of days I implemented a very simple
dynamic-code-loader, and tried to hook it to Borges. The thing is
still pretty hackish and error-prone (Release Early!). But I like the
idea behind it: start a Borges app, edit the source for some
component, save it, then hit 'refresh' in the browser and see the
changes immediately. (The changes only touch the classes, all
instances keep their instance variables but their interfaces change.)
It could be a nice match to Seaside's code halos...
Here's my implementation of Dynload (it uses evil.rb :
http://evil.rubyforge.org)
require 'evil'
PLACE = binding
module Dynload; class << self
def register_source_directory(dirname) (@dirs ||= []) << dirname end
def load_all
@dirs.each {|d| Dir.foreach(d) {|f| load(d+"/"+f) if f =~ /\.rb$/ }}
end
def classdef(name, sup='Object', &defs)
called(name).become Class.new(called(sup), &defs)
end
private; def called(name) eval("class #{name};end;"+name, PLACE) end
end end
Here's how I hook it to Borges and use it in my own project (that's
called SMPM):
...requires for borges and other library stuff...
require 'Dynload'
# hack to use Dynload with Borges - not sure it works 100% of the time
class Borges::StateRegistry
alias old_rs restore_snapshot
def restore_snapshot(snap)
Thread.current[:session].in_thread {Dynload.load_all}
old_rs(snap)
end
end
# load source code
module SMPM; end
Dynload.register_source_directory('SMPM') #don't require all the
source files in the dir!
Dynload.load_all #this loads all the defs into the main namespace
# setup and start
SMPM::MainTask.register_application('smpm', SMPM::Session) # register
here, not in the component code!
Borges::WEBrickServlet.start
To reload stuff more or less cleanly, the classdefs for individual
components in the SMPM directory don't use the 'class' keyword, but
are 'customized' (the args are class_name and superclass_name):
Dynload.classdef('SMPM::GraphsFrame', 'Borges::Component') do
...usual function definitions...
end
I haven't really tested this stuff... but it works for me, or so it
seems. Any suggestions to improve this are welcome. By the way, it
really makes the Borges memory leaks stand out after an app's been on
for 20 minutes or so :-)
Also, some other ideas for dynamic development with Borges. I already
keep all my CSS in a separate file that gets reloaded on every page
request, so I can tweak the look as the app runs; all my i18n stuff
uses a 'dictionary file', so I can translate the app into another
language without stopping it, piece by piece... This is cool.
Vladimir Slepnev
More information about the Borges-users
mailing list