once-ler 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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