ruby_ext 0.4.11 → 0.4.12

Sign up to get free protection for your applications and to get access to all the features.
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