RubyExt 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/README +846 -0
  2. data/lib/RubyExt/Cache.rb +101 -0
  3. data/lib/RubyExt/Cache.res/multiple_version_with_args.txt +12 -0
  4. data/lib/RubyExt/Cache.res/multiple_version_without_args.txt +11 -0
  5. data/lib/RubyExt/Cache.res/single_version_with_args.txt +11 -0
  6. data/lib/RubyExt/Cache.res/single_version_without_args.txt +10 -0
  7. data/lib/RubyExt/ClassLoader.rb +142 -0
  8. data/lib/RubyExt/Debug.rb +24 -0
  9. data/lib/RubyExt/ExtraBlankSlate.rb +14 -0
  10. data/lib/RubyExt/ImportAll.rb +9 -0
  11. data/lib/RubyExt/Localization/Module.rb +12 -0
  12. data/lib/RubyExt/Localization/Object.rb +19 -0
  13. data/lib/RubyExt/Localization/require.rb +3 -0
  14. data/lib/RubyExt/Localization.rb +28 -0
  15. data/lib/RubyExt/Log.config.sample +57 -0
  16. data/lib/RubyExt/Log.rb +59 -0
  17. data/lib/RubyExt/OpenConstructor.rb +51 -0
  18. data/lib/RubyExt/Path.rb +91 -0
  19. data/lib/RubyExt/Resource/file_system_provider.rb +244 -0
  20. data/lib/RubyExt/StateMashine.rb +176 -0
  21. data/lib/RubyExt/Synchronizer.rb +29 -0
  22. data/lib/RubyExt/array.rb +24 -0
  23. data/lib/RubyExt/assert.rb +111 -0
  24. data/lib/RubyExt/class.rb +0 -0
  25. data/lib/RubyExt/debug.rb +71 -0
  26. data/lib/RubyExt/false_class.rb +5 -0
  27. data/lib/RubyExt/file.rb +23 -0
  28. data/lib/RubyExt/ideas.txt +17 -0
  29. data/lib/RubyExt/kernel.rb +61 -0
  30. data/lib/RubyExt/module.rb +102 -0
  31. data/lib/RubyExt/nil_class.rb +5 -0
  32. data/lib/RubyExt/object.rb +7 -0
  33. data/lib/RubyExt/observable.rb +25 -0
  34. data/lib/RubyExt/require.rb +56 -0
  35. data/lib/RubyExt/require_base.rb +35 -0
  36. data/lib/RubyExt/resource.rb +198 -0
  37. data/lib/RubyExt/string.rb +21 -0
  38. data/lib/RubyExt/symbol.rb +21 -0
  39. data/lib/RubyExt/true_class +0 -0
  40. data/lib/RubyExt/true_class.rb +5 -0
  41. data/rakefile +49 -0
  42. data/spec/RubyExt/ForClassLoader/ClassA.rb +4 -0
  43. data/spec/RubyExt/ForClassLoader/LoadCount.rb +1 -0
  44. data/spec/RubyExt/ForClassLoader/ModuleA/ClassB.rb +3 -0
  45. data/spec/RubyExt/ForClassLoader/ModuleA/ClassInsideAnonymousClass.rb +3 -0
  46. data/spec/RubyExt/ForClassLoader/ModuleA/InfinityLoop.rb +3 -0
  47. data/spec/RubyExt/ForClassLoader/ModuleA/ModuleB/ClassC.rb +3 -0
  48. data/spec/RubyExt/ForClassLoader/ModuleA/SameName/SomeClass.rb +2 -0
  49. data/spec/RubyExt/ForClassLoader/ModuleA/SameName.rb +2 -0
  50. data/spec/RubyExt/ForClassLoader/Scope/ScopeA1.rb +3 -0
  51. data/spec/RubyExt/ForClassLoader/Scope/ScopeB1.rb +5 -0
  52. data/spec/RubyExt/ForKernel/Raise2.rb +5 -0
  53. data/spec/RubyExt/ForKernel/RaiseWithoutSelf.rb +9 -0
  54. data/spec/RubyExt/ForLocalization/NS/A.rb +3 -0
  55. data/spec/RubyExt/ForLocalization/NS/A.ru.localization.yaml +2 -0
  56. data/spec/RubyExt/ForLocalization/NS/B.rb +22 -0
  57. data/spec/RubyExt/ForLocalization/NS/B.ru.localization.yaml +3 -0
  58. data/spec/RubyExt/ForLocalization/NS.ru.localization.yaml +2 -0
  59. data/spec/RubyExt/ForModule/NS1/A.data +1 -0
  60. data/spec/RubyExt/ForModule/NS1/A.rb +1 -0
  61. data/spec/RubyExt/ForModule/NS1/A2.rb +1 -0
  62. data/spec/RubyExt/ForModule/NS1/B.rb +2 -0
  63. data/spec/RubyExt/ForModule/NS1/B2.rb +1 -0
  64. data/spec/RubyExt/ForModule/NS1.data +1 -0
  65. data/spec/RubyExt/ForModule/NS2/A.data +1 -0
  66. data/spec/RubyExt/ForModule/NS2/A.rb +3 -0
  67. data/spec/RubyExt/ForModule/NS2/B.rb +3 -0
  68. data/spec/RubyExt/ForModule/NS2/M.data +1 -0
  69. data/spec/RubyExt/ForModule/NS2/M.rb +3 -0
  70. data/spec/RubyExt/ForResource/ChangedClass.rb +1 -0
  71. data/spec/RubyExt/ForResource/ChangedClass.res/Text.txt +0 -0
  72. data/spec/RubyExt/ForResource/ChangedClass.txt +0 -0
  73. data/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ChainTest.rb +3 -0
  74. data/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ChainTest.resource +1 -0
  75. data/spec/RubyExt/ForResource/ProviderChaining/ProviderABaseDir/ClassExistOnlyInProviderA.rb +3 -0
  76. data/spec/RubyExt/ForResource/ProviderChaining/ProviderBBaseDir/ChainTest.rb +3 -0
  77. data/spec/RubyExt/ForResource/ProviderChaining/ProviderBBaseDir/ChainTest.resource +1 -0
  78. data/spec/RubyExt/ForResource/ResourceExtension.rb +1 -0
  79. data/spec/RubyExt/ForResource/ResourceExtension.res/Data.yaml +2 -0
  80. data/spec/RubyExt/ForResource/ResourceTest/Test.rb +1 -0
  81. data/spec/RubyExt/ForResource/ResourceTest/Test.res/Data.txt +1 -0
  82. data/spec/RubyExt/ForResource/ResourceTest/Test.res/txt +1 -0
  83. data/spec/array_spec.rb +27 -0
  84. data/spec/assert_spec.rb +18 -0
  85. data/spec/cache_spec.rb +95 -0
  86. data/spec/class_loader_spec.rb +94 -0
  87. data/spec/import_all_spec.rb +21 -0
  88. data/spec/kernel_spec.rb +38 -0
  89. data/spec/localization_spec.rb +49 -0
  90. data/spec/module_spec.rb +135 -0
  91. data/spec/object_spec.rb +8 -0
  92. data/spec/observable_spec.rb +44 -0
  93. data/spec/open_constructor_spec.rb +38 -0
  94. data/spec/path_spec.rb +169 -0
  95. data/spec/resource_spec.rb +135 -0
  96. data/spec/state_machine_spec.rb +201 -0
  97. data/spec/synchronizer_spec.rb +66 -0
  98. metadata +130 -10
  99. data/lib/RubyExt.rb +0 -1
  100. data/lib/hello_gem.rb +0 -5
