once-ler 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -60,6 +60,12 @@ RSpec.configure do |c|
60
60
  end
61
61
  ```
62
62
 
63
+ ## How much of a speedup will I get?
64
+
65
+ YMMV, it depends on how bad your `let`s/`before`s are. For example,
66
+ adding once-ler to a subset of [canvas-lms](https://github.com/instructure/canvas-lms)'s
67
+ model specs (spec/models/a*) **reduces their runtime by 40%**.
68
+
63
69
  ## How does it work?
64
70
 
65
71
  Any `before(:once)`/`let_once` blocks will run just once for the current
@@ -76,30 +76,16 @@ module Onceler
76
76
 
77
77
  def create_onceler!
78
78
  add_onceler_hooks!
79
- Recorder.new(parent_onceler)
79
+ Recorder.new(self)
80
80
  end
81
81
 
82
- # make sure we have access to subsequently added methods when
83
- # recording (not just `lets'). note that this really only works
84
- # for truly functional methods with no external dependencies. e.g.
85
- # methods that add stubs or set instance variables will not work
86
- # while recording
87
- def method_added(method_name)
88
- return if method_name == @current_let_once
89
- return if !@onceler
90
- proxy = onceler.helper_proxy ||= new
91
- onceler.helper_methods[method_name] ||= Proc.new do |*args|
92
- proxy.send method_name, *args
93
- end
94
- end
95
-
96
- private
97
-
98
82
  def parent_onceler
99
83
  return unless superclass.respond_to?(:onceler)
100
84
  superclass.onceler
101
85
  end
102
86
 
87
+ private
88
+
103
89
  def add_onceler_hooks!
104
90
  before(:all) do |group|
105
91
  Onceler.configuration.run_callbacks(:record, :before)
@@ -8,14 +8,6 @@ module Onceler
8
8
  end
9
9
 
10
10
  class Configuration
11
- def modules
12
- @modules ||= []
13
- end
14
-
15
- def include(mod)
16
- modules << mod
17
- end
18
-
19
11
  def before(scope, &block)
20
12
  callbacks[scope][:before] << block
21
13
  end
@@ -1,9 +1,11 @@
1
1
  module Onceler
2
- class BlankTape
3
- def initialize(modules)
4
- modules.each { |mod| extend mod }
5
- @__retvals = {}
6
- @__retvals_recorded = {} # we might override an inherited one, so we need to differentiate
2
+ module Recordable
3
+ def self.extended(instance)
4
+ instance.instance_eval do
5
+ @__retvals = {}
6
+ @__retvals_recorded = {} # we might override an inherited one, so we need to differentiate
7
+ @__ignore_ivars = instance_variables
8
+ end
7
9
  end
8
10
 
9
11
  def __prepare_recording(recording)
@@ -23,10 +25,12 @@ module Onceler
23
25
  end
24
26
 
25
27
  def __ivars
26
- ivars = instance_variables - [:@__retvals, :@__retvals_recorded]
28
+ ivars = instance_variables - @__ignore_ivars
27
29
  ivars.inject({}) do |hash, key|
28
- val = instance_variable_get(key)
29
- hash[key] = val
30
+ if key.to_s !~ /\A@__/
31
+ val = instance_variable_get(key)
32
+ hash[key] = val
33
+ end
30
34
  hash
31
35
  end
32
36
  end
@@ -35,12 +39,6 @@ module Onceler
35
39
  @__data ||= Marshal.dump([__ivars, @__retvals])
36
40
  end
37
41
 
38
- def copy(mixins)
39
- copy = self.class.new(mixins)
40
- copy.copy_from(self)
41
- copy
42
- end
43
-
44
42
  def copy_from(other)
45
43
  ivars, @__retvals = Marshal.load(other.__data)
46
44
  ivars.each do |key, value|
@@ -1,4 +1,4 @@
1
- require "onceler/blank_tape"
1
+ require "onceler/recordable"
2
2
  require "onceler/transactions"
3
3
 
4
4
  module Onceler
@@ -7,8 +7,8 @@ module Onceler
7
7
 
8
8
  attr_accessor :tape, :helper_proxy
9
9
 
10
- def initialize(parent)
11
- @parent = parent
10
+ def initialize(group_class)
11
+ @group_class = group_class
12
12
  @recordings = []
13
13
  @named_recordings = []
14
14
  end
@@ -28,8 +28,11 @@ module Onceler
28
28
 
29
29
  def record!
30
30
  begin_transactions!
31
- @tape = @parent ? @parent.tape.copy(mixins) : BlankTape.new(mixins)
32
- proxy_recordable_methods!
31
+ @tape = @group_class.new
32
+ @tape.send :extend, Recordable
33
+ if parent = @group_class.parent_onceler
34
+ @tape.copy_from(parent.tape)
35
+ end
33
36
 
34
37
  # we don't know the order named recordings will be called (or if
35
38
  # they'll call each other), so prep everything first
@@ -46,37 +49,6 @@ module Onceler
46
49
  rollback_transactions!
47
50
  end
48
51
 
49
- def proxy_recordable_methods!
50
- # the proxy is used to run non-recordable methods that may be called
51
- # by ones are recording. since the former could in turn call more of
52
- # the latter, we need to proxy the other way too
53
- return unless helper_proxy
54
- methods = @named_recordings
55
- reverse_proxy = @tape
56
- helper_proxy.instance_eval do
57
- methods.each do |method|
58
- define_singleton_method(method) { reverse_proxy.send(method) }
59
- end
60
- end
61
- end
62
-
63
- def helper_methods
64
- @helper_methods ||= {}
65
- end
66
-
67
- def mixins
68
- mixins = (@parent ? @parent.mixins : Onceler.configuration.modules).dup
69
- if methods = @helper_methods
70
- mixin = Module.new do
71
- methods.each do |key, method|
72
- define_method(key, &method)
73
- end
74
- end
75
- mixins.push mixin
76
- end
77
- mixins
78
- end
79
-
80
52
  def reconsitute_data!
81
53
  @ivars, @retvals = Marshal.load(@data)
82
54
  identity_map = {}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: once-ler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-28 00:00:00.000000000 Z
12
+ date: 2014-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -54,13 +54,13 @@ files:
54
54
  - lib/once-ler.rb
55
55
  - lib/onceler/ambitious_helpers.rb
56
56
  - lib/onceler/basic_helpers.rb
57
- - lib/onceler/blank_tape.rb
58
57
  - lib/onceler/configuration.rb
59
58
  - lib/onceler/extensions/active_record.rb
60
59
  - lib/onceler/extensions/active_record_3_0.rb
61
60
  - lib/onceler/extensions/active_record_3_2.rb
62
61
  - lib/onceler/extensions/active_record_4_0.rb
63
62
  - lib/onceler/extensions/active_record_4_1.rb
63
+ - lib/onceler/recordable.rb
64
64
  - lib/onceler/recorder.rb
65
65
  - lib/onceler/transactions/active_record_3.rb
66
66
  - lib/onceler/transactions/active_record_4.rb