facets 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/HISTORY.rdoc +135 -294
  2. data/MANIFEST +40 -91
  3. data/NOTES +1 -1
  4. data/README.rdoc +10 -8
  5. data/Rakefile +11 -34
  6. data/demo/{hook.rd → hook.rdoc} +2 -0
  7. data/demo/{scenario_require.rd → scenario_require.rdoc} +3 -0
  8. data/lib/core/facets-live.rb +7 -5
  9. data/lib/core/facets.rb +379 -359
  10. data/lib/core/facets/array/conjoin.rb +2 -2
  11. data/lib/core/facets/array/pad.rb +1 -1
  12. data/lib/core/facets/array/recursively.rb +2 -2
  13. data/lib/core/facets/array/splice.rb +1 -1
  14. data/lib/core/facets/binding/caller.rb +2 -4
  15. data/lib/core/facets/comparable/comparable.rb +2 -2
  16. data/lib/core/facets/dir/ascend.rb +3 -0
  17. data/lib/core/facets/dir/recurse.rb +4 -0
  18. data/lib/core/facets/duplicable.rb +6 -8
  19. data/lib/core/facets/enumerable/count.rb +22 -13
  20. data/lib/core/facets/enumerable/map_detect.rb +28 -0
  21. data/lib/core/facets/enumerable/mash.rb +13 -5
  22. data/lib/core/facets/enumerable/per.rb +3 -1
  23. data/lib/core/facets/hash/count.rb +14 -0
  24. data/lib/core/facets/hash/data.rb +14 -0
  25. data/lib/core/facets/kernel/__method__.rb +1 -1
  26. data/lib/core/facets/kernel/d.rb +9 -8
  27. data/lib/core/facets/kernel/eigenclass.rb +20 -0
  28. data/lib/core/facets/kernel/extend.rb +10 -0
  29. data/lib/core/facets/kernel/instance_class.rb +1 -0
  30. data/lib/core/facets/kernel/instance_variables.rb +6 -6
  31. data/lib/core/facets/kernel/meta_alias.rb +18 -0
  32. data/lib/core/facets/kernel/meta_class.rb +17 -0
  33. data/lib/core/facets/kernel/meta_def.rb +18 -0
  34. data/lib/core/facets/kernel/meta_eval.rb +18 -0
  35. data/lib/core/facets/kernel/object_hexid.rb +21 -6
  36. data/lib/core/facets/kernel/object_state.rb +4 -2
  37. data/lib/core/facets/kernel/populate.rb +3 -1
  38. data/lib/core/facets/kernel/with.rb +1 -1
  39. data/lib/core/facets/metaid.rb +6 -93
  40. data/lib/core/facets/module/class_def.rb +2 -0
  41. data/lib/core/facets/module/extend.rb +10 -11
  42. data/lib/core/facets/module/is.rb +5 -5
  43. data/lib/core/facets/module/module_def.rb +31 -0
  44. data/lib/core/facets/string/camelcase.rb +14 -12
  45. data/lib/core/facets/string/cleanlines.rb +35 -0
  46. data/lib/core/facets/string/edit_distance.rb +62 -0
  47. data/lib/core/facets/string/indent.rb +86 -4
  48. data/lib/core/facets/string/index_all.rb +24 -0
  49. data/lib/core/facets/string/lines.rb +3 -6
  50. data/lib/core/facets/string/margin.rb +2 -1
  51. data/lib/core/facets/string/newlines.rb +35 -0
  52. data/lib/core/facets/string/op_div.rb +14 -0
  53. data/lib/core/facets/string/range.rb +2 -22
  54. data/lib/core/facets/string/range_all.rb +1 -0
  55. data/lib/core/facets/string/range_of_line.rb +1 -0
  56. data/lib/core/facets/string/similarity.rb +92 -0
  57. data/lib/core/facets/string/start_with.rb +6 -6
  58. data/lib/core/facets/string/titlecase.rb +1 -1
  59. data/lib/more/facets/basicobject.rb +16 -15
  60. data/lib/more/facets/blankslate.rb +8 -0
  61. data/lib/more/facets/class_extend.rb +126 -1
  62. data/lib/more/facets/continuation.rb +53 -54
  63. data/lib/more/facets/dictionary.rb +9 -63
  64. data/lib/more/facets/erb.rb +63 -0
  65. data/lib/more/facets/filelist.rb +5 -5
  66. data/lib/more/facets/hashbuilder.rb +101 -0
  67. data/lib/more/facets/inheritor.rb +36 -45
  68. data/lib/more/facets/ini.rb +267 -0
  69. data/lib/more/facets/instance_eval.rb +4 -4
  70. data/lib/more/facets/ioredirect.rb +7 -60
  71. data/lib/more/facets/linkedlist.rb +195 -0
  72. data/lib/more/facets/matcher.rb +140 -0
  73. data/lib/more/facets/memoizer.rb +64 -0
  74. data/lib/more/facets/methodspace.rb +9 -4
  75. data/lib/more/facets/module/class_extend.rb +2 -121
  76. data/lib/more/facets/ostruct.rb +9 -9
  77. data/lib/more/facets/pathlist.rb +1 -9
  78. data/lib/more/facets/pathname.rb +11 -4
  79. data/lib/more/facets/plugin_manager.rb +50 -0
  80. data/lib/more/facets/random.rb +25 -3
  81. data/lib/more/facets/roman.rb +174 -0
  82. data/lib/more/facets/semaphore.rb +92 -0
  83. data/lib/more/facets/shellwords.rb +21 -48
  84. data/lib/more/facets/succ.rb +1 -1
  85. data/meta/{modified → released} +0 -0
  86. data/meta/repository +1 -0
  87. data/meta/suite +1 -0
  88. data/meta/version +1 -1
  89. data/script/conflicts +63 -0
  90. data/script/methods +49 -0
  91. data/test/core/binding/test_caller.rb +11 -4
  92. data/test/core/enumerable/test_count.rb +19 -10
  93. data/test/core/enumerable/test_map_detect.rb +75 -0
  94. data/test/core/enumerable/test_take.rb +1 -1
  95. data/test/core/kernel/test_object_hexid.rb +2 -1
  96. data/test/core/proc/test_to_method.rb +1 -1
  97. data/test/core/string/test_cleanlines.rb +11 -0
  98. data/test/core/string/test_indent.rb +66 -4
  99. data/test/core/string/test_lines.rb +2 -1
  100. data/test/core/string/test_newlines.rb +13 -0
  101. data/test/core/time/test_change.rb +1 -1
  102. data/test/core/time/test_stamp.rb +4 -7
  103. data/test/core/unboundmethod/test_name.rb +1 -1
  104. data/test/more/test_basicobject.rb +1 -20
  105. data/test/more/test_class_extend.rb +7 -0
  106. data/test/more/test_continuation.rb +8 -6
  107. data/test/more/test_inheritor.rb +12 -6
  108. data/test/more/test_random.rb +19 -10
  109. data/test/more/test_shellwords.rb +33 -0
  110. metadata +60 -31
  111. data/TODO +0 -5
  112. data/doc/README.core +0 -102
  113. data/doc/README.more +0 -61
  114. data/doc/manual/about.rb +0 -47
  115. data/doc/manual/annotations.rdoc +0 -60
  116. data/doc/manual/associations.rdoc +0 -55
  117. data/doc/manual/blockups.rdoc +0 -101
  118. data/doc/manual/capsule.rdoc +0 -34
  119. data/doc/manual/command.rdoc +0 -177
  120. data/doc/manual/core.rdoc +0 -37
  121. data/doc/manual/faq.rdoc +0 -32
  122. data/doc/manual/typecast.html +0 -112
  123. data/lib/more/facets/capsule.rb +0 -258
  124. data/lib/more/facets/coroutine.rb +0 -159
  125. data/lib/more/facets/enumerablepass.rb +0 -3
  126. data/lib/more/facets/fileable.rb +0 -162
  127. data/lib/more/facets/progressbar.rb +0 -253
  128. data/lib/more/facets/recorder.rb +0 -108
  129. data/meta/releases +0 -14
  130. data/test/more/test_coroutine.rb +0 -46