@@ -0,0 +1,101 @@
1
+ module Cache
2
+ DISABLED = false
3
+
4
+ warn "CASHE DISABLED" if DISABLED
5
+
6
+ # It's not a good idea to mix Business Logic and Performance optimization,
7
+ # so i think these methods should be never used.
8
+ # def cached *methods
9
+ # Cache.cached self, *methods
10
+ # end
11
+ #
12
+ # def cached_with_params *methods
13
+ # Cache.cached_with_params self, *methods
14
+ # end
15
+
16
+ @versions, @alias_counter, @monitor = Hash.new{should! :be_never_called}, 0, Monitor.new
17
+ class << self
18
+
19
+ def alias_counter
20
+ @alias_counter += 1
21
+ return :"m#{@alias_counter}"
22
+ end
23
+
24
+ def cached *arg
25
+ vnames, klass, methods = parse_and_check_arguments *arg
26
+
27
+ return if DISABLED
28
+ methods.each do |m|
29
+ als = (m.to_s =~ /^[_a-zA-Z0-9]+$/) ? m : RubyExt::Cache.alias_counter.to_sym
30
+
31
+ klass.class_eval{alias_method :"cached_#{als}", :"#{m}"}
32
+ unless vnames.is_a? Array
33
+ script = Cache["single_version_without_args.txt"].substitute binding
34
+ @versions[vnames] = 0 unless @versions.include? vnames
35
+ else
36
+ vnames_str = vnames.collect{|vname| "'#{vname}' => nil"}.join(', ')
37
+ script = Cache["multiple_version_without_args.txt"].substitute binding
38
+ vnames.each{|vname| @versions[vname] = 0 unless @versions.include? vname}
39
+ end
40
+ klass.class_eval script, __FILE__, __LINE__
41
+ end
42
+ end
43
+
44
+ def cached_with_params *arg
45
+ vnames, klass, methods = parse_and_check_arguments *arg
46
+
47
+ return if DISABLED
48
+ methods.each do |m|
49
+ als = (m.to_s =~ /^[_a-zA-Z0-9]+$/) ? m : RubyExt::Cache.alias_counter
50
+
51
+ klass.class_eval{alias_method :"cached_#{als}", :"#{m}"}
52
+ unless vnames.is_a? Array
53
+ script = Cache["single_version_with_args.txt"].substitute binding
54
+ @versions[vnames] = 0 unless @versions.include? vnames
55
+ else
56
+ vnames_str = vnames.collect{|vname| "'#{vname}' => nil"}.join(', ')
57
+ script = Cache["multiple_version_with_args.txt"].substitute binding
58
+ vnames.each{|vname| @versions[vname] = 0 unless @versions.include? vname}
59
+ end
60
+ klass.class_eval script, __FILE__, __LINE__
61
+ end
62
+ end
63
+
64
+ def version name
65
+ @versions[name]
66
+ end
67
+
68
+ def update *names
69
+ names.each do |n|
70
+ n = n.to_s
71
+ @versions[n] = 0 unless @versions.include? n
72
+ @versions[n] += 1
73
+ end
74
+ end
75
+
76
+ attr_reader :monitor
77
+
78
+ protected
79
+ def parse_and_check_arguments *arg
80
+ arg.size.should! :>=, 3
81
+
82
+ version_names = arg[0]
83
+ if version_names.is_a? Array
84
+ version_names.size.should! :>, 0
85
+ version_names = version_names.collect{|n| n.to_s}
86
+ else
87
+ version_names = version_names.to_s
88
+ end
89
+
90
+ klass = arg[1]
91
+ klass.class.should! :be, [Class, Module]
92
+
93
+ methods = arg[2..arg.size]
94
+ defined = klass.instance_methods
95
+ methods.each do |m|
96
+ raise "Invalid method_name '#{m}'!" unless defined.include? m.to_s
97
+ end
98
+ return version_names, klass, methods
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,12 @@
1
+ def #{m} *params
2
+ Cache.monitor.synchronize do
3
+ @cache_versions_#{als} ||= {#{vnames_str}}
4
+ @cache_value_#{als} ||= {}
5
+ if @cache_versions_#{als}.all?{|vname, v| v == RubyExt::Cache.version(vname)} and @cache_value_#{als}.include?(params)
6
+ return @cache_value_#{als}[params]
7
+ else
8
+ @cache_versions_#{als}.keys.each{|vname| @cache_versions_#{als}[vname] = RubyExt::Cache.version(vname)}
9
+ return @cache_value_#{als}[params] = cached_#{als}(*params)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ def #{m}
2
+ Cache.monitor.synchronize do
3
+ @cache_versions_#{als} ||= {#{vnames_str}}
4
+ if @cache_versions_#{als}.all?{|vname, v| v == RubyExt::Cache.version(vname)}
5
+ return @cache_value_#{als}
6
+ else
7
+ @cache_versions_#{als}.keys.each{|vname| @cache_versions_#{als}[vname] = RubyExt::Cache.version(vname)}
8
+ return @cache_value_#{als} = cached_#{als}
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ def #{m} *params
2
+ Cache.monitor.synchronize do
3
+ @cache_value_#{als} ||= {}
4
+ if @cache_version_#{als} == RubyExt::Cache.version("#{vnames}") and @cache_value_#{als}.include?(params)
5
+ return @cache_value_#{als}[params]
6
+ else
7
+ @cache_version_#{als} = RubyExt::Cache.version("#{vnames}")
8
+ return @cache_value_#{als}[params] = cached_#{als}(*params)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ def #{m}
2
+ Cache.monitor.synchronize do
3
+ if @cache_version_#{als} == RubyExt::Cache.version("#{vnames}")
4
+ return @cache_value_#{als}
5
+ else
6
+ @cache_version_#{als} = RubyExt::Cache.version("#{vnames}")
7
+ return @cache_value_#{als} = cached_#{als}
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,142 @@
1
+ module RubyExt
2
+ module ClassLoader
3
+ @monitor = Monitor.new
4
+ @loaded_classes = {}
5
+
6
+ class << self
7
+ include Observable
8
+
9
+ attr_accessor :error_on_defined_constant
10
+
11
+ def reload_class class_name
12
+ @monitor.synchronize do
13
+ class_name = class_name.sub(/^::/, "")
14
+ namespace = Module.namespace_for(class_name);
15
+ name = class_name.sub(/^#{namespace}::/, "")
16
+ return load_class namespace, name, true
17
+ end
18
+ end
19
+
20
+ def load_class namespace, const, reload = false
21
+ @monitor.synchronize do
22
+ namespace = nil if namespace == Object or namespace == Module
23
+ target_namespace = namespace
24
+
25
+ # Name hack (for anonymous classes)
26
+ namespace = eval "#{name_hack(namespace)}" if namespace
27
+
28
+ class_name = namespace ? "#{namespace.name}::#{const}" : const
29
+ simple_also_tried = false
30
+ begin
31
+ simple_also_tried = (namespace == nil)
32
+
33
+ if try_load class_name, const
34
+ defined_in_home_scope = namespace ? namespace.const_defined?(const) : \
35
+ Object.const_defined?(const)
36
+
37
+ raise_without_self NameError, "Class Name '#{class_name}' doesn't\
38
+ correspond to File Name '#{Resource.class_to_virtual_file(class_name)}'!", ClassLoader \
39
+ unless defined_in_home_scope
40
+
41
+ unless reload
42
+ if @loaded_classes.include? class_name
43
+ if error_on_defined_constant
44
+ raise_without_self NameError,
45
+ "Class '#{class_name}' is not defined in the '#{target_namespace}' Namespace!",
46
+ ClassLoader
47
+ else
48
+ warn "Warn: Class '#{class_name}' is not defined in the '#{target_namespace}' Namespace!"
49
+ puts caller
50
+ end
51
+ end
52
+ end
53
+
54
+ result = namespace ? namespace.const_get(const) : Object.const_get(const)
55
+
56
+ @loaded_classes[class_name] = target_namespace
57
+ notify_observers :update_class, result
58
+ return result
59
+ elsif namespace
60
+ namespace = Module.namespace_for(namespace.name)
61
+ class_name = namespace ? "#{namespace.name}::#{const}" : const
62
+ end
63
+ end until simple_also_tried
64
+
65
+ raise_without_self NameError, "uninitialized constant '#{class_name}'!",
66
+ ClassLoader
67
+ end
68
+ end
69
+
70
+ def wrap_inside_namespace namespace, script
71
+ nesting = []
72
+ if namespace
73
+ current_scope = ""
74
+ namespace.name.split("::").each do |level|
75
+ current_scope += "::#{level}"
76
+ type = eval current_scope, TOPLEVEL_BINDING, __FILE__, __LINE__
77
+ nesting << [level, (type.class == Module ? "module" : "class")]
78
+ end
79
+ end
80
+ begining = nesting.collect{|l, t| "#{t} #{l};"}.join(' ')
81
+ ending = nesting.collect{"end"}.join('; ')
82
+ return "#{begining}#{script} \n#{ending}"
83
+ end
84
+
85
+ protected
86
+
87
+ def try_load class_name, const
88
+ if Resource.class_exist? class_name
89
+ script = Resource.class_get class_name
90
+ script = wrap_inside_namespace Module.namespace_for(class_name), script
91
+ eval script, TOPLEVEL_BINDING, Resource.class_to_virtual_file(class_name)
92
+ # elsif Resource.class_namespace_exist? class_name
93
+ # script = "#{begining} module #{const}; end; #{ending}"
94
+ # eval script, TOPLEVEL_BINDING, __FILE__, __LINE__
95
+ else
96
+ return false
97
+ end
98
+ return true
99
+ end
100
+
101
+ def name_hack namespace
102
+ if namespace
103
+ namespace.to_s.gsub("#<Class:", "").gsub(">", "")
104
+ else
105
+ ""
106
+ end
107
+ # Namespace Hack description
108
+ # Module.name doesn't works correctly for Anonymous classes.
109
+ # try to execute this code:
110
+ #
111
+ #class Module
112
+ # def const_missing const
113
+ # p self.to_s
114
+ # end
115
+ #end
116
+ #
117
+ #class A
118
+ # class << self
119
+ # def a
120
+ # p self
121
+ # MissingConst
122
+ # end
123
+ # end
124
+ #end
125
+ #
126
+ #A.a
127
+ #
128
+ # the output will be:
129
+ # A
130
+ # "#<Class:A>"
131
+ #
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ class Module
138
+ # alias_method :old_const_missing, :const_missing
139
+ def const_missing const
140
+ return RubyExt::ClassLoader.load_class self, const.to_s
141
+ end
142
+ end
@@ -0,0 +1,24 @@
1
+ class Debug
2
+ class << self
3
+
4
+ def trace_methods klass
5
+ klass.instance_methods(false).each do |m|
6
+ klass.class_eval do
7
+ alias_method :"old_#{m}", m
8
+ define_method m.to_sym do |*args|
9
+ begin
10
+ time = Time.now
11
+ p [m.to_sym, :start]
12
+ result = send :"old_#{m}", *args
13
+ ensure
14
+ p [m.to_sym, :end, time - Time.now]
15
+ end
16
+ return result
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ class ExtraBlankSlate < BlankSlate
2
+ CUSTOM_UNDEFINE = [:p, :select, :puts]
3
+
4
+ undefine = Kernel.instance_methods + Object.instance_methods + CUSTOM_UNDEFINE
5
+ BlankSlate.instance_methods.each{|m| undefine.delete m}
6
+
7
+ undefine.each do |m|
8
+ script = %{\
9
+ def #{m} *p, &b
10
+ method_missing :#{m}, *p, &b
11
+ end}
12
+ class_eval script, __FILE__, __LINE__
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module ImportAll
2
+ def import_all *params
3
+ params.each do |m|
4
+ m.constants.each do |name|
5
+ const_set name, m.const_get(name)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class Module
2
+ def localization lang
3
+ list, resource = [], "#{lang}.#{RubyExt::Localization::RESOURCE_EXTENSION}"
4
+ self_ancestors_and_namespaces do |klass|
5
+ if RubyExt::Resource.resource_exist? klass, resource
6
+ list << RubyExt::Resource.resource_get(klass, resource)
7
+ end
8
+ end
9
+ return list.reverse.inject(:merge)
10
+ end
11
+ end
12
+ Cache.cached_with_params :class, Module, :localization
@@ -0,0 +1,19 @@
1
+ class Object
2
+ def to_l string, binding = nil
3
+ lang = RubyExt::Localization.language
4
+ unless lang == RubyExt::Localization::DEFAULT_LANGUAGE
5
+ aself = self.respond_to(:localization_self) || self
6
+ aclass = (aself.class == Class or aself.class == Module) ? aself : aself.class
7
+
8
+ localization = aclass.localization lang
9
+ if localization and localization.include? string
10
+ string = localization[string]
11
+ else
12
+ RubyExt::Localization.log.warn("Not localized: '#{aclass.name}' '#{string}'!")
13
+ end
14
+ end
15
+
16
+ string = string.substitute binding if binding
17
+ return string
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ require 'RubyExt/require'
2
+ require 'RubyExt/Localization/Module'
3
+ require 'RubyExt/Localization/Object'
@@ -0,0 +1,28 @@
1
+ module Localization
2
+ extend Log
3
+ DEFAULT_LANGUAGE = :en
4
+ RESOURCE_EXTENSION = "localization.yaml"
5
+
6
+ class << self
7
+ def default_language= lang
8
+ @default_language = lang
9
+ end
10
+
11
+ def default_language
12
+ @default_language ||= DEFAULT_LANGUAGE
13
+ end
14
+
15
+ def language= block
16
+ @language = block
17
+ end
18
+
19
+ def language
20
+ if @language
21
+ lang = @language.call
22
+ return lang || default_language
23
+ else
24
+ return default_language
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ <log4r_config>
2
+ <pre_config>
3
+ <global level="DEBUG"/>
4
+
5
+ <parameter name="serverlog" value="./logs/server.log"/>
6
+ </pre_config>
7
+
8
+
9
+ <outputter type="FileOutputter" name="server">
10
+ <filename>#{serverlog}</filename>
11
+ <trunc>false</trunc>
12
+ </outputter>
13
+ <outputter type="FileOutputter" name="client"
14
+ filename="./../logs/client.log"/>
15
+ <outputter type="FileOutputter" name="gui"
16
+ filename="./../logs/guidebug.log"/>
17
+ <outputter type="StderrOutputter" name="console" level="ERROR"/>
18
+
19
+ <logger name="server" level="ERROR" outputters="server, console"/>
20
+ <logger name="client" level="INFO" outputters="client, console"/>
21
+ <logger name="client::gui" trace="true">
22
+ <level>DEBUG</level>
23
+ <outputter>gui</outputter>
24
+ </logger>
25
+
26
+ </log4r_config>
27
+
28
+
29
+
30
+
31
+ <log4r_config>
32
+ <pre_config>
33
+ <global level="ALL"/>
34
+ </pre_config>
35
+
36
+ <outputter type="StderrOutputter" name="default" level="ALL"/>
37
+ <logger name="Default" level="ALL" outputters="default"/>
38
+
39
+ <outputter type="StderrOutputter" name="console" level="WARN"/>
40
+ <outputter type="StderrOutputter" name="console_all" level="ALL"/>
41
+ <outputter type="FileOutputter" name="microcontainer" filename="./../logs/microcontainer.log"/>
42
+ <outputter type="FileOutputter" name="rubyext" filename="./../logs/rubyext.log"/>
43
+ <outputter type="FileOutputter" name="wgui" filename="./../logs/wgui.log"/>
44
+ <outputter type="FileOutputter" name="howt" filename="./../logs/howt.log"/>
45
+ <outputter type="FileOutputter" name="log" filename="./../logs/log.log"/>
46
+ <outputter type="FileOutputter" name="localization" filename="./../logs/localization.log"/>
47
+ <outputter type="FileOutputter" name="object_model" filename="./../logs/object_model.log" level="ALL"/>
48
+
49
+ <logger name="MicroContainer" level="ALL" outputters="console, microcontainer"/>
50
+ <logger name="HOWT" level="ALL" outputters="console, howt"/>
51
+ <logger name="WGUI" level="ALL" outputters="console, wgui"/>
52
+ <logger name="RubyExt" level="ALL" outputters="console, rubyext"/>
53
+ <logger name="Localization" level="ALL" outputters="localization"/>
54
+ <logger name="Log" level="ALL" outputters="console, log"/>
55
+ <logger name="ClassLoader" level="ALL" outputters="console_all"/>
56
+ <logger name="ObjectModel" level="ALL" outputters="object_model, console_all"/>
57
+ </log4r_config>
@@ -0,0 +1,59 @@
1
+ require 'log4r'
2
+ require 'log4r/configurator'
3
+
4
+ module Log
5
+ @loggers = Hash.new do |hash, klass|
6
+ # Such complex initialization because I don't know how it exactly work.
7
+ # For example: Log.new for WGUI::SomeClass will works, but Log.new for WGUI will not.
8
+ logger = begin
9
+ Log4r::Logger.get(klass.name)
10
+ rescue
11
+ Log4r::Logger.new(klass.name) rescue Log4r::Logger.get("Default")
12
+ end
13
+ hash[klass] = logger
14
+ end
15
+
16
+ module ClassMethods
17
+ def log
18
+ Log.loggers[(self.class == Class or self.class == Module) ? self : self.class]
19
+ end
20
+ end
21
+
22
+ def log
23
+ Log.loggers[(self.class == Class or self.class == Module) ? self : self.class]
24
+ end
25
+
26
+ class << self
27
+ attr_reader :loggers
28
+
29
+ def info *s
30
+ log.info *s
31
+ end
32
+
33
+ def error *s
34
+ log.error *s
35
+ end
36
+
37
+ def warn *s
38
+ log.warn *s
39
+ end
40
+
41
+ def log
42
+ Log.loggers[Log]
43
+ end
44
+ end
45
+ # configure %{\
46
+ #<log4r_config>
47
+ # <pre_config>
48
+ # <global level="ALL"/>
49
+ # </pre_config>
50
+ #
51
+ # <outputter type="StderrOutputter" name="default" level="ALL"/>
52
+ # <logger name="Default" level="ALL" outputters="default"/>
53
+ #</log4r_config>}
54
+ end
55
+
56
+ module Log
57
+ config = Dir.getwd + "config/log.xml"
58
+ Log4r::Configurator.load_xml_string(File.read(config)) if File.exist? config
59
+ end
@@ -0,0 +1,51 @@
1
+ module OpenConstructor
2
+ def set values, list = nil
3
+ unless list
4
+ if values.is_a? Hash
5
+ values.each do |k, v|
6
+ self.respond_to k.to_writer, v
7
+ end
8
+ else
9
+ values.instance_variables.each do |name|
10
+ accessor = name[1..name.size].to_writer
11
+ if self.respond_to? accessor
12
+ self.send accessor, values.instance_variable_get(name)
13
+ end
14
+ end
15
+ end
16
+ else
17
+ if values.is_a? Hash
18
+ values.each do |k, v|
19
+ self.respond_to k.to_writer, v if list.include? k
20
+ end
21
+ else
22
+ values.instance_variables.each do |name|
23
+ accessor = name[1..name.size]
24
+ if list.include?(accessor.to_sym)
25
+ accessor = accessor.to_writer
26
+ if self.respond_to?(accessor)
27
+ self.send accessor, values.instance_variable_get(name)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ return self
34
+ end
35
+
36
+ def set_with_check values
37
+ values.each do |k, v|
38
+ self.send k.to_writer, v
39
+ end
40
+ return self
41
+ end
42
+ alias_method :set!, :set_with_check
43
+
44
+ def to_hash
45
+ hash = {}
46
+ instance_variables.each do |name|
47
+ hash[name[1..name.size].to_sym] = instance_variable_get name
48
+ end
49
+ return hash
50
+ end
51
+ end
@@ -0,0 +1,91 @@
1
+ class Path < String
2
+ def initialize path = ''
3
+ super path.chomp
4
+ raise "Invalid Path '#{path}' (ends with the '/' sign)" if (self =~ /\/$/ ) && !empty?
5
+ raise "Tnvalid Path '#{path}' (the '/' sign encounters multiple times in a row)" if self =~ /\/{2,}/
6
+ end
7
+
8
+ def absolute?;
9
+ (self =~ /^\//) ? true : false
10
+ end
11
+
12
+ def relative?;
13
+ !absolute?
14
+ end
15
+
16
+ def empty?; self == '' || self == '/' end
17
+
18
+ def simple?;
19
+ self =~ /^\/?[^\/]*$/ ? true : false
20
+ end
21
+
22
+ def after part
23
+ raise "There is no Part '#{part}' in the Path '#{self}'" unless include? part
24
+ Path.new((absolute? ? '/' : '') + sub(/.*#{part}\/*/, ""))
25
+ end
26
+
27
+ def before part
28
+ raise "There is no Part '#{part}' in the Path '#{self}'" unless include? part
29
+ Path.new((absolute? ? '/' : '') + to_relative.sub(/\/*#{part}.*/, ""))
30
+ end
31
+
32
+ def previous;
33
+ return nil if empty?
34
+ p = sub(/[^\/]+?$/, "" )
35
+ p = p[0..p.string_size-2] if p.string_size > 1
36
+ return p
37
+ end
38
+
39
+ def next;
40
+ p = sub(/[^\/]+\/?/, "")
41
+ return p.empty? ? nil : p
42
+ end
43
+
44
+ def first;
45
+ Path.new(scan(/^\/?[^\/]*/)[0])
46
+ end
47
+
48
+ def last;
49
+ Path.new(sub(/[^\/].+\//, ""))
50
+ end
51
+
52
+ def last_name
53
+ list = scan(/[^\/]+$/)
54
+ return list.size > 0 ? list[0] : nil
55
+ end
56
+
57
+ def first_name
58
+ list = scan(/[^\/]+/)
59
+ return list.size > 0 ? list[0] : nil
60
+ end
61
+
62
+ def add path
63
+ path = Path.new(path) unless path.is_a? Path
64
+ return Path.new((absolute? ? "/" : "") + path.to_relative) if empty?
65
+ return Path.new(self) if path.empty?
66
+ return Path.new(self.string_plus((path.absolute? ? '' : '/')) + path)
67
+ end
68
+
69
+ alias_method :string_plus, :+
70
+ def + o
71
+ add(o)
72
+ end
73
+
74
+ def to_absolute; Path.new(absolute? ? self : "/#{self}") end
75
+
76
+ def to_relative; Path.new sub(/^\//, "") end
77
+
78
+ alias_method :string_each, :each
79
+ def each &block
80
+ to_a.each(&block)
81
+ end
82
+
83
+ alias_method :string_size, :size
84
+ def size() to_a.size end
85
+
86
+ def to_a; @elements ||= to_relative.split('/') end
87
+
88
+ def to_s
89
+ return String.new(self)
90
+ end
91
+ end