core_ex 0.2.0 → 0.3.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.
Files changed (41) hide show
  1. data/NEWS +39 -1
  2. data/SPEC.dyn.yml +6 -6
  3. data/SPEC.gemspec +13 -0
  4. data/SPEC.yml +3 -3
  5. data/lib/core_ex/dependencies_ext/constant_load_path.rb +23 -0
  6. data/lib/core_ex/embedded_tests.rb +29 -23
  7. data/lib/core_ex/enumerable.rb +10 -18
  8. data/lib/core_ex/exception.rb +24 -21
  9. data/lib/core_ex/file_utils.rb +51 -0
  10. data/lib/core_ex/module/attr_once.rb +41 -0
  11. data/lib/core_ex/module/import.rb +28 -0
  12. data/lib/core_ex/module/mix_in_with_args.rb +267 -0
  13. data/lib/core_ex/object/instance_eval_with_args.rb +56 -0
  14. data/lib/core_ex/object/singleton_class.rb +78 -0
  15. data/lib/core_ex/object/the_first_time.rb +32 -0
  16. data/lib/core_ex/pathname.rb +268 -164
  17. data/lib/core_ex/proc.rb +77 -0
  18. data/lib/core_ex/rakefile_base.rf +93 -51
  19. data/lib/core_ex/require.rb +43 -384
  20. data/lib/core_ex/string.rb +52 -41
  21. data/lib/core_ex/time.rb +26 -41
  22. data/lib/core_ex/try_dup.rb +68 -0
  23. data/lib/core_ex/yaml.rb +103 -100
  24. data/lib/core_ex.rb +246 -35
  25. data/lib/{core_ex/dtime.rb → d_time.rb} +36 -22
  26. data/lib/{core_ex/dumpable_proc.rb → dumpable_proc.rb} +1 -2
  27. data/lib/{core_ex/pathlist.rb → path_list.rb} +111 -63
  28. data/lib/{core_ex/temp_path.rb → temp_path.rb} +55 -41
  29. data/lib/{core_ex/test/unit/ui/yaml/testrunner.rb → test/unit/u_i/yaml/test_runner.rb} +7 -10
  30. data/lib/{core_ex/version.rb → version.rb} +4 -7
  31. data/lib/yaml_extension.rb +78 -0
  32. data/test/check-core_ex.yml +6 -8
  33. data/test/check-pkg-core_ex.yml +3 -6
  34. data/test/sanity/multiple-requires.yml +41 -17
  35. data/test/sanity/single-requires.yml +36 -20
  36. data/test/sanity-suite.yml +5 -7
  37. data/test/test-unit-setup.rb +11 -3
  38. data/test/unit-suite.yml +8 -9
  39. metadata +35 -13
  40. data/lib/core_ex/attr_once.rb +0 -36
  41. data/lib/core_ex/fileutils.rb +0 -44
@@ -1,387 +1,46 @@
1
1
  # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
2
2
  # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
3
3
  # License:: Gnu General Public License.