@@ -0,0 +1,140 @@
1
+ #= Matcher
2
+ #
3
+ # Matcher derives from Ruby Quiz #103, the DictionaryMatcher quiz.
4
+ #
5
+ class Matcher
6
+ attr_reader :word_count
7
+
8
+ #Contains the index matched, and the word matched
9
+ class MatchData < Struct.new(:index,:match)
10
+ def inspect
11
+ "#{match.inspect}@#{index}"
12
+ end
13
+ end
14
+
15
+ def inspect
16
+ to_s
17
+ end
18
+
19
+ #Create a DictionaryMatcher with no words in it
20
+ def initialize
21
+ @trie = {}
22
+ @word_count = 0
23
+ end
24
+
25
+ #Add a word to the DictionaryMatcher
26
+ def add(word)
27
+ @word_count += 1
28
+ container = @trie
29
+ containers=[]
30
+
31
+ i=0
32
+ word.each_byte do |b|
33
+ container[b] = {} unless container.has_key? b
34
+ container[:depth]=i
35
+ containers << container
36
+ container = container[b]
37
+ i+=1
38
+ end
39
+ containers << container
40
+
41
+ container[0] = true # Mark end of word
42
+ container[:depth]=i
43
+
44
+ ff=compute_failure_function word
45
+ ff.zip(containers).each do |pointto,container|
46
+ container[:failure]=containers[pointto] if pointto
47
+ end
48
+
49
+ self
50
+
51
+ end
52
+
53
+ alias << add
54
+
55
+ def compute_failure_function p
56
+ m=p.size
57
+ pi=[nil,0]
58
+ k=0
59
+ 2.upto m do |q|
60
+ k=pi[k] while k>0 and p[k] != p[q-1]
61
+ k=k+1 if p[k]==p[q-1]
62
+ pi[q]=k
63
+ end
64
+ pi
65
+ end
66
+ private :compute_failure_function
67
+
68
+ #Determine whether +string+ was previously <tt>add</tt>ed to the
69
+ #Trie.
70
+ def include?(word)
71
+ container = @trie
72
+ word.each_byte do |b|
73
+ break unless container.has_key? b
74
+ container = container[b]
75
+ end
76
+ container[0]
77
+ end
78
+
79
+ #Determines whether one of the words in the DictionaryMatcher is a
80
+ #substring of
81
+ #+string+. Returns the index of the match if found, +nil+ if not
82
+ #found.
83
+ def =~ text
84
+ internal_match(text){|md| return md.index}
85
+ nil
86
+ end
87
+
88
+ #Determine whether one of the words in the DictionaryMatcher is a
89
+ #substring of
90
+ #+string+. Returns a DictionaryMatcher::MatchData object if found,
91
+ #+nil+ if not #found.
92
+ def match text
93
+ internal_match(text){|md| return md}
94
+ nil
95
+ end
96
+
97
+ def internal_match string
98
+ node=@trie
99
+ pos=0
100
+ string.each_byte do |b|
101
+ advance=false
102
+ until advance
103
+ nextnode=node[b]
104
+ if not nextnode
105
+ if node[:failure]
106
+ node=node[:failure]
107
+ else
108
+ advance=true
109
+ end
110
+ elsif nextnode[0]
111
+ yield MatchData.new(pos, string[pos+1-nextnode[:depth],nextnode[:depth]])
112
+ advance=true
113
+ node=@trie
114
+ else
115
+ advance=true
116
+ node=nextnode
117
+ end
118
+ pos+=1
119
+ end
120
+ end
121
+ end
122
+ private :internal_match
123
+
124
+ #Scans +string+ for all occurrances of strings in the
125
+ #DictionaryMatcher.
126
+ #Overlapping matches are skipped (only the first one is yielded), and
127
+ #when some strings in the
128
+ #DictionaryMatcher are substrings of others, only the shortest match
129
+ #at a given position is found.
130
+ def scan(text, &block)
131
+ matches=[]
132
+ block= lambda{ |md| matches << md } unless block
133
+ internal_match(text,&block)
134
+ matches
135
+ end
136
+
137
+ #Case equality. Similar to =~.
138
+ alias_method :===, :=~
139
+ end
140
+
@@ -0,0 +1,64 @@
1
+ # Memoizer
2
+ #
3
+ # Copyright (c) 2006 Erik Veenstra
4
+ #
5
+ # See http://javathink.blogspot.com/2008/09/what-is-memoizer-and-why-should-you.html
6
+
7
+ # Memoizer wraps objects to provide cached method calls.
8
+ #
9
+ # class X
10
+ # def initialize ; @tick = 0 ; end
11
+ # def tick; @tick + 1; end
12
+ # def memo; @memo ||= Memoizer.new(self) ; end
13
+ # end
14
+ #
15
+ # x = X.new
16
+ # x.tick #=> 1
17
+ # x.memo.tick #=> 2
18
+ # x.tick #=> 3
19
+ # x.memo.tick #=> 2
20
+ # x.tick #=> 4
21
+ # x.memo.tick #=> 2
22
+ #
23
+ # You can also use to cache collections of objects to gain code speed ups.
24
+ #
25
+ # points = points.collect{|point| Memoizer.cache(point)}
26
+ #
27
+ # After our algorithm has finished using points, we want to get rid of
28
+ # these Memoizer objects. That's easy:
29
+ #
30
+ # points = points.collect{|point| point.__self__ }
31
+ #
32
+ # Or if you prefer (it is ever so slightly safer):
33
+ #
34
+ # points = points.collect{|point| Memoizer.uncache(point)}
35
+ #
36
+ class Memoizer
37
+
38
+ #private :class, :clone, :display, :type, :method, :to_a, :to_s
39
+ private *instance_methods(true).select{ |m| m.to_s !~ /^__/ }
40
+
41
+ def initialize(object)
42
+ @self = object
43
+ @cache = {}
44
+ end
45
+
46
+ def __self__ ; @self ; end
47
+
48
+ # Not thread-safe! Speed is important in caches... ;]
49
+ def method_missing(method_name, *args, &block)
50
+ @cache[[method_name, args, block]] ||= @self.__send__(method_name, *args, &block)
51
+ end
52
+
53
+ #def self; @self; end
54
+
55
+ def self.cache(object)
56
+ new(object)
57
+ end
58
+
59
+ def self.uncache(cached_object)
60
+ cached_object.instance_variable_get('@self')
61
+ end
62
+
63
+ end
64
+
@@ -70,11 +70,16 @@ class Module
70
70
  methods = {}
