在方法定义之外定义实例变量(ruby)

时间:2010-03-28 16:35:42

标签: ruby dynamic methods metaprogramming

我正在开发(好吧,至少尝试)Ruby Gosu库的游戏框架。我已经建立了一个基本的事件系统,每个Blocks :: Event都有一个处理程序列表,当事件被触发时,方法被调用。目前实现事件的方式如下:

class TestClass

    attr_accessor :on_close

    def initialize
        @on_close = Blocks::Event.new
    end

    def close
        @on_close.fire(self, Blocks::OnCloseArgs.new)
    end
end

但是这种实现事件的方法看起来相当长,我的问题是,我怎么能这样做,以便当一个人想要一个类中的事件时,他们就可以这样做

class TestClass

    event :on_close

    def close
        @on_close.fire(self, Blocks::OnCloseArgs.new)
    end
end

先谢谢,等等。

2 个答案:

答案 0 :(得分:2)

以下内容完全未经测试,但可能会让您入门:

class Blocks
  class Event
    # dummy 
  end
end

class Class
  def event(*args)
    define_method :initialize do
      args.each { |a| instance_variable_set("@#{a}", Blocks::Event.new) }
    end
  end
end

class TestClass
    event :on_close

    def close
      #@on_close.fire(self, Blocks::OnCloseArgs.new)
      p @on_close
    end
end

test = TestClass.new
test.close
# => #<Blocks::Event:0x10059a0a0>
p test.instance_variables
# => ["@on_close"]

根据班尼斯特的评论编辑。

答案 1 :(得分:1)

我并不完全明白您要做的是什么,但您可以通过以下方式避免使用initialize方法:

class TestClass

    event :on_close

    def close
        @on_close ||= Blocks::Event.new
        @on_close.fire(self, Blocks::OnCloseArgs.new)
    end
end

||=成语允许您在ruby中懒惰地初始化实例变量。