ruby_ext 0.4.11 → 0.4.12

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.
Files changed (69) hide show
  1. data/Rakefile +6 -6
  2. data/lib/rake_ext.rb +10 -5
  3. data/lib/rake_ext/project.rb +31 -16
  4. data/lib/rspec_ext.rb +82 -19
  5. data/lib/ruby_ext.rb +1 -52
  6. data/lib/ruby_ext/core.rb +24 -0
  7. data/lib/ruby_ext/{array.rb → core/array.rb} +4 -2
  8. data/lib/ruby_ext/core/basic_object.rb +8 -0
  9. data/lib/ruby_ext/core/class.rb +0 -0
  10. data/lib/ruby_ext/{deep_clone.rb → core/deep_clone.rb} +3 -4
  11. data/lib/ruby_ext/core/enumerable.rb +17 -0
  12. data/lib/ruby_ext/{file.rb → core/file.rb} +5 -2
  13. data/lib/ruby_ext/core/hash.rb +23 -0
  14. data/lib/ruby_ext/{kernel.rb → core/kernel.rb} +0 -0
  15. data/lib/ruby_ext/{micelaneous.rb → core/micelaneous.rb} +0 -0
  16. data/lib/ruby_ext/{module.rb → core/module.rb} +13 -2
  17. data/lib/ruby_ext/{multiple_inheritance.rb → core/multiple_inheritance.rb} +30 -14
  18. data/lib/ruby_ext/{must.rb → core/must.rb} +30 -27
  19. data/lib/ruby_ext/{not_defined.rb → core/not_defined.rb} +0 -0
  20. data/lib/ruby_ext/{object.rb → core/object.rb} +0 -0
  21. data/lib/ruby_ext/{open_object.rb → core/open_object.rb} +21 -16
  22. data/lib/ruby_ext/{string.rb → core/string.rb} +27 -0
  23. data/lib/ruby_ext/{symbol.rb → core/symbol.rb} +0 -0
  24. data/lib/ruby_ext/fixes.rb +6 -0
  25. data/lib/ruby_ext/gems.rb +0 -1
  26. data/lib/ruby_ext/more.rb +11 -0
  27. data/lib/ruby_ext/more/declarative_cache.rb +96 -0
  28. data/lib/ruby_ext/more/micelaneous.rb +7 -0
  29. data/lib/ruby_ext/{observable2.rb → more/observable2.rb} +0 -0
  30. data/lib/ruby_ext/{open_constructor.rb → more/open_constructor.rb} +2 -2
  31. data/lib/ruby_ext/more/safe_hash.rb +214 -0
  32. data/lib/ruby_ext/{synchronize.rb → more/synchronize.rb} +5 -5
  33. data/lib/ruby_ext/{tuple.rb → more/tuple.rb} +0 -0
  34. data/lib/yaml_fix.rb +9 -0
  35. data/readme.md +46 -42
  36. data/spec/core/array_spec.rb +7 -0
  37. data/spec/{deep_clone_spec.rb → core/deep_clone_spec.rb} +2 -3
  38. data/spec/core/enumerable.rb +9 -0
  39. data/spec/{kernel_spec.rb → core/kernel_spec.rb} +4 -6
  40. data/spec/{kernel_spec → core/kernel_spec}/TheNamespace/ClassA.rb +0 -0
  41. data/spec/{kernel_spec → core/kernel_spec}/another_class.rb +0 -0
  42. data/spec/{kernel_spec → core/kernel_spec}/the_namespace/class_b.rb +0 -0
  43. data/spec/{module_spec.rb → core/module_spec.rb} +2 -4
  44. data/spec/{multiple_inheritance_spec.rb → core/multiple_inheritance_spec.rb} +28 -12
  45. data/spec/core/must_spec.rb +32 -0
  46. data/spec/{open_object_spec.rb → core/open_object_spec.rb} +6 -7
  47. data/spec/core/spec_helper.rb +2 -0
  48. data/spec/{declarative_cache_spec.rb → more/declarative_cache_spec.rb} +35 -8
  49. data/spec/{observable2_spec.rb → more/observable2_spec.rb} +3 -4
  50. data/spec/{open_constructor_spec.rb → more/open_constructor_spec.rb} +6 -7
  51. data/spec/more/safe_hash_spec.rb +133 -0
  52. data/spec/more/spec_helper.rb +2 -0
  53. data/spec/{synchronize_spec.rb → more/synchronize_spec.rb} +2 -3
  54. metadata +67 -100
  55. data/lib/ruby_ext/basic_object.rb +0 -22
  56. data/lib/ruby_ext/class.rb +0 -11
  57. data/lib/ruby_ext/declarative_cache.rb +0 -85
  58. data/lib/ruby_ext/extra_blank_slate.rb +0 -17
  59. data/lib/ruby_ext/hash.rb +0 -15
  60. data/lib/ruby_ext/prepare_arguments.rb +0 -105
  61. data/lib/ruby_ext/prototype_inheritance.rb +0 -110
  62. data/lib/ruby_ext/should.rb +0 -166
  63. data/lib/rubyopt.rb +0 -7
  64. data/spec/_prototype_inheritance_spec.rb +0 -190
  65. data/spec/array_spec.rb +0 -8
  66. data/spec/must_spec.rb +0 -29
  67. data/spec/prepare_arguments_spec.rb +0 -46
  68. data/spec/should_spec.rb +0 -24
  69. data/spec/spec_helper.rb +0 -19