71
71
  mod.instance_methods(false).each do |m|
72
72
  methods[m.to_sym] = mod.instance_method(m)
73
- mod.instance_eval do
74
- define_method(m) do
75
- super
73
+ mod.module_eval %{
74
+ def #{m}(*a,&b)
75
+ super(*a,&b)
76
76
  end
77
- end
77
+ }
78
+ #mod.instance_eval do
79
+ #define_method(m)
80
+ # super
81
+ #end
82
+ #end
78
83
  end
79
84
 
80
85
  # Add a method for the namespace that delegates
@@ -1,122 +1,3 @@
1
- # = Class Extension
2
- #
3
- # Normally when including modules, class/module methods are not
4
- # extended. To achieve this behavior requires some clever
5
- # Ruby Karate. Instead class_extension provides an easy to use
6
- # and clean solution. Simply place the extending class methods
7
- # in a block of the special module method #class_extension.
8
- #
9
- # module Mix
10
- # def inst_meth
11
- # puts 'inst_meth'
12
- # end
13
- #
14
- # class_extend do
15
- # def class_meth
16
- # "Class Method!"
17
- # end
18
- # end
19
- # end
20
- #
21
- # class X
22
- # include Mix
23
- # end
24
- #
25
- # X.class_meth #=> "Class Method!"
26
- #
27
- # == History
28
- #
29
- # Thanks to Trans, Nobu and Ulysses for their original on this concept.
30
- #
31
- # == Authors
32
- #
33
- # * Daniel Schierbeck
34
- # * Thomas Sawyer
35
- # * Nobu Nakada
36
- # * Ulysses
37
- #
38
- # == Copying
39
- #
40
- # Copyright (c) 2006 Daniel Schierbeck
41
- #
42
- # Ruby License
43
- #
44
- # This module is free software. You may use, modify, and/or redistribute this
45
- # software under the same terms as Ruby.
46
- #
47
- # This program is distributed in the hope that it will be useful, but WITHOUT
48
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
49
- # FOR A PARTICULAR PURPOSE.
50
-
51
- #
52
- class Module
53
-
54
- alias_method :append_features_without_class_extension, :append_features
55
-
56
- # Normally when including modules, class/module methods are not
57
- # extended. To achieve this behavior requires some clever
58
- # Ruby Karate. Instead class_extension provides an easy to use
59
- # and clean solution. Simply place the extending class methods
60
- # in a block of the special module method #class_extension.
61
- #
62
- # module Mix
63
- # def inst_meth
64
- # puts 'inst_meth'
65
- # end
66
- #
67
- # class_extend do
68
- # def class_meth
69
- # "Class Method!"
70
- # end
71
- # end
72
- # end
73
- #
74
- # class X
75
- # include Mix
76
- # end
77
- #
78
- # X.class_meth #=> "Class Method!"
79
- #
80
- # NOTE: This old #class_extension version of this method
81
- # did not extend the containing class automatically --it had
82
- # to be done by hand. With #class_extend, that is no longer
83
- # the case.
84
- #
85
- def class_extend(*mods, &block)
86
- @class_extension ||= Module.new do
87
- def self.append_features(mod)
88
- append_features_without_class_extension(mod)
89
- end
90
- end
91
- @class_extension.__send__(:include, *mods)
92
- @class_extension.module_eval(&block) if block_given?
93
- extend(@class_extension) # extend this module too
94
- @class_extension
95
- end
96
-
97
- # TODO: DEPRECATE
98
- alias_method :class_extension, :class_extend
99
-
100
- #private :class_extend
101
-
102
- # Override +append_features+ to handle class-inheritable extensions.
103
- def append_features(mod)
104
- append_features_without_class_extension(mod)
105
- mod.extend(class_extend)
106
- if mod.instance_of? Module
107
- mod.__send__(:class_extend).__send__(:include, class_extend)
108
- end
109
- end
110
-
111
- end
112
-
113
- class Class
114
- # For Class, #class_extend is the same as class_eval.
115
- # The alternative is to "undef_method :class_extend",
116
- # but this seems uneccessarily limited.
117
- #
118
- def class_extend(&blk)
119
- class_eval(&blk)
120
- end
121
- end
1
+ warn "use 'facets/class_extend' for future versions"
2
+ require 'facets/class_extend'
122
3
 
