Class: Onceler::Recorder

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent) ⇒ Recorder

Returns a new instance of Recorder.



7
8
9
10
11
# File 'lib/onceler/recorder.rb', line 7

def initialize(parent)
  @parent = parent
  @recordings = []
  @named_recordings = []
end

Instance Attribute Details

#helper_proxyObject

Returns the value of attribute helper_proxy.



5
6
7
# File 'lib/onceler/recorder.rb', line 5

def helper_proxy
  @helper_proxy
end

#tapeObject

Returns the value of attribute tape.



5
6
7
# File 'lib/onceler/recorder.rb', line 5

def tape
  @tape
end

Instance Method Details

#<<(block) ⇒ Object



13
14
15
# File 'lib/onceler/recorder.rb', line 13

def <<(block)
  @recordings << Recording.new(block)
end

#[](name) ⇒ Object



22
23
24
# File 'lib/onceler/recorder.rb', line 22

def [](name)
  @retvals[name]
end

#[]=(name, block) ⇒ Object



17
18
19
20
# File 'lib/onceler/recorder.rb', line 17

def []=(name, block)
  @named_recordings << name
  @recordings << NamedRecording.new(block, name)
end

#helper_methodsObject



55
56
57
# File 'lib/onceler/recorder.rb', line 55

def helper_methods
  @helper_methods ||= {}
end

#mixinsObject



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/onceler/recorder.rb', line 59

def mixins
  mixins = (@parent ? @parent.mixins : Onceler.configuration.modules).dup
  if methods = @helper_methods
    mixin = Module.new do
      methods.each do |key, method|
        define_method(key, &method)
      end
    end
    mixins.push mixin
  end
  mixins
end

#proxy_recordable_methods!Object



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/onceler/recorder.rb', line 41

def proxy_recordable_methods!
  # the proxy is used to run non-recordable methods that may be called
  # by ones are recording. since the former could in turn call more of
  # the latter, we need to proxy the other way too
  return unless helper_proxy
  methods = @named_recordings
  reverse_proxy = @tape
  helper_proxy.instance_eval do
    methods.each do |method|
      define_singleton_method(method) { reverse_proxy.send(method) }
    end
  end
end

#reconsitute_data!Object



72
73
74
75
76
77
# File 'lib/onceler/recorder.rb', line 72

def reconsitute_data!
  @ivars, @retvals = Marshal.load(@data)
  identity_map = {}
  reidentify!(@ivars, identity_map)
  reidentify!(@retvals, identity_map)
end

#record!Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/onceler/recorder.rb', line 26

def record!
  @tape = @parent ? @parent.tape.copy(mixins) : BlankTape.new(mixins)
  proxy_recordable_methods!

  # we don't know the order named recordings will be called (or if
  # they'll call each other), so prep everything first
  @recordings.each do |recording|
    recording.prepare_medium!(@tape)
  end
  @recordings.each do |recording|
    recording.record_onto!(@tape)
  end
  @data = Marshal.dump(@tape.__data)
end

#reidentify!(hash, identity_map) ⇒ Object



79
80
81
82
83
84
85
86
87
# File 'lib/onceler/recorder.rb', line 79

def reidentify!(hash, identity_map)
  hash.each do |key, value|
    if identity_map.key?(value)
      hash[key] = identity_map[value]
    else
      identity_map[value] = value
    end
  end
end

#replay_into!(instance) ⇒ Object



89
90
91
92
93
94
# File 'lib/onceler/recorder.rb', line 89

def replay_into!(instance)
  reconsitute_data!
  @ivars.each do |key, value|
    instance.instance_variable_set(key, value)
  end
end