data/lib/ruby_ext/gems.rb CHANGED
@@ -1 +0,0 @@
1
- gem 'facets', '2.9.0'
@@ -0,0 +1,11 @@
1
+ require 'ruby_ext/core'
2
+
3
+ %w(
4
+ declarative_cache
5
+ observable2
6
+ open_constructor
7
+ synchronize
8
+ tuple
9
+ safe_hash
10
+ micelaneous
11
+ ).each{|f| require "ruby_ext/more/#{f}"}
@@ -0,0 +1,96 @@
1
+ require 'monitor'
2
+
3
+ Module.class_eval do
4
+ def cache_method *methods
5
+ DeclarativeCache.cache_method self, *methods
6
+ end
7
+
8
+ def cache_method_with_params *methods
9
+ DeclarativeCache.cache_method_with_params self, *methods
10
+ end
11
+ end
12
+
13
+ class Object
14
+ def clear_cache
15
+ instance_variables.each do |iv|
16
+ remove_instance_variable iv if iv =~ /_cache$/ or iv =~ /_cache_check$/
17
+ end
18
+ end
19
+ end
20
+
21
+ module DeclarativeCache
22
+ DISABLED = false
23
+
24
+ warn "CASHE DISABLED" if DISABLED
25
+ unless DISABLED
26
+ class << self
27
+
28
+ def cache_method klass, *methods
29
+ methods.each do |method|
30
+ klass.class_eval do
31
+ escaped_method = escape_method(method)
32
+ method_with_cache, method_without_cache = "#{escaped_method}_with_cache".to_sym, "#{escaped_method}_without_cache".to_sym
33
+ iv_check = "@#{escaped_method}_cache_check"
34
+ iv = "@#{escaped_method}_cache"
35
+
36
+ if instance_methods.include?(method_with_cache) or instance_methods.include?(method_without_cache)
37
+ warn "can't cache the :#{method} twice!"
38
+ else
39
+ alias_method method_without_cache, method
40
+
41
+ define_method method_with_cache do |*args|
42
+ raise "You tried to use cache without params for method with params (use 'cache_method_with_params' instead)!" unless args.empty?
43
+ unless cached = instance_variable_get(iv)
44
+ unless check = instance_variable_get(iv_check)
45
+ cached = send method_without_cache
46
+ instance_variable_set iv, cached
47
+ instance_variable_set iv_check, true
48
+ end
49
+ end
50
+ cached
51
+ end
52
+
53
+ alias_method method, method_with_cache
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def cache_method_with_params klass, *methods
60
+ methods.each do |method|
61
+ klass.class_eval do
62
+ escaped_method = escape_method(method)
63
+ method_with_cache, method_without_cache = "#{escaped_method}_with_cache".to_sym, "#{escaped_method}_without_cache".to_sym
64
+ iv_check = "@#{escaped_method}_cache_check"
65
+ iv = "@#{escaped_method}_cache"
66
+
67
+ if instance_methods.include?(method_with_cache) or instance_methods.include?(method_without_cache)
68
+ warn "can't cache the :#{method} twice!"
69
+ else
70
+ alias_method method_without_cache, method
71
+
72
+ define_method method_with_cache do |*args|
73
+ unless results = instance_variable_get(iv)
74
+ results = Hash.new(NotDefined)
75
+ instance_variable_set iv, results
76
+ end
77
+
78
+ result = results[args]
79
+
80
+ if result.equal? NotDefined
81
+ result = send method_without_cache, *args
82
+ results[args] = result
83
+ end
84
+
85
+ result
86
+ end
87
+
88
+ alias_method method, method_with_cache
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,7 @@
1
+ Kernel.class_eval do
2
+ alias_method :old_p, :p
3
+ def p *args
4
+ puts args.collect{|a| a.inspect}.join(' ')
5
+ return *args
6
+ end
7
+ end
@@ -33,13 +33,13 @@ module OpenConstructor
33
33
  return self