4
- # Revision:: $Id: require.rb 297 2005-06-18 21:51:39Z ertai $
5
-
6
- require 'core_ex/pathname'
7
- require 'set'
8
-
9
- module Kernel
10
- class << self
11
- alias :__require__ :require
12
- alias :__load__ :load
13
- end
14
- end # module Kernel
15
-
16
-
17
- class RequireSystem
18
-
19
-
20
- EXTENSIONS = %w[ .rb .so .bundle .o .dll ] << ''
21
-
22
-
23
- attr_reader :include_dirs, :loaded, :required
24
-
25
- def initialize
26
- @include_dirs = Set.new
27
- @loaded = Set.new
28
- # @autoloads = {} FIXME AUTOLOAD
29
- self.class.enable
30
- Kernel.kernel_require_system = self
31
- Module.module_require_system = self
32
- adds = []
33
- $".each do |file|
34
- feature = file.to_path.expand_path_with($:, EXTENSIONS)
35
- raise "file not found #{file}" if feature.nil?
36
- adds << feature.to_s unless feature.to_s == file
37
- end
38
- feature = $0.to_path.expand_path_with($:, EXTENSIONS)
39
- adds << feature.to_s unless feature.nil?
40
- $".replace(($" + adds).uniq)
41
- end
42
-
43
-
44
- def check_pathname ( aPathname )
45
- unless aPathname.is_a? Pathname
46
- raise LoadError, "need a Pathname not a #{aPathname.class}"
47
- end
48
- end
49
- protected :check_pathname
50
-
51
-
52
- def cannot_found ( aPathname )
53
- raise LoadError, "CoreEx: Cannot found #{aPathname} in $:"
54
- end
55
- private :cannot_found
56
-
57
-
58
- def add_to_required ( aString )
59
- return if $".include? aString
60
- $" << aString
61
- end
62
-
63
-
64
- def required_include? ( aString )
65
- $".include? aString
66
- end
67
-
68
-
69
- def load ( aPathname )
70
- check_pathname(aPathname)
71
- abs = aPathname.expand_path_with($:, EXTENSIONS + [aPathname.extname])
72
- cannot_found(aPathname) if abs.nil?
73
- @loaded << abs
74
- Kernel.__load__(abs)
75
- end
76
-
77
-
78
- # FIXME This autoload doesn't work for these reasons:
79
- # - |
80
- # # file1.rb
81
- # module B
82
- # class A
83
- # end
84
- # end
85
- #
86
- # # file2.rb
87
- # class A # where ::A != B::A
88
- # end
89
- #
90
- # module B
91
- # autoload :A, 'file1'
92
- # A # this doesn't work because ::A exists so no const_missing is reached
93
- # end
94
- #
95
- # - |
96
- # # file1.rb
97
- # module B
98
- # class A
99
- # end
100
- # end
101
- #
102
- # # file2.rb
103
- # module B
104
- # autoload :A, 'file1'
105
- # class ::C
106
- # A # this doesn't work because A is search in ::C which is not
107
- # # included in B.
108
- # end
109
- # end
110
- # etc.
111
- # Const missing was (it's obvious now) a very bad idea to make an autoload.
112
- # We need to hook a const_get which is call every time.
113
- def autoload ( aModule, aConst, aPathname )
114
- raise ArgumentError, "need a module not #{cst}" unless aModule.is_a? Module
115
- raise ArgumentError, "need a symbol not #{cst}" unless aConst.is_a? Symbol
116
- raise if aConst.to_s =~ /::/
117
- abs = aPathname.expand_path_with($:, EXTENSIONS)
118
- abs = aPathname if abs.nil? # FIXME
119
- # cannot_found(aPathname) if abs.nil?
120
- aModule.__autoload__(aConst, abs.to_s)
121
- # @autoloads[aModule] ||= {}
122
- # @autoloads[aModule][aConst] ||= []
123
- # @autoloads[aModule][aConst] << aPathname
124
- self
125
- end
126
-
127
-
128
- # def const_missing ( aModule, aConst )
129
- # raise ArgumentError, "need a module not #{cst}" unless aModule.is_a? Module
130
- # raise ArgumentError, "need a symbol not #{cst}" unless aConst.is_a? Symbol
131
- # raise if aConst.to_s =~ /::/
132
- # @autoloads[aModule] ||= {}
133
- # if @autoloads[aModule][aConst].nil?
134
- # mods = aModule.to_s.split(/::/)
135
- # if mods.size == 1
136
- # p "CONSTMISSING"
137
- # aModule.__const_missing__(aConst)
138
- # end
139
- # return const_missing(eval(mods[0..-2].join('::')), aConst)
140
- # end
141
- # @autoloads[aModule][aConst] ||= []
142
- # @autoloads[aModule][aConst].each do |req|
143
- # req.require
144
- # end
145
- # @autoloads[aModule].delete aConst
146
- # if aModule.const_defined?(aConst)
147
- # aModule.const_get(aConst)
148
- # else
149
- # p "CONSTMISSING"
150
- # aModule.__const_missing__(aConst)
151
- # end
152
- # end
153
-
154
- def require ( aPathname )
155
- check_pathname(aPathname)
156
- abs = aPathname.expand_path_with($:, EXTENSIONS)
157
- cannot_found(aPathname) if abs.nil?
158
- feature = aPathname.to_s
159
- feature += abs.extname if aPathname.extname.empty?
160
- if required_include? feature or required_include? abs.to_s
161
- return false
162
- else
163
- if abs.extname =~ /^(\.rb)?$/
164
- add_to_required feature
165
- add_to_required abs.to_s
166
- res = Kernel.__load__(abs)
167
- else
168
- res = Kernel.__require__(abs.extsplit.first.to_s)
169
- add_to_required feature
170
- add_to_required abs.to_s
171
- end
172
- return true
173
- end
174
- end
175
-
176
-
177
- def include_dir ( aPathname )
178
- unless abs = include_dir?(aPathname)
179
- $: << aPathname.to_s << abs.to_s
180
- @include_dirs << abs
181
- end
182
- self
183
- end
184
-
185
-
186
- def include_dir? ( aPathname )
187
- check_pathname(aPathname)
188
- abs = aPathname.expand_path.cleanpath
189
- return ($:.include?(aPathname.to_s) ||
190
- $:.include?(abs.to_s) ||
191
- @include_dirs.include?(abs))? abs : nil
192
- end
193
-
194
-
195
- def required? ( aPathname )
196
- check_pathname(aPathname)
197
- abs = aPathname.expand_path_with($:, EXTENSIONS)
198
- cannot_found(aPathname) if abs.nil?
199
- feature = aPathname.to_s
200
- feature += abs.extname if aPathname.extname.empty?
201
- return required_include?(feature)
202
- end
203
-
204
-
205
- def self.instance
206
- @@instance = new
207
- class << self
208
- undef :instance
209
- def instance
210
- @@instance
211
- end
212
- end
213
- @@instance
214
- end
215
-
216
- def self.enable
217
- class << self
218
- module ::Kernel
219
- def kernel_require_system= ( arg )
220
- @@require_system = arg
221
- end
222
- alias :__require__ :require
223
- def require ( aString )
224
- @@require_system.require(aString.to_path)
225
- end
226
- alias :__load__ :load
227
- def load ( aString )
228
- @@require_system.load(aString.to_path)
229
- end
230
- end # module ::Kernel
231
- class ::Module
232
- def module_require_system= ( arg )
233
- @@require_system = arg
234
- end
235
- alias :__autoload__ :autoload
236
- def autoload ( aConst, anObject )
237
- @@require_system.autoload(self, aConst, anObject.to_path)
238
- end
239
- # alias :__const_missing__ :const_missing
240
- # def const_missing ( aConst )
241
- # @@require_system.const_missing(self, aConst)
242
- # end
243
- end # module ::Module
244
- undef :enable
245
- def enable
246
- end
247
- end
248
- end
249
-
250
- end # class RequireSystem
251
-
252
-
253
-
254
- test_section __FILE__ do
255
-
256
- class RequireSystemTest < Test::Unit::TestCase
257
-
258
- class MockRequirable < Pathname
259
- @@requires = []
260
- def initialize ( name, url )
261
- @name, @url = name, url
262
- end
263
- def require ( *a )
264
- @url.require
265
- @@requires << @name
266
- end
267
- def self.requires
268
- @@requires
269
- end
270
- def inspect
271
- "#<#{self.class}: url=#@url, name=#@name>"
272
- end
273
- def self.[] ( name, url )
274
- new(name, url)
275
- end
276
- end
277
-
278
- @@save_dirs = $:.dup
279
- @@save_files = $".dup
280
-
281
- def setup
282
- @rs = RequireSystem.new
283
- @test = __FILE__.to_path.dirname.parent.parent + 'test'
284
- @res = @test + 'resources'
285
- @req = @res + 'require'
286
- @s = 'test_require'
287
- @s_dne = 'test_require_dne'
288
- @s_so = 'test_require_so.so'
289
- @s_rb = 'test_require_rb.rb'
290
- @p = @s.to_path
291
- @p_dne = @s_dne.to_path
292
- @p_so = @s_so.to_path
293
- @p_rb = @s_rb.to_path
294
- @ls = [ @s, @s_dne, @s_so, @s_rb ]
295
- @lp = [ @p, @p_dne, @p_rb ] # FIXME @p_so on mac
296
- @l = @ls + @lp
297
- $:.replace @@save_dirs.dup
298
- @mr = MockRequirable
299
- end
300
-
301
- def teardown
302
- $".delete_if { |x| x =~ /test_require/ }
303
- end
304
-
305
- def test_0_initialize
306
- %w[
307
- load require
308
- include_dir include_dirs
309
- loaded required
310
- ].each do |m|
311
- assert_respond_to(@rs, m, m)
312
- end
313
- end
314
-
315
- def assert_search ( inp, ref )
316
- assert_nothing_raised do
317
- @my = inp.expand_path_with($:, RequireSystem::EXTENSIONS)
318
- ref = ref.expand_path.cleanpath unless ref.nil?
319
- assert_equal(ref, @my, inp)
320
- end
321
- unless ref.nil?
322
- assert_kind_of(Pathname, @my)
323
- assert(@my.exist?)
324
- end
325
- end
326
-
327
- def test_1_search
328
- @lp.each { |x| assert_search(x, nil) }
329
- end
330
-
331
- def test_2_include_dir
332
- assert(! @rs.include_dir?(@test))
333
- assert_nothing_raised do
334
- assert_equal(@rs, @rs.include_dir(@test))
335
- end
336
- assert(@rs.include_dir?(@test))
337
- $: << @res.to_s
338
- assert(@rs.include_dir?(@res))
339
- end
340
-
341
- def test_2_search
342
- @rs.include_dir(@req)
343
- @lp.delete(@p_dne)
344
- @lp.each { |x| assert_search(x, @req + x) }
345
- @lp.each { |x| assert_search(@req + x, @req + x) }
346
- assert_search(@p_dne, nil)
347
- end
348
-
349
- def test_load
350
- end
351
-
352
- def assert_require ( aPathname, ref_bool, ref_cst )
353
- $REQUIRE_SYSTEM_TEST_COUNTER = 0
354
- assert_nothing_raised { @my = aPathname.require }
355
- assert_equal(ref_bool, @my)
356
- assert_equal(ref_cst, $REQUIRE_SYSTEM_TEST_COUNTER)
357
- end
358
-
359
- def test_require
360
- @lp.each do |x|
361
- assert_raise(LoadError) { x.require }
362
- end
363
- @rs.include_dir(@req)
364
- @lp.delete(@p_dne)
365
- @lp.each { |x| assert_require(x, true, 1) }
366
- assert_raise(LoadError) { @p_dne.require }
367
- end
368
-
369
- module ::AutoloadTree
370
- end
371
-
372
- def t_e_s_t_autoload # FIXME AUTOLOAD
373
- @rs.include_dir(@res + 'autoload_tree')
374
- [[:A,'A'], [:B,'B'], [:Foo, 'foo/C']].each do |cst,url|
375
- assert_nothing_raised { AutoloadTree.autoload cst, @mr[cst,url] }
376
- end
377
- assert_nothing_raised do
378
- assert(AutoloadTree)
379
- assert_equal('AutoloadTree::A', ::AutoloadTree::A.name)
380
- assert_equal('AutoloadTree::B', ::AutoloadTree::B.name)
381
- assert_equal('AutoloadTree::Foo::C', ::AutoloadTree::Foo::C.name)
382
- end
383
- assert_equal([:A, :B, :Foo], @mr.requires)
384
- end
385
-
386
- end # RequireSystemTest
387
- end
4
+ # Revision:: $Id: require.rb 334 2005-09-04 14:29:40Z ertai $
5
+
6
+ # FIXME This autoload didn't work for these reasons:
7
+ # - |
8
+ # # file1.rb
9
+ # module B
10
+ # class A
11
+ # end
12
+ # end
13
+ #
14
+ # # file2.rb
15
+ # class A # where ::A != B::A
16
+ # end
17
+ #
18
+ # module B
19
+ # autoload :A, 'file1'
20
+ # A # this doesn't work because ::A exists so no const_missing is reached
21
+ # end
22
+ #
23
+ # - |
24
+ # # file1.rb
25
+ # module B
26
+ # class A
27
+ # end
28
+ # end
29
+ #
30
+ # # file2.rb
31
+ # module B
32
+ # autoload :A, 'file1'
33
+ # class ::C
34
+ # A # this doesn't work because A is search in ::C which is not
35
+ # # included in B.
36
+ # end
37
+ # end
38
+ # etc.
39
+ # Const missing was (it's obvious now) a very bad idea to make an autoload.
40
+ # We need to hook a const_get which is call every time.
41
+ module CoreEx
42
+
43
+ module Require
44
+ end # module Require
45
+
46
+ end # module CoreEx
@@ -3,45 +3,56 @@
3
3
  # License:: GNU General Public License (GPL).
