Ruby Metaprogramming Ruby 中的 An Event Better DSL 写得太纠结了

hhuai · 2014年01月24日 · 最后由 windwiny 回复于 2014年01月26日 · 2657 次阅读

不知道是不是作者学 js 太入神,完全是 js 搞法, 为了隐藏一个全局变量,却搞出 N 多的全局方法出来了。

lambda {
  setups = []
  events = {}
  
  Kernel.send :define_method, :event do |name, &block| 
    events[name] = block
  end

  Kernel.send :define_method, :setup do |&block|
    setups << block
  end

  Kernel.send :define_method, :each_event do |&block|
    events.each_pair do |name, event|
    block.call name, event
  end end

  Kernel.send :define_method, :each_setup do |&block|
    setups.each do |setup|
    block.call setup
  end end

}.call

Dir.glob('*events.rb').each do |file| load file
each_event do |name, event|
  env = Object.new each_setup do |setup|
    env.instance_eval &setup
  end
  puts "ALERT: #{name}" if env.instance_eval &event end
end

我稍微改了一下,看着顺眼多了,缺点就是调试定不到文件。

Class.new do
  def event(name, &block)
    @events ||= {}
    @events[name] = block
  end

  def setup(&block)
    @setups ||= []
    @setups << block
  end

  def run
    @events.each do |k,v|
      o = Object.new
      @setups.each do |setup|
        o.instance_eval &setup
      end
      puts "ALERT: #{k}" if o.instance_eval &v
    end
  end
end.new.instance_eval {
  instance_eval File.open("./test_event.rb").read
  run
}

这代码不是半成品吗

需要 登录 后方可回复, 如果你还没有账号请 注册新账号