Module: Test::Unit::Util::Observable

Included in:
TestResult, Test::Unit::UI::TestRunnerMediator
Defined in:
lib/test/unit/util/observable.rb,
lib/test/unit/util/observable.rb

Overview

This is a utility class that allows anything mixing it in to notify a set of listeners about interesting events.

Constant Summary collapse

NOTHING =

We use this for defaults since nil might mean something

"NOTHING/#{__id__}"

Instance Method Summary collapse

Instance Method Details

#add_listener(channel_name, listener_key = NOTHING, &listener) ⇒ Object

Adds the passed proc as a listener on the channel indicated by channel_name. listener_key is used to remove the listener later; if none is specified, the proc itself is used.

Whatever is used as the listener_key is returned, making it very easy to use the proc itself as the listener_key:

listener = add_listener("Channel") { ... }
remove_listener("Channel", listener)


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/test/unit/util/observable.rb', line 25

def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value
  unless(block_given?)
    raise ArgumentError.new("No callback was passed as a listener")
  end
      
  key = listener_key
  if (listener_key == NOTHING)
    listener_key = listener
    key = ProcWrapper.new(listener)
  end
      
  channels[channel_name] ||= {}
  channels[channel_name][key] = listener
  return listener_key
end

#notify_listeners(channel_name, *arguments) ⇒ Object

Calls all the procs registered on the channel indicated by channel_name. If value is specified, it is passed in to the procs, otherwise they are called with no arguments.

Perhaps this should be private? Would it ever make sense for an external class to call this method directly?



68
69
70
71
72
73
74
# File 'lib/test/unit/util/observable.rb', line 68

def notify_listeners(channel_name, *arguments)
  channel = channels[channel_name]
  return 0 unless (channel)
  listeners = channel.values
  listeners.each { |listener| listener.call(*arguments) }
  return listeners.size
end

#remove_listener(channel_name, listener_key) ⇒ Object

Removes the listener indicated by listener_key from the channel indicated by channel_name. Returns the registered proc, or nil if none was found.



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/test/unit/util/observable.rb', line 45

def remove_listener(channel_name, listener_key)
  channel = channels[channel_name]
  return nil unless (channel)
  key = listener_key
  if (listener_key.instance_of?(Proc))
    key = ProcWrapper.new(listener_key)
  end
  if (channel.has_key?(key))
    return channel.delete(key)
  end
  return nil
end