Ell
Ell

Reputation: 4376

Define Instance Variable Outside of Method Defenition (ruby)

I am developing (well, trying to at least) a Game framework for the Ruby Gosu library. I have made a basic event system wherebye each Blocks::Event has a list of handlers and when the event is fired the methods are called. At the moment the way to implement an event is as follows:

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

But this method of implementing events seems rather long, my question is, how can I make a way so that when one wants an event in a class, they can just do this

class TestClass

    event :on_close

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

Thanks in advance, ell.

Upvotes: 2

Views: 944

Answers (2)

Michael Kohl
Michael Kohl

Reputation: 66867

The following is completely untested, but maybe it gets you started:

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"]

Edited according to banister's comment.

Upvotes: 2

horseyguy
horseyguy

Reputation: 29915

I don't entirely understand what you're trying to do, but you can avoid using the initialize method in the following way:

class TestClass

    event :on_close

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

The ||= idiom lets you lazily initialize instance variables in ruby.

Upvotes: 1

Related Questions