Tapio K. wrote:
scripts get inctance_evaled, to avoid pollution of Object). Overriding
method_missing probably solves this nicely.
Ruby is a great thing (although it lacks multiple dispatching and
multiple inheritance)!
You could evaluate the whole config file inside of a scope (for example,
a module), and then pull objects out of this module as you need them.
There’s one way to do this in:
http://redshift.sourceforge.net/script/
You can make methods like “archive” and “feature” available by
subclassing the Script module and defining them as module methods.
$ cat config-script.rb
name = “gcc”
version = “4.1.1”
title = “GNU Compiler Collection”
description = “…”
archive {
localname “#{name}-#{version}.tar.bz2”
#originalname “#{name}-#{version}.tar.gz”
#baseurl “ftp://ftp.gnu.org/gnu/gcc/#{version}/”
#baseurl “ftp.mirror.site/gnu/gcc/#{version}/”
#convert “gz-bz2”
}
Optional components
feature(“gfortran”) {
title “Fortran compiler”
#depend “gmp”
}
$ cat parser.rb
require ‘script’
class Archive
def localname n; @localname = n; end
# etc.
end
class Feature
def initialize arg; @arg = arg; end
def title t; @title = t; end
# etc.
end
class ConfigScript < Script
def archive(&bl)
@archive = Archive.new
@archive.instance_eval(&bl)
end
def feature(arg, &bl)
@feature = Feature.new(arg)
@feature.instance_eval(&bl)
end
def inspect
super + [@archive, @feature].inspect
end
end
config_script = ConfigScript.load(“config-script.rb”)
p config_script
$ ruby parser.rb
#ConfigScript:/home/vjoel/tmp/scr/config-script.rb[#<Archive:0xb7cb5ff4
@localname=“gcc-4.1.1.tar.bz2”>, #<Feature:0xb7cb5f7c @arg=“gfortran”,
@title=“Fortran compiler”>]
This doesn’t really try to solve your parsing questions. It’s just an
example of how to eval the script inside a scope and not let that leak
out into the global scope.
It might be less work if you can accept a config file of the form:
$ cat config-script2.rb
NAME = “gcc”
VERSION = “4.1.1”
TITLE = “GNU Compiler Collection”
DESCRIPTION = “…”
ARCHIVE = {
:localname => “#{NAME}-#{VERSION}.tar.bz2”
}
module Features
GFORTRAN = {
:title => “Fortran compiler”
}
end
Then the parser is just:
$ cat parser2.rb
require ‘script’
config_script = Script.load(“config-script2.rb”)
p config_script
p config_script::NAME
p config_script::ARCHIVE
config_script::Features.constants.each do |c|
p(c=>config_script::Features.const_get(c))
end
$ ruby parser2.rb
#Script:/home/vjoel/tmp/scr/config-script2.rb
“gcc”
{:localname=>“gcc-4.1.1.tar.bz2”}
{“GFORTRAN”=>{:title=>“Fortran compiler”}}
Anyway, I hope this suggests some of the possibilities for scoping your
DSL. There are lots of possibilities for sweetening up the syntax.