Class: Xavier::Observer Private

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

Overview

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

Observes an object for state mutations.

Instance Method Summary collapse

Constructor Details

#initialize(mutator = Mutator.new, states = States.new) ⇒ Observer

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.

Creates an instance of Observer.

Parameters:

  • mutator (Mutator) (defaults to: Mutator.new)

    Applies and unapplies state modifications.

  • states (States) (defaults to: States.new)

    States of objects under observation. Empty by default.



15
16
17
18
# File 'lib/xavier/observer.rb', line 15

def initialize(mutator = Mutator.new, states = States.new)
  @states = states
  @mutator = mutator
end

Instance Method Details

#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