@@ -34,13 +34,13 @@ class OpenStruct
34
34
  # o.name = 'John Smith'
35
35
  # o.gender = :M
36
36
  # o.age = 71
37
- # end
37
+ # end
38
38
  #
39
39
  # You can still provide a hash for initialization purposes, and even combine
40
40
  # the two approaches if you wish.
41
41
  #
42
42
  # person = OpenStruct.new(:name => 'John Smith', :age => 31) do |p|
43
- # p.gender = :M
43
+ # p.gender = :M
44
44
  # end
45
45
  #
46
46
  # Alternatively you can provide a default block:
@@ -201,13 +201,6 @@ class Hash
201
201
  OpenStruct.new(self)
202
202
  end
203
203
 
204
- # CREDIT Alison Rowland, Jamie Macey, Mat Schaffer
205
-
206
- #--
207
- # Special thanks to Alison Rowland, Jamie Macey and Mat Schaffer
208
- # for inspiring recursive improvements.
209
- #++
210
-
211
204
  # Like to_ostruct but recusively objectifies all hash elements as well.
212
205
  #
213
206
  # o = { 'a' => { 'b' => 1 } }.to_ostruct_recurse
@@ -223,6 +216,8 @@ class Hash
223
216
  # o = h.to_ostruct_recurse( { h['a'] => h['a'] } )
