class Concurrent::CopyOnWriteObserverSet

duplicated and replaced with a new one.
every time an observer is added or removed the whole internal data structure is
A thread safe observer set implemented using copy-on-write approach:

def add_observer(observer=nil, func=:update, &block)

Returns:
  • (Object) - the added observer

Parameters:
  • func (Symbol) -- the function to call on the observer during notification. Default is :update
  • observer (Object) -- the observer to add
def add_observer(observer=nil, func=:update, &block)
  if observer.nil? && block.nil?
    raise ArgumentError, 'should pass observer as a first argument or block'
  elsif observer && block
    raise ArgumentError.new('cannot provide both an observer and a block')
  end
  if block
    observer = block
    func = :call
  end
  @mutex.lock
  new_observers = @observers.dup
  new_observers[observer] = func
  @observers = new_observers
  @mutex.unlock
  observer
end

def clear_observers_and_return_old

def clear_observers_and_return_old
  @mutex.lock
  old_observers = @observers
  @observers = {}
  @mutex.unlock
  old_observers
end

def count_observers

Returns:
  • (Integer) - the observers count
def count_observers
  observers.count
end

def delete_observer(observer)

Returns:
  • (Object) - the deleted observer

Parameters:
  • observer (Object) -- the observer to remove
def delete_observer(observer)
  @mutex.lock
  new_observers = @observers.dup
  new_observers.delete(observer)
  @observers = new_observers
  @mutex.unlock
  observer
end

def delete_observers

Returns:
  • (CopyOnWriteObserverSet) - self
def delete_observers
  self.observers = {}
  self
end

def initialize

def initialize
  @mutex = Mutex.new
  @observers = {}
end

def notify_and_delete_observers(*args, &block)

Returns:
  • (CopyOnWriteObserverSet) - self

Parameters:
  • args (Object) -- arguments to be passed to each observer
def notify_and_delete_observers(*args, &block)
  old = clear_observers_and_return_old
  notify_to(old, *args, &block)
  self
end

def notify_observers(*args, &block)

Returns:
  • (CopyOnWriteObserverSet) - self

Parameters:
  • args (Object) -- arguments to be passed to each observer
def notify_observers(*args, &block)
  notify_to(observers, *args, &block)
  self
end

def notify_to(observers, *args)

def notify_to(observers, *args)
  raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty?
  observers.each do |observer, function|
    args = yield if block_given?
    observer.send(function, *args)
  end
end

def observers

def observers
  @mutex.lock
  o = @observers
  @mutex.unlock
  o
end

def observers=(new_set)

def observers=(new_set)
  @mutex.lock
  @observers = new_set
  @mutex.unlock
end