lib/ably/modules/event_emitter.rb in ably-0.7.2 vs lib/ably/modules/event_emitter.rb in ably-0.7.4

- old
+ new

@@ -1,12 +1,16 @@ +require 'ably/modules/safe_yield' + module Ably module Modules # EventEmitter provides methods to attach to public events and trigger events on any class instance # # EventEmitter are typically used for public interfaces, and as such, may be overriden in # the classes to enforce `event` names match expected values. # + # @note This module requires that the method #logger is defined. + # # @example # class Example # include Modules::EventEmitter # end # @@ -14,10 +18,12 @@ # event_emitter.on(:signal) { |name| puts "Signal #{name} received" } # event_emitter.trigger :signal, "Test" # #=> "Signal Test received" # module EventEmitter + include Ably::Modules::SafeYield + module ClassMethods attr_reader :event_emitter_coerce_proc # Configure included EventEmitter # @@ -47,10 +53,19 @@ event_names.each do |event_name| callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block) end end + # Equivalent of {#on} but any exception raised in a block will bubble up and cause this client library to fail. + # This method should only be used internally by the client library. + # @api private + def unsafe_on(*event_names, &block) + event_names.each do |event_name| + callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, unsafe: true) + end + end + # On receiving an event maching the event_name, call the provided block only once and remove the registered callback # # @param [Array<String>] event_names event name # # @return [void] @@ -58,16 +73,29 @@ event_names.each do |event_name| callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, delete_once_run: true) end end + # Equivalent of {#once} but any exception raised in a block will bubble up and cause this client library to fail. + # This method should only be used internally by the client library. + # @api private + def unsafe_once(*event_names, &block) + event_names.each do |event_name| + callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, delete_once_run: true, unsafe: true) + end + end + # Trigger an event with event_name that will in turn call all matching callbacks setup with `on` def trigger(event_name, *args) callbacks[callbacks_event_coerced(event_name)]. clone. select do |proc_hash| - proc_hash[:trigger_proc].call(*args) + if proc_hash[:unsafe] + proc_hash[:trigger_proc].call *args + else + safe_yield proc_hash[:trigger_proc], *args + end end.each do |callback| callbacks[callbacks_event_coerced(event_name)].delete callback end end @@ -106,10 +134,11 @@ { trigger_proc: Proc.new do |*args| block.call *args true if options[:delete_once_run] end, - block: block + block: block, + unsafe: options[:unsafe] } end def callbacks @callbacks ||= Hash.new { |hash, key| hash[key] = [] }