224
217
  # o.a['b'] #=> 1
225
218
  #
219
+ # CREDIT: Alison Rowland, Jamie Macey, Mat Schaffer
220
+
226
221
  def to_ostruct_recurse(exclude={})
227
222
  return exclude[self] if exclude.key?( self )
228
223
  o = exclude[self] = OpenStruct.new
@@ -233,5 +228,10 @@ class Hash
233
228
  o.__update__(h)
234
229
  end
235
230
 
231
+ #--
232
+ # Special thanks to Alison Rowland, Jamie Macey and Mat Schaffer
233
+ # for inspiring recursive improvements.
234
+ #++
235
+
236
236
  end
237
237
 
@@ -89,16 +89,8 @@ $:.find_ext = 'rb'
89
89
  # Doesn't work
90
90
  #ENV['PATH'] = PathList.new(ENV['PATH'])
91
91
 
92
- #++
93
92
 
94
-
95
- # _____ _
96
- # |_ _|__ ___| |_
97
- # | |/ _ \/ __| __|
98
- # | | __/\__ \ |_
99
- # |_|\___||___/\__|
100
- #
101
- =begin #testing
93
+ =begin test
102
94
 
103
95
  require 'test/unit'
104
96
 
@@ -129,7 +129,7 @@ class Pathname
129
129
  flags = 0
130
130
  opts.each do |opt|
131
131
  case opt when Symbol, String
132
- flags += File.const_get("FNM_#{opt}".upcase)
132
+ flags += ::File.const_get("FNM_#{opt}".upcase)
133
133
  else
134
134
  flags += opt
135
135
  end
@@ -156,10 +156,17 @@ class Pathname
156
156
  Dir.glob(::File.join(self.to_s, '*')).empty?
157
157
  end
158
158
 
159
- end
159
+ #
160
+ def uptodate?(*sources)
161
+ ::FileUtils.uptodate?(to_s, sources.flatten)
162
+ end
160
163
 
161
- # Constant alias of Pathname (short is better!)
162
- Path = Pathname
164
+ #
165
+ def outofdate?(*sources)
166
+ ::FileUtils.outofdate?(to_s, sources.flatten)
167
+ end
168
+
169
+ end
163
170
 
164
171
  class NilClass
165
172
  # Provide platform dependent null path.