34
34
  end
35
35
 
36
- def set_with_check values
36
+ def set! values
37
37
  values.each do |k, v|
38
38
  self.send k.to_writer, v
39
39
  end
40
40
  return self
41
41
  end
42
- alias_method :set!, :set_with_check
42
+ # alias_method :set! #, :set_with_check
43
43
 
44
44
  def to_hash
45
45
  hash = {}
@@ -0,0 +1,214 @@
1
+ # require 'singleton'
2
+
3
+ class SafeHash < BasicObject
4
+ attr_reader :hash
5
+
6
+ alias_method :send, :__send__
7
+
8
+ def initialize hash = {}
9
+ reinitialize hash
10
+ end
11
+
12
+ def []= key, value
13
+ ::SafeHash.forbidden! key
14
+ # value = ::SafeHash.new value if value.is_a? ::Hash
15
+ # @hash[key.to_sym] = value
16
+ end
17
+
18
+ def set! key, value
19
+ value = ::SafeHash.new value if value.is_a? ::Hash
20
+ @hash[key.to_sym] = value
21
+ end
22
+ def set *args; raise "you probably mistyped :set! method!" end
23
+
24
+ def include? key
25
+ @hash.include? key.to_sym
26
+ end
27
+
28
+ def tap &b
29
+ b.call self
30
+ self
31
+ end
32
+
33
+ def [] key, if_not_exist = ::NotDefined
34
+ last = key[-1]
35
+ if last == '!'
36
+ key = key[0..-2].to_sym
37
+ if @hash.include? key
38
+ @hash[key]
39
+ else
40
+ raise "no key :#{key}"
41
+ end
42
+ elsif last == '?'
43
+ key = key[0..-2].to_sym
44
+ @hash.include? key
45
+ else
46
+ key = key.to_sym
47
+ if @hash.include? key
48
+ @hash[key]
49
+ elsif if_not_exist == ::NotDefined
50
+ SafeNil.new key
51
+ else
52
+ return if_not_exist
53
+ end
54
+ end
55
+ end
56
+
57
+ def reinitialize hash
58
+ @hash = {}
59
+ merge! hash
60
+ # hash.each do |k, v|
61
+ # v = ::SafeHash.new v if v.is_a? ::Hash
62
+ # @hash[k.to_sym] = v
63
+ # end
64
+ # @hash.freeze
65
+ end
66
+
67
+ def method_missing m, obj = ::NotDefined, &b
68
+ raise "invalid usage, can't pass block to (:#{m})!" if b
69
+ last = m[-1]
70
+ if last == '='
71
+ ::SafeHash.forbidden! m[0..-2]
72
+ # self[m[0..-2]] = obj
73
+ else
74
+ self[m, obj]
75
+ end
76
+ end
77
+
78
+ def to_yaml *args
79
+ @hash.to_yaml *args
80
+ end
81
+
82
+ def inspect
83
+ @hash.inspect
84
+ end
85
+
86
+ def delete key
87
+ @hash.delete key.to_sym
88
+ end
89
+
90
+ def merge! hash, options = {}
91
+ # parsing arguments
92
+ deep = options[:deep] || true
93
+ override = options[:override] || false
94
+ blank = options[:blank] || false
95
+ options.validate_options! :deep, :override, :blank
96
+ raise "invalid options, can't do both :blank and :override simultaneously!" if blank and override
97
+
98
+ # merging
99
+ hash.each do |k, v|
100
+ k = k.to_sym
101
+ if @hash.include? k
102
+ if deep and (old_v = @hash[k]).respond_to(:is_a_safe_hash?) and v.is_a?(::Hash)
103
+ old_v.merge! v, options
104
+ else
105
+ if blank
106
+ # do nothing
107
+ elsif override
108
+ self.set! k, v
109
+ else
110
+ raise "can't override :#{k} config value!" unless override
111
+ end
112
+ end
113
+ else
114
+ self.set! k, v
115
+ end
116
+ end
117
+ end
118
+ def merge *args; raise "you probably mistyped :merge! method!" end
119
+
120
+ def merge_if_blank! hash, options = {}
121
+ options[:blank] = true
122
+ merge! hash, options
123
+ end
124
+ def merge_if_blank *args; raise "you probably mistyped :merge_if_blank method!" end
125
+
126
+ # deep conversion, check and converts nested SafeHashes to Hashes
127
+ def to_hash options = {}
128
+ r = {}
129
+ @hash.each do |k, v|
130
+ k = k.to_s if options[:to_s]
131
+ r[k] = if v.respond_to :is_a_safe_hash?
132
+ v.to_hash options
133
+ else
134
+ v
135
+ end
136
+ end
137
+ r
138
+ end
139
+ alias_method :to_h, :to_hash
140
+
141
+ def is_a_safe_hash?
142
+ true
143
+ end
144
+
145
+
146
+ class SafeNil < BasicObject
147
+ # include ::Singleton
148
+
149
+ def initialize key
150
+ @key = key
151
+ end
152
+
153
+ def [] key, if_not_exist = ::NotDefined
154
+ last = key[-1]
155
+ if last == '!'
156
+ raise "no key :#{key}"
157
+ elsif last == '?'
158
+ false
159
+ elsif if_not_exist == ::NotDefined
160
+ SafeNil.new key
161
+ else
162
+ return if_not_exist
163
+ end
164
+ end
165
+
166
+ def method_missing m, if_not_exist = ::NotDefined, &b
167
+ raise "invalid usage, can't pass block to (:#{m})!" if b
168
+ last = m[-1]
169
+ if last == '='
170
+ ::SafeHash.forbidden! m[0..-2]
171
+ # raise "No key '#{@key}'!"
172
+ else
173
+ self[m, if_not_exist]
174
+ end
175
+ end
176
+
177
+ def include? key
178
+ false
179
+ end
180
+
181
+ def to_b
182
+ false
183
+ end
184
+
185
+ def to_yaml *args
186
+ nil.to_yaml *args
187
+ end
188
+
189
+ def to_h
190
+ {}
191
+ end
192
+
193
+ def to_s
194
+ raise "can't convert SafeNil for key '#{@key}' to String!"
195
+ end
196
+
197
+ def inspect
198
+ nil.inspect
199
+ end
200
+ end
201
+
202
+
203
+ class << self
204
+ def forbidden! key
205
+ raise "direct modifications of SafeHash is forbidden, use :merge instead (you are trying to assign :#{key} value)!"
206
+ end
207
+ end
208
+
209
+
210
+ protected
211
+ def p *a
212
+ ::Object.send :p, *a
213
+ end
214
+ end
@@ -1,13 +1,13 @@
1
1
  require 'monitor'
