What is the equivalent of .NET events in Ruby?
events, oop, ruby
Solution
Firstly, in Ruby there are no method signatures. The closest would be checking the function's arity. Duck typing requires thinking differently (slightly).
The Observable module is a start, but if you have a requirement to have multiple events from a single class it might not be enough.
This is a quick sketch. It supports methods and blocks. Modify as necessary to adapt for your code, threading approach, etc. For example, you could use method_missing to have the event name in the method name rather than having it as a parameter.
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
s = MyClass.new
l = TestListener.new(s)
s.raise_event1("here is event 1")
s.raise_event2("here is event 2")
Problem
The problem is very simple. An object needs to notify some events that might be of interest to observers. When I sat to validate a design that I cooked up now in Ruby just to validate it.. I find myself stumped as to how to implement the object events. In .Net this would be a one-liner.. .Net also does handler method signature verification,etc. e.g. ``` // Object with events public delegate void HandlerSignature(int a); public event HandlerSignature MyEvent; public event HandlerSignature AnotherCriticalEvent; // Client MyObject.MyEvent += new HandlerSignature(MyHandlerMethod); // MyHandlerMethod has same signature as delegate ``` Is there an EventDispatcher module or something that I am missing that I can strap on to a Ruby class ? Hoping for an answer that plays along with Ruby's principle of least surprise. An event would be the name of the event plus a queue of [observer, methodName] objects that need to be invoked when the event takes place.