1
- class State
1
+ class StateWrapper
2
2
class << self
3
3
def inherited ( subclass )
4
- return unless self == State
5
- @shared_proxy = subclass
6
- @instance_proxy = Class . new ( @shared_proxy )
7
- @class_proxy = Class . new ( @shared_proxy )
8
- @shared_mutator_proxy = Class . new ( Mutator )
9
- @instance_mutator_proxy = Class . new ( @shared_mutator_proxy )
10
- @class_mutator_proxy = Class . new ( @shared_mutator_proxy )
4
+ subclass . add_class_instance_vars if self == StateWrapper
11
5
end
12
6
13
- attr_reader :instance_proxy
14
- attr_reader :class_proxy
15
- attr_reader :instance_mutator_proxy
16
- attr_reader :class_mutator_proxy
7
+ def add_class_instance_vars
8
+ @shared_state_wrapper = subclass
9
+ @instance_state_wrapper = Class . new ( @shared_wrapper )
10
+ @class_state_wrapper = Class . new ( @shared_wrapper )
11
+ @shared_mutator_wrapper = Class . new ( Mutator )
12
+ @instance_mutator_wrapper = Class . new ( @shared_mutator_wrapper )
13
+ @class_mutator_wrapper = Class . new ( @shared_mutator_wrapper )
14
+ @wrappers = [
15
+ @instance_state_wrapper , @instance_mutator_wrapper ,
16
+ @class_state_wrapper , @class_mutator_wrapper
17
+ ]
17
18
18
- def define_accessor ( *args , &block )
19
- # process args into name, opts, and init_value
20
- # call add_error_methods / add_method / remove_method
21
19
end
22
20
23
- def add_error_methods name
24
- [ @shared_proxy , @shared_mutator_proxy ] . each do |klass |
25
- klass . define_method ( name ) do |*args , &block |
21
+ attr_reader :instance_state_wrapper
22
+ attr_reader :class_state_wrapper
23
+ attr_reader :instance_mutator_wrapper
24
+ attr_reader :class_mutator_wrapper
25
+ attr_reader :wrappers
26
+
27
+ def define_state_methods ( klass , *args , &block )
28
+ return self if args . empty?
29
+ opts = process_args ( klass , *args )
30
+ add_readers ( klass , opts )
31
+ add_error_methods ( opts )
32
+ add_methods ( opts )
33
+ remove_methods ( opts )
34
+ end
35
+
36
+ def process_args ( klass , *args , &block )
37
+ # returns *args processed into opts, will add name key, and will update initialize key
38
+ # and the scope
39
+ # so that initialize is always a proc or nil... that part if fun
40
+ # (state_name: some_value...) ==+> (name: :state_name, initialize: -> () { some_value.dup })
41
+ # (state_name, ... initialize: :meth_name) ===> (name: :state_name, initialize: klass-depends-on-scope.method(:meth_name))
42
+ # (state_name, ... initialize: someproc) ===> (name: :state_name, initialize: someproc)
43
+ # (state_name, ... &block) ===> (name: :state_name, initialize: block)
44
+ # (state_name ....) ===> (name: :state_name, ... no initialize key ...)
45
+ end
46
+
47
+ def add_readers ( klass , opts )
48
+ if opts [ :scope ] == :instance
49
+ klass . define_method ( opts [ :reader ] ) { state . send ( opts [ :name ] ) } ## we could get it directly from React::State...
50
+ else
51
+ klass . singleton_class . define_method ( ...) I think? ??
52
+ end unless opts [ :reader ]
53
+ end
54
+
55
+ def add_error_methods ( opts )
56
+ [ @shared_state_wrapper , @shared_mutator_wrapper ] . each do |klass |
57
+ klass . define_method ( opts [ :name ] ) do |*args , &block |
26
58
"illegal boss"
27
59
end
28
- end
60
+ end unless opts [ :scope ] == :shared
61
+ end
62
+
63
+ def add_methods ( opts )
64
+ instance_variable_get ( "@#{ opts [ :scope ] } _state_wrapper" ) . add_method opts [ :name ] , opts [ :initialize ] , opts [ :reader ]
65
+ instance_variable_get ( "@#{ opts [ :scope ] } _mutator_wrapper" ) . add_method opts [ :name ]
29
66
end
30
67
31
- def add_method ( name , opts = { } , init_value , &block )
32
- define_method ( name ) do ...
68
+ def remove_methods ( opts )
69
+ wrappers . each { |wrapper | wrapper . remove_method opts [ :name ] } if opts [ :scope ] == :shared
70
+ end
71
+
72
+ def add_method ( klass , opts )
73
+ # define the method
74
+ define_method ( opts [ :name ] ) do ...
33
75
end
76
+
77
+ return unless opts [ :initializer ]
34
78
end
35
79
36
80
def default_scope
37
- self == @instance_proxy ? :instance : :class
81
+ # remember:
82
+ # class Store
83
+ # state :foo # this is calling the state wrapper but defining instance variables
84
+ # class << self
85
+ # state :foo # this is calling the shared state wrapper but defining class variables
86
+ # end
87
+ # end
88
+ self == @class_state_wrapper ? :instance : :class
38
89
end
39
90
end
40
91
@@ -45,7 +96,7 @@ def method_missing(name, *args, &block)
45
96
46
97
end
47
98
48
- class Mutator
99
+ class MutatorWrapper
49
100
def method_missing ( name , *args , &block )
50
101
self . class . add_method name
51
102
self . send ( name , *args , &block )
@@ -60,28 +111,28 @@ def define_method(name) do ...
60
111
class HyperStore ::Base
61
112
def self . inherited ( child )
62
113
child . singleton_class . define_singleton_method ( :state ) do |*args , &block |
63
- @state ||= Class . new ( State ) . new
64
- @state . class . define_accessor ( *args , &block )
65
- @state
114
+ # the singleton_class_method is only called either to define states
115
+ # or for the class and instance methods to get the wrapper so we just
116
+ # save the wrapper. We don't need an instance here.
117
+ @state_wrapper ||= Class . new ( StateWrapper )
118
+ @state_wrapper . define_state_methods ( child , *args , &block ) # i think this is self here
66
119
end
67
120
end
68
121
69
122
def self . state ( *args , &block )
70
- @state ||= singleton_class . state . class . class_proxy . new
71
- singleton_class . state . class . class_proxy . process_args ( *args , &block )
72
- @state
123
+ singleton_class . state . class_state_wrapper . define_state_methods ( child , *args , &block )
124
+ @state ||= singleton_class . state . class_state_wrapper . new
73
125
end
74
126
75
127
def self . mutate
76
- @mutate ||= singleton_class . state . class . class_mutator_proxy . new
128
+ @mutate ||= singleton_class . state . class_mutator_wrapper . new
77
129
end
78
130
79
131
def state
80
- @state ||= self . class . singleton_class . state . class . instance_proxy . new
132
+ @state ||= self . class . singleton_class . instance_state_wrapper . new
81
133
end
82
134
83
135
def mutate
84
- @mutate ||= self . class . singleton_class . state . class . instance_mutator_proxy . new
136
+ @mutate ||= self . class . singleton_class . instance_mutator_wrapper . new
85
137
end
86
-
87
138
end
0 commit comments