2010-03-28 3 views
2

Je développe (bien, essayant au moins) un cadre de jeu pour la bibliothèque Ruby Gosu. J'ai fait un système d'événement de base où chaque Blocks :: Event a une liste de gestionnaires et quand l'événement est déclenché les méthodes sont appelées. En ce moment la façon de mettre en œuvre un événement est la suivante:Définir la variable d'instance en dehors de la méthode Defenition (ruby)

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 

Mais cette méthode de la mise en œuvre des événements semble assez longue, ma question est, comment puis-je faire d'une manière de sorte que lorsque l'on veut un événement dans une classe , ils peuvent juste faire ceci

class TestClass 

    event :on_close 

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

Merci d'avance, ell.

Répondre

1

Je ne comprends pas tout à fait ce que vous essayez de faire, mais vous pouvez éviter d'utiliser la méthode initialize de la manière suivante:

class TestClass 

    event :on_close 

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

L'idiome ||= vous permet d'initialiser les variables d'instance paresseusement en rubis.

1

Ce qui suit est tout à fait non testé, mais peut-être il vous permet de démarrer:

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

Edité selon le commentaire de banister.

+0

C'est en effet. Comme je l'ai dit, juste un tir rapide non testé, merci de le signaler :-) –

+0

Il semble fonctionner sur une classe qui ne nécessite aucune logique d'initialisation et cela signifie que je devrais faire un alias, ce qui pour moi devient un peu anti-rubis, en mettant plus de travail que nécessaire, donc je m'en tiendrai à l'ajouter manuellement, peut-être que je trouverai un moyen mais pour l'instant c'est jusqu'à ce que nous nous retrouvions :) – Ell