手抜き設定ファイル読み込みクラス

こんな風に読み込める。
ローカル変数に代入するだけ。

setting = EvalSetting.new <<-EOT
  directory = '~/script/ruby/'
  filename  = 'fixmp3.rb'
  @base_name = 'anekos'
  item1 = @base_name + '_moge'
  item2 = @base_name * 2 + '_hoge'
EOT

アクセスはこんなん。
引数が項目がない場合のデフォルト値になる。

p setting                               #=> {:item2=>"anekosanekos_hoge...}
p setting.directory '~/'                #=> "~/script/ruby/"
p setting.filename                      #=> "fixmp3.rb"
p setting.priority 6                    #=> 6
p setting.order                         #=> nil
p setting[:item1]                       #=> "anekos_moge"
p setting['item2']                      #=> "anekosanekos_hoge"
p setting['item3', 'anekos' + '_foge']  #=> "anekos_foge"

eval を使っていてアレだ。いまいちかも。

class EvalSetting
  @@get_new_binding = proc do
    binding
  end

  instance_methods.each {|it| undef_method it unless /\A__.+__\Z/ === it }

  def initialize (expr)
    @variables = {}
    @load = proc do
      |expr|
      eval(expr, b = @@get_new_binding.call)
      eval('local_variables', b).each do
        |vname|
        @variables[vname.to_sym] = eval(vname, b)
      end
      @variables
    end
    @load[expr]
  end

  def method_missing (name, *args)
    if @variables.include?(name)
      @variables[name]
    else
      args.first
    end
  end

  def [] (name, default = nil)
    name = name.to_sym
    @variables.include?(name) ? @variables[name] : default
  end

  def inspect
    @variables.inspect
  end
end


setting = EvalSetting.new <<-EOT
  directory = '~/script/ruby/'
  filename  = 'fixmp3.rb'
  @base_name = 'anekos'
  item1 = @base_name + '_moge'
  item2 = @base_name * 2 + '_hoge'
EOT

p setting                               #=> {:item2=>"anekosanekos_hoge...}
p setting.directory '~/'                #=> "~/script/ruby/"
p setting.filename                      #=> "fixmp3.rb"
p setting.priority 6                    #=> 6
p setting.order                         #=> nil
p setting[:item1]                       #=> "anekos_moge"
p setting['item2']                      #=> "anekosanekos_hoge"
p setting['item3', 'anekos' + '_foge']  #=> "anekos_foge"