RubyExt 0.1.0 → 0.1.1
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 +846 -0
- data/lib/RubyExt/Cache.rb +101 -0
- data/lib/RubyExt/Cache.res/multiple_version_with_args.txt +12 -0
- data/lib/RubyExt/Cache.res/multiple_version_without_args.txt +11 -0
- data/lib/RubyExt/Cache.res/single_version_with_args.txt +11 -0
- data/lib/RubyExt/Cache.res/single_version_without_args.txt +10 -0
- data/lib/RubyExt/ClassLoader.rb +142 -0
- data/lib/RubyExt/Debug.rb +24 -0
- data/lib/RubyExt/ExtraBlankSlate.rb +14 -0
- data/lib/RubyExt/ImportAll.rb +9 -0
- data/lib/RubyExt/Localization/Module.rb +12 -0
- data/lib/RubyExt/Localization/Object.rb +19 -0
- data/lib/RubyExt/Localization/require.rb +3 -0
- data/lib/RubyExt/Localization.rb +28 -0
- data/lib/RubyExt/Log.config.sample +57 -0
- data/lib/RubyExt/Log.rb +59 -0
- data/lib/RubyExt/OpenConstructor.rb +51 -0
- data/lib/RubyExt/Path.rb +91 -0
- data/lib/RubyExt/Resource/file_system_provider.rb +244 -0
- data/lib/RubyExt/StateMashine.rb +176 -0
- data/lib/RubyExt/Synchronizer.rb +29 -0
- data/lib/RubyExt/array.rb +24 -0
- data/lib/RubyExt/assert.rb +111 -0
- data/lib/RubyExt/class.rb +0 -0
- data/lib/RubyExt/debug.rb +71 -0
- data/lib/RubyExt/false_class.rb +5 -0
- data/lib/RubyExt/file.rb +23 -0
- data/lib/RubyExt/ideas.txt +17 -0
- data/lib/RubyExt/kernel.rb +61 -0
- data/lib/RubyExt/module.rb +102 -0
- data/lib/RubyExt/nil_class.rb +5 -0
- data/lib/RubyExt/object.rb +7 -0
- data/lib/RubyExt/observable.rb +25 -0
- data/lib/RubyExt/require.rb +56 -0
- data/lib/RubyExt/require_base.rb +35 -0
- data/lib/RubyExt/resource.rb +198 -0
- data/lib/RubyExt/string.rb +21 -0
- data/lib/RubyExt/symbol.rb +21 -0
- data/lib/RubyExt/true_class +0 -0
- data/lib/RubyExt/true_class.rb +5 -0
- data/rakefile +49 -0
- data/spec/RubyExt/ForClassLoader/ClassA.rb +4 -0
- data/spec/RubyExt/ForClassLoader/LoadCount.rb +1 -0
- data/spec/RubyExt/ForClassLoader/ModuleA/ClassB.rb +3 -0
- data/spec/RubyExt/ForClassLoader/ModuleA/ClassInsideAnonymousClass.rb +3 -0
- data/spec/RubyExt/ForClassLoader/ModuleA/InfinityLoop.rb +3 -0
- data/spec/RubyExt/ForClassLoader/ModuleA/ModuleB/ClassC.rb +3 -0
- data/spec/RubyExt/ForClassLoader/ModuleA/SameName/SomeClass.rb +2 -0
- data/spec/RubyExt/ForClassLoader/ModuleA/SameName.rb +2 -0
- data/spec/RubyExt/ForClassLoader/Scope/ScopeA1.rb +3 -0
- data/spec/RubyExt/ForClassLoader/Scope/ScopeB1.rb +5 -0
- data/spec/RubyExt/ForKernel/Raise2.rb +5 -0
- data/spec/RubyExt/ForKernel/RaiseWithoutSelf.rb +9 -0
- data/spec/RubyExt/ForLocalization/NS/A.rb +3 -0
- data/spec/RubyExt/ForLocalization/NS/A.ru.localization.yaml +2 -0
- data/spec/RubyExt/ForLocalization/NS/B.rb +22 -0
- data/spec/RubyExt/ForLocalization/NS/B.ru.localization.yaml +3 -0
- data/spec/RubyExt/ForLocalization/NS.ru.localization.yaml +2 -0
- data/spec/RubyExt/ForModule/NS1/A.data +1 -0
- data/spec/RubyExt/ForModule/NS1/A.rb +1 -0
- data/spec/RubyExt/ForModule/NS1/A2.rb +1 -0
- data/spec/RubyExt/ForModule/NS1/B.rb +2 -0
- data/spec/RubyExt/ForModule/NS1/B2.rb +1 -0
- data/spec/RubyExt/ForModule/NS1.data +1 -0
- data/spec/RubyExt/ForModule/NS2/A.data +1 -0
- data/spec/RubyExt/ForModule/NS2/A.rb +3 -0
- data/spec/RubyExt/ForModule/NS2/B.rb +3 -0
- data/spec/RubyExt/ForModule/NS2/M.data +1 -0
- data/spec/RubyExt/ForModule/NS2/M.rb +3 -0
- data/spec/RubyExt/ForResource/ChangedClass.rb +1 -0
- data/spec/RubyExt/ForResource/ChangedClass.res/Text.txt +0 -0
- data/spec/RubyExt/ForResource/ChangedClass.txt +0 -0
- data/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ChainTest.rb +3 -0
- data/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ChainTest.resource +1 -0
- data/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ClassExistOnlyInProviderA.rb +3 -0
- data/spec/RubyExt/ForResource/ProviderChaining/ProviderBBaseDir/ChainTest.rb +3 -0
- data/spec/RubyExt/ForResource/ProviderChaining/ProviderBBaseDir/ChainTest.resource +1 -0
- data/spec/RubyExt/ForResource/ResourceExtension.rb +1 -0
- data/spec/RubyExt/ForResource/ResourceExtension.res/Data.yaml +2 -0
- data/spec/RubyExt/ForResource/ResourceTest/Test.rb +1 -0
- data/spec/RubyExt/ForResource/ResourceTest/Test.res/Data.txt +1 -0
- data/spec/RubyExt/ForResource/ResourceTest/Test.res/txt +1 -0
- data/spec/array_spec.rb +27 -0
- data/spec/assert_spec.rb +18 -0
- data/spec/cache_spec.rb +95 -0
- data/spec/class_loader_spec.rb +94 -0
- data/spec/import_all_spec.rb +21 -0
- data/spec/kernel_spec.rb +38 -0
- data/spec/localization_spec.rb +49 -0
- data/spec/module_spec.rb +135 -0
- data/spec/object_spec.rb +8 -0
- data/spec/observable_spec.rb +44 -0
- data/spec/open_constructor_spec.rb +38 -0
- data/spec/path_spec.rb +169 -0
- data/spec/resource_spec.rb +135 -0
- data/spec/state_machine_spec.rb +201 -0
- data/spec/synchronizer_spec.rb +66 -0
- metadata +130 -10
- data/lib/RubyExt.rb +0 -1
- data/lib/hello_gem.rb +0 -5
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
module RubyExt
|
|
2
|
+
class FileSystemProvider
|
|
3
|
+
attr_accessor :directories
|
|
4
|
+
|
|
5
|
+
def initialize directories = lambda{[File.expand_path('.')]}
|
|
6
|
+
@directories, @files, @cache = directories, {}, {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def class_get class_name
|
|
10
|
+
path = real_class_path class_name
|
|
11
|
+
raise Resource::NotExist unless path
|
|
12
|
+
|
|
13
|
+
if File.directory? path
|
|
14
|
+
"module #{File.basename(path)}; end;"
|
|
15
|
+
else
|
|
16
|
+
File.read path
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# It updates existing class, if class doesn't exist it creates one in directory provided by filter
|
|
21
|
+
def class_set class_name, data, directory_for_class_file = nil
|
|
22
|
+
directory_for_class_file ||= Dir.getwd
|
|
23
|
+
directory_for_class_file = File.expand_path directory_for_class_file
|
|
24
|
+
unless @directories.call.include? directory_for_class_file
|
|
25
|
+
raise "Dirctories should include '#{directory_for_class_file}'!"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
path = real_class_path class_name
|
|
29
|
+
unless path
|
|
30
|
+
path = class_to_files(class_name).select{|f| f.include?(directory_for_class_file)}.first
|
|
31
|
+
dir = path.sub(/\w+\.rb/, "")
|
|
32
|
+
FileUtils.mkdir dir unless dir.empty? or File.exist? dir
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
length = File.write(path, data)
|
|
36
|
+
remember_file path
|
|
37
|
+
return length
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def class_exist? class_name
|
|
41
|
+
real_class_path(class_name) != nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def class_delete class_name
|
|
45
|
+
path = real_class_path class_name
|
|
46
|
+
File.delete path if path
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# def class_namespace_exist? namespace_name
|
|
50
|
+
# File.exist? class_to_basefile(namespace_name)
|
|
51
|
+
# end
|
|
52
|
+
|
|
53
|
+
# First search for "./class_name.resource_name" files
|
|
54
|
+
# And then search for "./class_name.res/resource_name" files
|
|
55
|
+
def resource_get class_name, resource_name
|
|
56
|
+
path = real_resource_path class_name, resource_name
|
|
57
|
+
raise Resource::NotExist unless path
|
|
58
|
+
|
|
59
|
+
File.read path
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def resource_delete class_name, resource_name
|
|
63
|
+
path = real_resource_path class_name, resource_name
|
|
64
|
+
File.delete path if path
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# It can only update existing resource, it can't create a new one
|
|
68
|
+
# First search for the same resource and owerwrites it
|
|
69
|
+
# If such resource doesn't exists writes to
|
|
70
|
+
# "./class_name.res/resource_name" file.
|
|
71
|
+
def resource_set class_name, resource_name, data
|
|
72
|
+
class_path = real_class_path class_name
|
|
73
|
+
raise Resource::NotExist unless class_path
|
|
74
|
+
|
|
75
|
+
path = real_resource_path class_name, resource_name
|
|
76
|
+
unless path
|
|
77
|
+
class_path = class_path.sub(/\.rb$/, "")
|
|
78
|
+
dir = "#{class_path}.res"
|
|
79
|
+
FileUtils.mkdir dir unless File.exist? dir
|
|
80
|
+
path = "#{dir}/#{resource_name}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
length = File.write path, data
|
|
84
|
+
remember_file path
|
|
85
|
+
return length
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def resource_exist? class_name, resource_name
|
|
89
|
+
class_path = real_class_path class_name
|
|
90
|
+
raise Resource::NotExist unless class_path
|
|
91
|
+
|
|
92
|
+
real_resource_path(class_name, resource_name) != nil
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def check_for_changed_files
|
|
97
|
+
changed = []
|
|
98
|
+
v = @directories.call
|
|
99
|
+
@directories.call.inject([]){|list, dir| list + Dir.glob("#{dir}/**/**")}.each do |path|
|
|
100
|
+
if file_changed? path
|
|
101
|
+
remember_file path
|
|
102
|
+
changed << file_changed(path)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
return changed
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def reset_changed_files
|
|
109
|
+
@files = {}
|
|
110
|
+
@directories.call.inject([]){|list, dir| list + Dir.glob("#{dir}/**/**")}.each do |path|
|
|
111
|
+
remember_file path
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Different Providers can use different class path interpretation.
|
|
116
|
+
# So we return virtual path only if this path really exist.
|
|
117
|
+
def class_to_virtual_file class_name
|
|
118
|
+
path = nil
|
|
119
|
+
if @cache.include? class_name
|
|
120
|
+
path = @cache[class_name]
|
|
121
|
+
else
|
|
122
|
+
path = real_class_path class_name
|
|
123
|
+
raise Resource::NotExist, "Class '#{class_name}' doesn't Exist!" unless path
|
|
124
|
+
|
|
125
|
+
@cache[class_name] = path
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
File.expand_path path
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# def class_to_virtual_path class_name
|
|
132
|
+
# result = nil
|
|
133
|
+
# if @cache.include? class_name
|
|
134
|
+
# result = @cache[class_name]
|
|
135
|
+
# else
|
|
136
|
+
# result = nil
|
|
137
|
+
# path = "#{base_dir}/#{class_name.gsub("::", "/")}"
|
|
138
|
+
# if File.exist? path
|
|
139
|
+
# result = path
|
|
140
|
+
# else
|
|
141
|
+
# path2 = "#{path}.rb"
|
|
142
|
+
# if File.exist? path2
|
|
143
|
+
# result = path
|
|
144
|
+
# else
|
|
145
|
+
# path3 = "#{path}.res"
|
|
146
|
+
# if File.exist? path3
|
|
147
|
+
# result = path
|
|
148
|
+
# end
|
|
149
|
+
# end
|
|
150
|
+
# end
|
|
151
|
+
# @cache[class_name] = result
|
|
152
|
+
# end
|
|
153
|
+
#
|
|
154
|
+
# if result
|
|
155
|
+
# return result
|
|
156
|
+
# else
|
|
157
|
+
# raise Resource::NotExist, "Class '#{class_name}' doesn't Exist!"
|
|
158
|
+
# end
|
|
159
|
+
# end
|
|
160
|
+
|
|
161
|
+
protected
|
|
162
|
+
def real_class_path class_name
|
|
163
|
+
path = class_to_files(class_name).find{|f| File.exist? f}
|
|
164
|
+
path = class_to_basefiles(class_name).find{|f| File.exist? f} unless path
|
|
165
|
+
return path
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def real_resource_path class_name, resource_name
|
|
169
|
+
file = class_to_basefiles(class_name).collect{|f| "#{f}.#{resource_name}"}.find{|f| File.exist? f}
|
|
170
|
+
file = class_to_basefiles(class_name).collect{|f| "#{f}.res/#{resource_name}"}.find{|f| File.exist? f} unless file
|
|
171
|
+
return file
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def class_to_files class_name
|
|
175
|
+
class_to_basefiles(class_name).collect{|name| "#{name}.rb"}
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Different Providers can use different class path interpretation.
|
|
179
|
+
# So we return virtual path only if this path really exist.
|
|
180
|
+
def class_to_basefiles class_name
|
|
181
|
+
relative = class_name.gsub("::", "/")
|
|
182
|
+
return @directories.call.collect{|dir| "#{dir}/#{relative}"}
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def remember_file path
|
|
186
|
+
@files[path] = File.mtime(path)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def file_changed? path
|
|
190
|
+
old_time = @files[path]
|
|
191
|
+
old_time == nil or old_time != File.mtime(path)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def file_changed path
|
|
195
|
+
begin
|
|
196
|
+
if path =~ /\.rb$/
|
|
197
|
+
path = path.sub(/\.rb$/, "")
|
|
198
|
+
class_name = path_to_class(path)
|
|
199
|
+
|
|
200
|
+
# ClassLoader.reload_class()
|
|
201
|
+
klass = eval class_name, TOPLEVEL_BINDING, __FILE__, __LINE__
|
|
202
|
+
@cache.delete class_name
|
|
203
|
+
return :class, klass, nil
|
|
204
|
+
else
|
|
205
|
+
if path =~ /\.res/
|
|
206
|
+
class_path = path.sub(/\.res.+/, "")
|
|
207
|
+
resource_name = path.sub("#{class_path}.res/", "")
|
|
208
|
+
class_name = path_to_class class_path
|
|
209
|
+
else
|
|
210
|
+
resource_name = path.sub(/.+\./, "")
|
|
211
|
+
class_name = path_to_class path.sub(/\.#{resource_name}$/, "")
|
|
212
|
+
end
|
|
213
|
+
klass = eval class_name, TOPLEVEL_BINDING, __FILE__, __LINE__
|
|
214
|
+
return :resource, klass, resource_name
|
|
215
|
+
end
|
|
216
|
+
rescue Exception => e
|
|
217
|
+
warn "Can't reload file '#{path}' #{e.message}!"
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def path_to_class path
|
|
222
|
+
base_dir = @directories.call.select{|f| path.include? f}.max{|a, b| a.size <=> b.size}
|
|
223
|
+
path.gsub(/^#{base_dir}\//, "").gsub("/", "::")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Doesn't make Sense for Virtual Resource System
|
|
227
|
+
# def resource_path class_name, resource_name
|
|
228
|
+
# @monitor.synchronize do
|
|
229
|
+
# path = "#{class_to_path(class_name)}.#{resource_name}"
|
|
230
|
+
# if File.exist? path
|
|
231
|
+
# return path
|
|
232
|
+
# else
|
|
233
|
+
# path = "#{class_to_path(class_name)}.res/#{resource_name}"
|
|
234
|
+
# if File.exist? path
|
|
235
|
+
# return path
|
|
236
|
+
# else
|
|
237
|
+
# nil
|
|
238
|
+
# end
|
|
239
|
+
# end
|
|
240
|
+
# end
|
|
241
|
+
# end
|
|
242
|
+
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
class StateMashine
|
|
2
|
+
attr_accessor :object
|
|
3
|
+
|
|
4
|
+
def initialize object = nil;
|
|
5
|
+
@object = object
|
|
6
|
+
@on_entry, @on_exit, @on_event = {}, {}, {}
|
|
7
|
+
|
|
8
|
+
@custom_states = {}
|
|
9
|
+
if self.class.custom_state_get
|
|
10
|
+
self.class.custom_state_get.each do |state, klass|
|
|
11
|
+
@custom_states[state] = klass.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
is = self.class.initial_state_get
|
|
16
|
+
raise_without_self "Initial State not defined!" unless is
|
|
17
|
+
fire_action @on_entry[is]
|
|
18
|
+
@state = is
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def on_entry state, method = nil, &b
|
|
22
|
+
if method or b
|
|
23
|
+
@on_entry[state] = method || b
|
|
24
|
+
else
|
|
25
|
+
@on_entry.delete state
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def on_event from, event, method = nil, &b
|
|
30
|
+
if method or b
|
|
31
|
+
@on_event[from + event] = method || b
|
|
32
|
+
else
|
|
33
|
+
@on_event.delete from + event
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def on_exit state, method = nil, &b
|
|
38
|
+
if method or b
|
|
39
|
+
@on_exit[state] = method || b
|
|
40
|
+
else
|
|
41
|
+
@on_exit.delete state
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def event event
|
|
46
|
+
custom_state = @custom_states[state]
|
|
47
|
+
|
|
48
|
+
to = if custom_state
|
|
49
|
+
begin
|
|
50
|
+
custom_state.send event
|
|
51
|
+
rescue NoMethodError
|
|
52
|
+
raise_without_self "There is no :#{event} Event in :#{state} State!"
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
actions = self.class.from_actions[state]
|
|
56
|
+
raise_without_self "There is no :#{event} Event in :#{state} State!" unless actions
|
|
57
|
+
actions[event]
|
|
58
|
+
end
|
|
59
|
+
raise_without_self "There is no :#{event} Event in :#{state} State!" unless to
|
|
60
|
+
|
|
61
|
+
# p [state, event, to]
|
|
62
|
+
|
|
63
|
+
old_state = state
|
|
64
|
+
|
|
65
|
+
@state = to
|
|
66
|
+
|
|
67
|
+
begin
|
|
68
|
+
fire_action @on_exit[old_state]
|
|
69
|
+
fire_action @on_event[old_state + event]
|
|
70
|
+
fire_action @on_entry[to]
|
|
71
|
+
rescue Exception => e
|
|
72
|
+
@state = old_state
|
|
73
|
+
raise e
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def state; @state end
|
|
78
|
+
|
|
79
|
+
def state= new_state
|
|
80
|
+
custom_state = @custom_states[state]
|
|
81
|
+
|
|
82
|
+
event = if custom_state
|
|
83
|
+
begin
|
|
84
|
+
custom_state.state new_state
|
|
85
|
+
rescue Exception => e
|
|
86
|
+
raise e
|
|
87
|
+
end
|
|
88
|
+
else
|
|
89
|
+
states = self.class.from_states[state]
|
|
90
|
+
raise_without_self "There is no way from :#{state} State into :#{new_state} State!" unless states
|
|
91
|
+
states[new_state]
|
|
92
|
+
end
|
|
93
|
+
raise_without_self "There is no way from :#{state} State into :#{new_state} State!" unless event
|
|
94
|
+
|
|
95
|
+
old_state = state
|
|
96
|
+
|
|
97
|
+
@state = new_state
|
|
98
|
+
|
|
99
|
+
begin
|
|
100
|
+
fire_action @on_exit[old_state]
|
|
101
|
+
fire_action @on_event[old_state + event]
|
|
102
|
+
fire_action @on_entry[new_state]
|
|
103
|
+
rescue Exception => e
|
|
104
|
+
@state = old_state
|
|
105
|
+
raise e
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def == other
|
|
110
|
+
return true if equal? other
|
|
111
|
+
return state == other if other.is_a? Symbol
|
|
112
|
+
return state == other.state if other.is_a? StateMashine
|
|
113
|
+
return false
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def hash
|
|
117
|
+
state.hash
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def eql? other
|
|
121
|
+
return true if equal? other
|
|
122
|
+
return state == other.state if other.is_a? StateMashine
|
|
123
|
+
return false
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class << self
|
|
127
|
+
def from_actions; @from_actions end
|
|
128
|
+
def from_states; @from_states end
|
|
129
|
+
def initial_state_get; @initial_state end
|
|
130
|
+
def custom_state_get; @custom_state end
|
|
131
|
+
|
|
132
|
+
def transitions *args
|
|
133
|
+
@from_actions, @from_states = {}, {}
|
|
134
|
+
args.each do |from, action, to|
|
|
135
|
+
actions = @from_actions[from]
|
|
136
|
+
unless actions
|
|
137
|
+
actions = {}
|
|
138
|
+
@from_actions[from] = actions
|
|
139
|
+
end
|
|
140
|
+
actions[action] = to
|
|
141
|
+
|
|
142
|
+
states = @from_states[from]
|
|
143
|
+
unless states
|
|
144
|
+
states = {}
|
|
145
|
+
@from_states[from] = states
|
|
146
|
+
end
|
|
147
|
+
states[to] = action
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def custom_state state, klass;
|
|
152
|
+
@custom_state ||= {}
|
|
153
|
+
@custom_state[state] = klass
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def initial_state state; @initial_state = state end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def to_s
|
|
160
|
+
"#<#{self.class.name} state = :#{state}"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def inspect
|
|
164
|
+
to_s
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
protected
|
|
168
|
+
def fire_action a
|
|
169
|
+
return unless a
|
|
170
|
+
if a.is_a? Symbol
|
|
171
|
+
@object.send a if @object
|
|
172
|
+
else
|
|
173
|
+
a.call
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Synchronizer
|
|
2
|
+
include MonitorMixin
|
|
3
|
+
|
|
4
|
+
module ClassMethods
|
|
5
|
+
def synchronize *methods
|
|
6
|
+
methods.each do |name|
|
|
7
|
+
als = (name.to_s =~ /^[_a-zA-Z0-9]+$/) ? name : RubyExt::Cache.alias_counter.to_sym
|
|
8
|
+
|
|
9
|
+
alias_method :"sync_#{als}", name
|
|
10
|
+
script = "\
|
|
11
|
+
def #{name} *p, &b
|
|
12
|
+
synchronize{sync_#{als} *p, &b}
|
|
13
|
+
end"
|
|
14
|
+
class_eval script, __FILE__, __LINE__
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def synchronize_all
|
|
19
|
+
methods = self.instance_methods(false).collect{|m| m.to_sym}
|
|
20
|
+
synchronize *methods
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
def alias_counter
|
|
25
|
+
@alias_counter += 1
|
|
26
|
+
return :"m#{@alias_counter}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Array
|
|
2
|
+
def sort_by_weight weight
|
|
3
|
+
clone.sort_by_weight! weight.clone
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def sort_by_weight! weight
|
|
7
|
+
size.times do |i|
|
|
8
|
+
iteration = size - i - 1
|
|
9
|
+
break if iteration < 0
|
|
10
|
+
iteration.times do |j|
|
|
11
|
+
if weight[j] > weight[j+1]
|
|
12
|
+
buf = self[j]
|
|
13
|
+
self[j] = self[j+1]
|
|
14
|
+
self[j+1] = buf
|
|
15
|
+
|
|
16
|
+
buf = weight[j]
|
|
17
|
+
weight[j] = weight[j+1]
|
|
18
|
+
weight[j+1] = buf
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
return self
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
def should! cmd, arg = NotDefined
|
|
3
|
+
result = case cmd
|
|
4
|
+
when :be_never_called then false
|
|
5
|
+
|
|
6
|
+
when :be_nil then self.equal? nil
|
|
7
|
+
|
|
8
|
+
when :be_a
|
|
9
|
+
if arg.class == Array
|
|
10
|
+
arg.any?{|klass| self.is_a? klass}
|
|
11
|
+
else
|
|
12
|
+
self.is_a? arg
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
when :be
|
|
16
|
+
if arg.class == Array
|
|
17
|
+
arg.any?{|klass| self.respond_to :is?, klass}
|
|
18
|
+
else
|
|
19
|
+
self.respond_to :is?, arg
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
when :include then self.include? arg
|
|
23
|
+
|
|
24
|
+
when :be_in then arg.include? self
|
|
25
|
+
|
|
26
|
+
when :be_true then self
|
|
27
|
+
|
|
28
|
+
when :be_false then !self
|
|
29
|
+
|
|
30
|
+
when :be_empty then self.empty?
|
|
31
|
+
|
|
32
|
+
else
|
|
33
|
+
if arg.equal? NotDefined
|
|
34
|
+
self.send cmd
|
|
35
|
+
else
|
|
36
|
+
self.send cmd, arg
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
unless result
|
|
41
|
+
unless arg.equal? NotDefined
|
|
42
|
+
raise RuntimeError, "
|
|
43
|
+
ASSERTION FAILED:
|
|
44
|
+
#{self.inspect} should #{cmd} #{arg.inspect}
|
|
45
|
+
", caller
|
|
46
|
+
else
|
|
47
|
+
raise RuntimeError, "
|
|
48
|
+
ASSERTION FAILED:
|
|
49
|
+
#{self.inspect} should #{cmd}
|
|
50
|
+
", caller
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
return self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def should_not! cmd, arg = NotDefined
|
|
58
|
+
result = case cmd
|
|
59
|
+
when :be_never_called then false
|
|
60
|
+
|
|
61
|
+
when :be_nil then self.equal? nil
|
|
62
|
+
|
|
63
|
+
when :be_a
|
|
64
|
+
if arg.class == Array
|
|
65
|
+
arg.any?{|klass| self.is_a? klass}
|
|
66
|
+
else
|
|
67
|
+
self.is_a? arg
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
when :be
|
|
71
|
+
if arg.class == Array
|
|
72
|
+
arg.any?{|klass| self.respond_to :is?, klass}
|
|
73
|
+
else
|
|
74
|
+
self.respond_to :is?, arg
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
when :include then self.include? arg
|
|
78
|
+
|
|
79
|
+
when :be_in then arg.include? self
|
|
80
|
+
|
|
81
|
+
when :be_true then self
|
|
82
|
+
|
|
83
|
+
when :be_false then !self
|
|
84
|
+
|
|
85
|
+
when :be_empty then self.empty?
|
|
86
|
+
|
|
87
|
+
else
|
|
88
|
+
if arg.equal? NotDefined
|
|
89
|
+
self.send cmd
|
|
90
|
+
else
|
|
91
|
+
self.send cmd, arg
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if result
|
|
96
|
+
unless arg.equal? NotDefined
|
|
97
|
+
raise RuntimeError, "
|
|
98
|
+
ASSERTION FAILED:
|
|
99
|
+
#{self.inspect} should not #{cmd} #{arg.inspect}
|
|
100
|
+
", caller
|
|
101
|
+
else
|
|
102
|
+
raise RuntimeError, "
|
|
103
|
+
ASSERTION FAILED:
|
|
104
|
+
#{self.inspect} should not #{cmd}
|
|
105
|
+
", caller
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
return self
|
|
110
|
+
end
|
|
111
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
$debug = true
|
|
2
|
+
if $debug
|
|
3
|
+
warn 'DEBUG MODE'
|
|
4
|
+
|
|
5
|
+
#require 'ruby-debug'
|
|
6
|
+
|
|
7
|
+
Thread.abort_on_exception = true
|
|
8
|
+
|
|
9
|
+
RubyExt::ClassLoader.error_on_defined_constant = true
|
|
10
|
+
|
|
11
|
+
module Kernel
|
|
12
|
+
STACK_TRACE_EXCLUDE = [
|
|
13
|
+
/\/rspec/,
|
|
14
|
+
/\/ruby-debug/,
|
|
15
|
+
/\/monitor.rb/,
|
|
16
|
+
/\/timeout.rb/,
|
|
17
|
+
# /gems/,
|
|
18
|
+
# /WGUI/,
|
|
19
|
+
/\/MicroContainer/,
|
|
20
|
+
/\/RubyExt/,
|
|
21
|
+
/\/kernel.rb/,
|
|
22
|
+
/\/mongrel/,
|
|
23
|
+
/\/rack/,
|
|
24
|
+
/\/sync/,
|
|
25
|
+
/\/require/,
|
|
26
|
+
/\/site_ruby/,
|
|
27
|
+
/OpenConstructor/,
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
alias_method :old_caller, :caller
|
|
31
|
+
def caller int = 0
|
|
32
|
+
stack = old_caller
|
|
33
|
+
stack = stack[(int+1)..stack.size].delete_if do |line|
|
|
34
|
+
STACK_TRACE_EXCLUDE.any?{|re| line =~ re}
|
|
35
|
+
end
|
|
36
|
+
return stack
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def where?
|
|
40
|
+
puts "\nwhere:"
|
|
41
|
+
puts caller
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# alias_method :old_raise, :raise
|
|
45
|
+
# def raise *p
|
|
46
|
+
# case p.size
|
|
47
|
+
# when 3
|
|
48
|
+
# e, m, c = p
|
|
49
|
+
# when 2
|
|
50
|
+
# e, m = p
|
|
51
|
+
# c = caller
|
|
52
|
+
# when 1
|
|
53
|
+
# if p[0].is_a? Exception
|
|
54
|
+
# e = p[0].class
|
|
55
|
+
# m = p[0].message
|
|
56
|
+
# else
|
|
57
|
+
# e = RuntimeError
|
|
58
|
+
# m = p[0]
|
|
59
|
+
# end
|
|
60
|
+
# c = caller
|
|
61
|
+
# when 0
|
|
62
|
+
# e, m, c = RuntimeError, "", caller
|
|
63
|
+
# else
|
|
64
|
+
# old_raise "Invalid Usage!"
|
|
65
|
+
# end
|
|
66
|
+
# old_raise e, m, c
|
|
67
|
+
# end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
#def p; end
|
|
71
|
+
#def puts; end
|
data/lib/RubyExt/file.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class File
|
|
2
|
+
class << self
|
|
3
|
+
def write(path, data)
|
|
4
|
+
File.open(path, "wb") do |file|
|
|
5
|
+
return file.write(data)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def read(path)
|
|
10
|
+
File.open(path, "rb") do |file|
|
|
11
|
+
return file.read
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def create_directory dir
|
|
16
|
+
Dir.mkdir dir unless File.exist? dir
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete_directory dir
|
|
20
|
+
FileUtils.rm_r dir, :force => true if File.exist? dir
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
CRITICAL
|
|
2
|
+
- Reloading resourses in ClassXXX.res folder doesn't works.
|
|
3
|
+
- Change 'raise_without_self' to caller.delete(SomePackage)
|
|
4
|
+
|
|
5
|
+
MEDIUM
|
|
6
|
+
|
|
7
|
+
LOW
|
|
8
|
+
- Add macros functionality to Ruby. (for example replace all '!=' with 'not_equal')
|
|
9
|
+
- Create project 'Flawless Ruby' (macros != to not_equal, and so on)
|
|
10
|
+
- Automatically evaluate extension for resources, use Class["res"] instead of Class["res.yaml"]
|
|
11
|
+
|
|
12
|
+
DONE
|
|
13
|
+
- Add resource providers chaining.
|
|
14
|
+
- Resource providers should be abstract (also for ObjectModel storage).
|
|
15
|
+
- Cashe implementation
|
|
16
|
+
- Resource reloading doesn't works (fix and add spec).
|
|
17
|
+
- Add raise_withoud_self 'bla-bla', [excludeAclass, excludeBclass]
|