Class: EnumerableObserver::Observer

Inherits:
Object
  • Object
show all
Defined in:
lib/enumerable_observer.rb

Constant Summary collapse

UNSAFE_METHODS =
%i{
  instance_variable_set
  remove_instance_variable
  define_singleton_method
  instance_eval
  instance_exec
}
SAFE_METHODS =
(%i{each} + Object.instance_methods) - UNSAFE_METHODS

Instance Method Summary collapse

Constructor Details

#initialize(obj) ⇒ Observer

Returns a new instance of Observer.



34
35
36
37
38
39
40
# File 'lib/enumerable_observer.rb', line 34

def initialize(obj)
  @object        = obj
  observers_proc =
    observer_method_proc(obj.respond_to?(:observers) ? obj.observers : [])
  obj.define_singleton_method(:observers, &observers_proc)
  obj.extend mod
end

Instance Method Details

#added(&block) ⇒ Object



73
74
75
76
# File 'lib/enumerable_observer.rb', line 73

def added(&block)
  blocks[:add] = block
  self
end

#modObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/enumerable_observer.rb', line 42

def mod
  @mod ||= begin
    obj    = @object
    blocks = self.blocks
    Module.new do
      (obj.methods - SAFE_METHODS).each do |meth|
        old = obj.method(meth).unbind.bind(obj)
        define_method(meth) do |*args, &block|
          before  = each.to_a
          val     = old.call(*args, &block)
          after   = each.to_a
          added   = after - before
          removed = before - after
          blocks[:add].unstrict.call(added) unless added.empty? || !blocks[:add]
          blocks[:remove].unstrict.call(removed) unless removed.empty? || !blocks[:remove]
          val
        end
      end
    end
  end
end

#removed(&block) ⇒ Object



78
79
80
81
# File 'lib/enumerable_observer.rb', line 78

def removed(&block)
  blocks[:remove] = block
  self
end

#unobserveObject



64
65
66
67
68
69
70
71
# File 'lib/enumerable_observer.rb', line 64

def unobserve
  mod.instance_methods.each do |method_name|
    mod.module_eval do
      remove_method method_name
    end
  end
  @unobserved = true
end