[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