2
2
 
3
- class Module
3
+ Module.class_eval do
4
4
  def synchronize_method *methods
5
5
  methods.each do |method|
6
- raise "Can't synchronize system method #{method}" if method.to_s =~ /^__/
6
+ raise "can't synchronize system method #{method}" if method =~ /^__/
7
7
 
8
- als = "sync_#{escape_method(method)}"
8
+ als = "sync_#{escape_method(method)}".to_sym
9
9
 
10
- raise "Can't synchronize the '#{method}' twice!" if instance_methods.include?(als)
10
+ raise "can't synchronize the '#{method}' twice!" if instance_methods.include?(als)
11
11
 
12
12
  alias_method als, method
13
13
  script = "\
@@ -20,7 +20,7 @@ end"
20
20
  end
21
21
 
22
22
  def synchronize_all_methods include_super = false
23
- methods = self.instance_methods(include_super).collect{|m| m.to_sym}
23
+ methods = self.instance_methods(include_super).collect{|m| m}
24
24
  synchronize_method *methods
25
25
  end
26
26
  end
File without changes
data/lib/yaml_fix.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'yaml'
2
+
3
+ begin
4
+ require 'psych'
5
+ YAML::ENGINE.yamler = 'psych'
6
+ rescue Exception
7
+ warn "can't load 'psych', the new YAML engine (probably the 'libyaml' is not installed), usng 'sych' a deprecated one, \
8
+ there may be some problems with encoding."
9
+ end
data/readme.md CHANGED
@@ -1,55 +1,55 @@
1
1
  # Ruby extensions