4
4
  # Revision:: $Id$
5
5
 
6
- class String
7
-
8
- #
9
- # Provide an helper to cut strings.
10
- #
11
- # Example:
12
- #
13
- # puts "
14
- # | A very complex
15
- # | string
16
- # | with a specific indentation.
17
- # |
18
- # |I prefer that instead of a HERE doc
19
- # | because I keep my indentation.
20
- # |".head_cut!
21
- #
22
- def head_cut! ( sep='\|' )
23
- gsub!(/^\s*#{sep}/, '')
24
- self
25
- end
26
-
27
- def require
28
- to_path.require
29
- end
30
-
31
- def to_path
32
- Pathname.new(self)
33
- end
34
-
35
- def autoload ( aConst )
36
- to_path.autoload(aConst)
37
- end
38
-
39
- # XXX
40
- # Do not implement to_io.
41
- # It breaks File.exists?
42
- # def to_io
43
- # end
44
- # XXX
45
-
46
- end # class String
6
+
7
+ module CoreEx
8
+
9
+ module String
10
+ #
11
+ # Provide an helper to cut strings.
12
+ #
13
+ # Example:
14
+ #
15
+ # puts "
16
+ # | A very complex
17
+ # | string
18
+ # | with a specific indentation.
19
+ # |
20
+ # |I prefer that instead of a HERE doc
21
+ # | because I keep my indentation.
22
+ # |".head_cut!
23
+ #
24
+ def head_cut! ( sep='\|' )
25
+ gsub!(/^\s*#{sep}/, '')
26
+ self
27
+ end
28
+
29
+ def import
30
+ to_path.import
31
+ end
32
+
33
+ def to_path
34
+ ::Pathname.new(self)
35
+ end
36
+
37
+ def rec_fold ( init, &block )
38
+ if include? "\n"
39
+ super
40
+ else
41
+ block[init, self]
42
+ end
43
+ end
44
+
45
+ def width
46
+ size + count("\t") * 7 # TABWIDTH(8) - 1
47
+ end
48
+
49
+ # XXX
50
+ # Do not implement to_io.
51
+ # It breaks File.exists?
52
+ # def to_io
53
+ # end
54
+ # XXX
55
+ end # module String
56
+
57
+ end # module CoreEx
47
58
 
data/lib/core_ex/time.rb CHANGED
@@ -1,65 +1,48 @@
1
1
  # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
2
  # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
3
3
  # License:: GNU General Public License (GPL).
4
- # Revision:: $Id: time.rb 281 2005-06-05 21:39:51Z ertai $
4
+ # Revision:: $Id: time.rb 336 2005-09-06 20:32:49Z ertai $
5
5
 
6
- require 'core_ex'
7
- require 'time'
8
6
 
9
- class Time
7
+ module CoreEx
10
8
 
11
- PRECISION = 1e-016
9
+ module Time
12
10
 
13
- def float_minus ( rhs )
14
- diff = to_f - rhs.to_f
15
- (diff / PRECISION).to_i * PRECISION
16
- end
17
- private :float_minus
18
-
19
-
20
- undef :-
21
- undef :+
22
-
23
-
24
- def - ( rhs )
25
- case rhs
26
- when Time
27
- DTime.new(float_minus(rhs))
28
- when 0
29
- self
30
- when Numeric
31
- Time.at(float_minus(rhs)).utc
32
- when DTime
33
- Time.at(float_minus(rhs)).utc
34
- else
35
- raise TypeError, rhs
11
+ setup do
12
+ alias_method :minus_without_d_time, :-
13
+ remove_method :-
36
14
  end
37
- end
38
-
39
15
 
40
- def + ( rhs )
41
- if rhs.is_a? Numeric or rhs.is_a? DTime
42
- Time.at(to_f + rhs.to_f).utc
43
- else
44
- raise TypeError, rhs
16
+ def - ( rhs )
17
+ diff = minus_without_d_time(rhs)
18
+ (defined? DTime and rhs.is_a? Time)? DTime.new(diff) : diff
45
19
  end
46
- end
47
20
 
21
+ module ClassMethods
48
22
 
49
- def self.diff ( *args, &block )
50
- DTime.diff(*args, &block)
51
- end
23
+ def diff ( *args, &block )
24
+ DTime.diff(*args, &block)
25
+ end
52
26
 
53
- end # class Time
27
+ end # module ClassMethods
54
28
 
29
+ end # module Time
30
+
31
+ end # module CoreEx
55
32
 
56
33
 
57
34
  test_section __FILE__ do
58
35
 
36
+ DTime.import!
37
+
59
38
  class TimeExTest < Test::Unit::TestCase
60
39
 
61
40
  def setup
62
- @t1, @t2 = Time.now, Time.now
41
+ @t1, @t2 = Time.at(1125583814.373), Time.at(1125583801.445)
42
+ end
43
+
44
+ def test_mixed
45
+ assert ::Time.include?(CoreEx::Time)
63
46
  end
64
47
 
65
48
  def test_minus
@@ -83,6 +66,8 @@ test_section __FILE__ do
83
66
  d1 = @t1 - @t2
84
67
  assert_raise(TypeError) { @t1 + @t2 }
85
68
  assert_kind_of(Time, @t1 + d1)
69
+ assert_kind_of(Time, @t2 + d1)
70
+ assert_in_delta(@t1.utc.to_f, (@t2 + d1).to_f, 1e-06)
86
71
  end
87
72
 
88
73
  end # TimeExTest
@@ -0,0 +1,68 @@
1
+ # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
2
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
3
+ # License:: Gnu General Public License.
4
+ # Revision:: $Id: try_dup.rb 334 2005-09-04 14:29:40Z ertai $
5
+
6
+
7
+ module CoreEx
8
+
9
+ # Some objects are dupable, some are not. So we define a version of
10
+ # dup (called try_dup) that returns self on the handful of classes
11
+ # that are not dupable. (imported from rake (rake_dup))
12
+ module TryDup
13
+
14
+ # Duplicate an object if it can be duplicated. If it can not be
15
+ # cloned or duplicated, then just return the original object.
16
+ def try_dup
17
+ self
18
+ end
19
+
20
+ end # module TryDup
21
+
22
+ end # module CoreEx
23
+
24
+
25
+ class Object
26
+
27
+ # Duplicate an object if it can be duplicated. If it can not be
28
+ # cloned or duplicated, then just return the original object.
29
+ def try_dup
30
+ dup
31
+ end
32
+
33
+ end # class Object
34
+
35
+
36
+ [NilClass, FalseClass, TrueClass, Fixnum, Symbol, Fixnum, Float].each do |aClass|
37
+ aClass.class_eval do
38
+ include CoreEx::TryDup
39
+ end
40
+ end
41
+
42
+
43
+
44
+ test_section __FILE__ do
45
+ class TestTryDup < ::Test::Unit::TestCase
46
+
47
+ def setup
48
+ @s = "a simple string"
49
+ end
50
+
51
+ def teardown
52
+ end
53
+
54
+ def test_simple
55
+ assert_nothing_raised do
56
+ assert_equal nil, nil.try_dup
57
+ assert_equal true, true.try_dup
58
+ assert_equal false, false.try_dup
59
+ assert_equal 4, 4.try_dup
60
+ assert_equal 5.5, 5.5.try_dup
61
+ assert_equal :foo, :foo.try_dup
62
+ assert_equal @s, @s.try_dup
63
+ assert_not_equal @s.object_id, @s.try_dup
64
+ end
65
+ end
66
+
67
+ end # class TestTryDup
68
+ end