Event handling in Ruby
i want to be able to do event handling with ruby. I know there is no native开发者_如何转开发 way to do this, but i found a solution here in stackoverflow:
class EventBase
def initialize
@listeners = Hash.new
end
def listen_event(name, *func, &p)
if p
(@listeners[name] ||= Array.new) << p
else
(@listeners[name] ||= Array.new) << func[0]
end
end
def ignore_event(name, func)
return if !@listeners.has_key?(name)
@listeners[name].delete_if { |o| o == func }
end
def trigger_event(name, *args)
return if !@listeners.has_key?(name)
@listeners[name].each { |f| f.call(*args) }
end
end
class MyClass < EventBase
def raise_event1(*args)
trigger_event(:event1, *args)
end
def raise_event2(*args)
trigger_event(:event2, *args)
end
end
class TestListener
def initialize(source)
source.listen_event(:event1, method(:event1_arrival))
source.listen_event(:event2) do |*a|
puts "event 2 arrival, args #{a}"
end
end
def event1_arrival(*a)
puts "Event 1 arrived, args #{a}"
end
end
The problem is this: 1- It seems when you add a method to the listen array it executes right away 2- When the event triggers, it throws a NoMethodError: undefined method call for nil:NilClass
I am new to ruby so i dont understand the code completly, i feel its missing some pieces of code lol... (mostly because i dont know all ruby syntax) thanks
Some questions: - What means &p ? - What is ||=? - what means <
I think you may be trying to reinvent the wheel here. I would recommend using Observable
instead. It's in the standard library, just require "observer"
and include
the Observable
module into your class.
If you want to do event handling in a small Ruby script (ie: NOT a web application), then I recommend using the Unobservable gem (as in: it's NOT the Observable gem, har har har). You can find some basic details / links about the gem here:
https://briandamaged.org/blog/?p=1074
https://briandamaged.org/blog/?p=1161
This gem makes it easy to define multiple events in a single object. For example:
require 'unobservable'
class Button
include Unobservable::Support
attr_event :clicked
attr_event :double_clicked
def click(x, y)
raise_event(:clicked, x, y)
end
def double_click(x, y)
raise_event(:double_clicked, x, y)
end
end
button = Button.new
button.clicked.register {|x, y| puts "You just clicked: #{x} #{y}"}
button.click(2, 3)
Lol, ok i solved the problem... i wasnt calling listen_event correctly...
it should be listen_event(:indexChanged,method(:sayIndex)) not listen_event(:indexChanged,sayIndex(:index))
still learnin the ropes on ruby lol
精彩评论