Method: Xavier::Observer#observe

Defined in:
lib/xavier/observer.rb

#observe(observable) { ... } ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Observes an object, yields a block and then reverts the observed object’s class and instance variables.

Examples:

Observing a class

class EvilSingleton
  @@mutated = false
  @mutated = false

  def self.mutate
    @@mutated = true
    @mutated = true
  end

  def self.mutated?
    @@mutated && @mutated
  end
end

Xavier.observe(EvilSingleton) do
  EvilSingleton.mutated? # => false
  EvilSingleton.mutate
  EvilSingleton.mutated? # => true
end

EvilSingleton.mutated? # => false

Observing an instance

class InstanceSingleton
  def initialize
    @mutated = false
  end

  def mutate
    @mutated = true
  end

  def mutated?
    @mutated
  end
end

evil_singleton = InstanceSingleton.new

Xavier.observe(evil_singleton) do
  evil_singleton.mutated? # => false
  evil_singleton.mutate
  evil_singleton.mutated? # => true
end

evil_singleton.mutated? # => false

Parameters:

  • observable

    The object whose state should be observed. It can be a class or an instance.

Yields:

  • The block to be executed before the observable’s state is reverted.

Returns:

  • (Integer)

    The object_id of the observable.

Raises:

  • (AlreadyObserved)

    When attempting to observe the same object twice before the block returning.



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/xavier/observer.rb', line 79

def observe(observable)
  raise ArgumentError, 'This method expects a block. Without a block it is useless.' unless block_given?
  raise AlreadyObserved, 'Objects can only be observed once per block.' if being_observed?(observable)

  strategies = mutator.mutation_strategies_for(observable)
  original_state = mutator.create_state_from(observable, strategies: strategies)
  save_state(original_state)

  yield

  mutator.apply_state(from: original_state, to: observable, strategies: strategies)
  delete_state(original_state)
end