2
- **ruby-ext** is a collection of various utility classes and standard library extensions for the Ruby language.
2
+ **ruby_ext** is a collection of various utility classes and standard library extensions for the Ruby language.
3
3
 
4
4
  ## must - assertion tool, kind of RSpec assertions in runtime code
5
5
 
6
- 1.must_be.in 1..2
7
- "a".must_be.in 'a', 'b', 'c'
8
- key.must_be.a String
9
- value.must_not_be.nil
10
- must_be.never_called
11
- a.must_be == b
6
+ 1.must_be.in 1..2
7
+ "a".must_be.in 'a', 'b', 'c'
8
+ key.must_be.a String
9
+ value.must_not_be.nil
10
+ must_be.never_called
11
+ a.must_be == b
12
12
 
13
13
  ## inherit - combines include & extend in one
14
14
  Do you remember this *def self.included(base) ... end* hack? You don't need it anymore.
15
15
 
16
- module Feature
17
- def cool_method; end
18
- class_methods do
19
- def cool_class_method; end
20
- end
21
- end
22
-
23
- class TheClass
24
- inherit Feature
25
- end
26
-
27
- TheClass.new.cool_method
28
- TheClass.cool_class_method
29
-
16
+ module Feature
17
+ def cool_method; end
18
+ class_methods do
19
+ def cool_class_method; end
20
+ end
21
+ end
22
+
23
+ class TheClass
24
+ inherit Feature
25
+ end
26
+
27
+ TheClass.new.cool_method
28
+ TheClass.cool_class_method
29
+
30
30
  ## cache_method & synchronize_method
31
31
 
32
- def complex_calculation
33
- 2 * 2
34
- end
35
- cache_method :complex_calculation
32
+ def complex_calculation
33
+ 2 * 2
34
+ end
35
+ cache_method :complex_calculation
36
36
 
37
- def money_transfer amount
38
- @from -= amount
39
- @to += amount
40
- end
41
- synchronize_method :money_transfer
37
+ def money_transfer amount
38
+ @from -= amount
39
+ @to += amount
40
+ end
41
+ synchronize_method :money_transfer
42
42
 
43
43
  ## OpenConstructor - adds mass assignment to any class
44
-
45
- class TheClass
46
- include OpenConstructor
47
- attr_accessor :a, :b
48
- end
44
+
45
+ class TheClass
46
+ include OpenConstructor
47
+ attr_accessor :a, :b
48
+ end
49
49
 
50
- o = TheClass.new.set :a => 'a', :b => 'b'
51
- o.a => 'a'
52
- o.to_hash => {:a => 'a', :b => 'b'}
50
+ o = TheClass.new.set a: 'a', b: 'b'
51
+ o.a => 'a'
52
+ o.to_hash => {a: 'a', b: 'b'}
53
53
 
54
54
  ## More
55
55
 
@@ -57,10 +57,14 @@ These are just a small part of all handy methods and extensions, for more detail
57
57
 
58
58
  # Usage
59
59
 
60
- $ sudo gem install ruby-ext
61
-
62
- require 'ruby_ext'
60
+ $ sudo gem install ruby_ext
61
+
62
+ require 'ruby_ext'
63
63
 
64
- Copyright (c) 2009 Alexey Petrushin [http://bos-tec.com](http://bos-tec.com), released under the MIT license.
64
+ Copyright (c) Alexey Petrushin [http://4ire.net](http://4ire.net), released under the MIT license.
65
+
66
+ # TODO
67
+
68
+ - config.development{} should raise 'invalid usage'
65
69
 
66
70
  [ioc]: http://en.wikipedia.org/wiki/Inversion_of_control