facets 2.7.0 → 2.8.0

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 (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,50 @@
1
+ # = Plugin Manger
2
+ #
3
+ # Find plugins easily.
4
+ #
5
+ # NOTE: This is likely to be replaced with
6
+ # a more generic means of finding libraries.
7
+ #
8
+ module PluginManager
9
+ extend self
10
+
11
+ # Find plugins, searching through standard $LOAD_PATH,
12
+ # Roll Libraries and RubyGems.
13
+ #
14
+ # +match+ is a file glob for finding plugins.
15
+ #
16
+ # PluginManager.find('syckles/*')
17
+ #
18
+ def find(match)
19
+ plugins = []
20
+ # Standard $LOAD_PATH
21
+ $LOAD_PATH.uniq.each do |path|
22
+ list = Dir.glob(File.join(path, match))
23
+ #dirs = dirs.select{ |d| File.directory?(d) }
24
+ list = list.map{ |d| d.chomp('/') }
25
+ plugins.concat(list)
26
+ end
27
+ # ROLL (load latest versions only)
28
+ if defined?(::Roll)
29
+ ::Roll::Library.ledger.each do |name, lib|
30
+ lib = lib.sort.first if Array===lib
31
+ lib.load_path.each do |path|
32
+ find = File.join(lib.location, path, match)
33
+ list = Dir.glob(find)
34
+ list = list.map{ |d| d.chomp('/') }
35
+ plugins.concat(list)
36
+ end
37
+ end
38
+ end
39
+ # RubyGems (load latest versions only)
40
+ if defined?(::Gem)
41
+ Gem.latest_load_paths do |path|
42
+ list = Dir.glob(File.join(path, match))
43
+ list = list.map{ |d| d.chomp('/') }
44
+ plugins.concat(list)
45
+ end
46
+ end
47
+ plugins
48
+ end
49
+
50
+ end
@@ -2,9 +2,9 @@
2
2
  #
3
3
  # Randomization core extension methods.
4
4
  #
5
- # This library extends Object, Array, String and Hash with randomization
5
+ # This library extends Object, Array, String, Hash, and Range with randomization
6
6
  # methods. Most of the methods are of one of two kinds. Either they "pick"
7
- # a random element from the reciever or they randomly "shuffle" the reciever.
7
+ # a random element from the reciever or they randomly "shuffle" the receiver.
8
8
  #
9
9
  # The most common example is Array#shuffle, which simply randmomizes the
10
10
  # order of an array's elements.
@@ -66,6 +66,8 @@ module Random
66
66
  def self.append_features(mod)
67
67
  if mod == ::Object
68
68
  mod.send(:include, Random::Object)
69
+ elsif mod == ::Range
70
+ mod.send(:include, Random::Range)
69
71
  elsif mod == ::Array
70
72
  mod.send(:include, Random::Array)
71
73
  elsif mod == ::Hash
@@ -97,9 +99,25 @@ module Random
97
99
 
98
100
  #
99
101
 
102
+ module Range
103
+
104
+ # Return a random element from the range.
105
+ #
106
+ # (1..4).at_rand #=> 2
107
+ # (1..4).at_rand #=> 4
108
+ #
109
+ def at_rand
110
+ array = to_a
111
+ array.at(Random.number(array.size))
112
+ end
113
+
114
+ end
115
+
116
+ #
117
+
100
118
  module Array
101
119
 
102
- # Return a random element of the array.
120
+ # Return a random element from the array.
103
121
  #
104
122
  # [1, 2, 3, 4].at_rand #=> 2
105
123
  # [1, 2, 3, 4].at_rand #=> 4
@@ -437,6 +455,10 @@ class Object
437
455
  include Random
438
456
  end
439
457
 
458
+ class Range
459
+ include Random
460
+ end
461
+
440
462
  class Array
441
463
  include Random
442
464
  end
@@ -0,0 +1,174 @@
1
+ # = TITLE:
2
+ # Roman Numerals
3
+ #
4
+ # = SYNOPSIS:
5
+ # Generates roman numerals from integers and vice-versa.
6
+ #
7
+ # = NOTES:
8
+ # A response to Ruby Quiz of the Week #22 - Roman Numerals [ruby-talk:132925]
9
+ #
10
+ # = AUTHORS:
11
+ # - Dave Burt <dave at burt.id.au>
12
+ # - Trans
13
+
14
+ module English #:nodoc:
15
+
16
+ # Contains methods to convert integers to roman numeral strings and vice-versa.
17
+
18
+ module RomanNumerals
19
+
20
+ # The largest integer representable as a roman
21
+ # numerable by this module.
22
+
23
+ MAX = 3999
24
+
25
+ # Stolen from O'Reilly's Perl Cookbook 6.23. Regular Expression Grabbag.
26
+
27
+ REGEXP = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i
28
+
29
+ #
30
+
31
+ SYMBOLS = [ "M", "D", "C", "L", "X", "V", "I" ]
32
+ NUMBERS = [ 1000, 500, 100, 50, 10, 5, 1 ]
33
+
34
+
35
+ # Maps roman numeral digits to their integer values.
36
+ # {
37
+ # 'I' => 1,
38
+ # 'V' => 5,
39
+ # 'X' => 10,
40
+ # 'L' => 50,
41
+ # 'C' => 100,
42
+ # 'D' => 500,
43
+ # 'M' => 1000,
44
+ # }
45
+
46
+ TABLE = Hash[*SYMBOLS.zip(NUMBERS).flatten]
47
+
48
+ #
49
+
50
+ PAIR_SYMBOLS = [ "CM", "CD", "XC", "XL", "IX", "IV", "I" ]
51
+ PAIR_NUMBERS = [ 900, 400, 90, 40, 9, 4, 1 ]
52
+
53
+ # {
54
+ # 'CM' => 900,
55
+ # 'CD' => 400,
56
+ # 'XC' => 90,
57
+ # 'XL' => 40,
58
+ # 'IX' => 9,
59
+ # 'IV' => 4
60
+ # }
61
+
62
+ PAIR_TABLE = Hash[*PAIR_SYMBOLS.zip(PAIR_NUMBERS).flatten]
63
+
64
+ #
65
+
66
+ LOOKUP = TABLE.invert.merge(PAIR_TABLE.invert)
67
+
68
+
69
+ class << self
70
+
71
+ # Converts +integer+ to a roman numeral.
72
+
73
+ def from_integer(integer)
74
+ return nil if integer < 0 || integer > MAX
75
+
76
+ r = integer # remainder
77
+ y = '' # result
78
+
79
+ NUMBERS.each do |n|
80
+ while r >= n
81
+ r -= n
82
+ y += LOOKUP[n]
83
+ end
84
+ break if r <= 0
85
+ end
86
+
87
+ return y
88
+ end
89
+
90
+ alias_method :roman, :from_integer
91
+
92
+ # Converts +roman_string+, a roman numeral, to an integer
93
+
94
+ def to_integer(roman_string)
95
+ return nil unless roman_string.is_roman_numeral?
96
+
97
+ l = nil # last
98
+ i = 0 # integer result
99
+
100
+ c = roman_string.to_s.upcase.split(//).reverse
101
+
102
+ c.each do |d|
103
+ if v = TABLE[d]
104
+ if l && l > v
105
+ i -= v
106
+ else
107
+ i += v
108
+ end
109
+ l = v
110
+ end
111
+ end
112
+
113
+ return i
114
+ end
115
+
116
+ alias_method :arabic, :to_integer
117
+
118
+ # Returns true iif +string+ is a roman numeral.
119
+
120
+ def is_roman_numeral?(string)
121
+ REGEXP =~ string
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ end # module English
129
+
130
+
131
+ class Integer
132
+
133
+ def roman
134
+ English::RomanNumerals.roman(self) || ''
135
+ end
136
+
137
+ # Converts this integer to a roman numeral.
138
+
139
+ def to_s_roman
140
+ English::RomanNumerals.from_integer(self) || ''
141
+ end
142
+
143
+ end
144
+
145
+
146
+ class String
147
+
148
+ # Considers string a roman numeral numeral,
149
+ # and converts it to the corresponding integer.
150
+
151
+ def to_i_roman
152
+ English::RomanNumerals.to_integer(self)
153
+ end
154
+
155
+ # Returns true iif the subject is a roman numeral.
156
+
157
+ def is_roman_numeral?
158
+ English::RomanNumerals.is_roman_numeral?(self)
159
+ end
160
+
161
+ end
162
+
163
+
164
+ # # Quiz solution: filter that swaps roman and arabic numbers
165
+ # if __FILE__ == $0
166
+ # ARGF.each do |line|
167
+ # line.chomp!
168
+ # if line.is_roman_numeral?
169
+ # puts line.to_i_roman
170
+ # else
171
+ # puts line.to_i.to_s_roman
172
+ # end
173
+ # end
174
+ # end
@@ -0,0 +1,92 @@
1
+ # = Semaphore
2
+ #
3
+ # Technically a semaphore is simply an integer variable which
4
+ # has an execution queue associated with it.
5
+ #
6
+ # == Authors
7
+ #
8
+ # * Fukumoto
9
+ #
10
+ # = Copying
11
+ #
12
+ # Copyright (c) 2005 Fukumoto
13
+ #
14
+ # Ruby License
15
+ #
16
+ # This module is free software. You may use, modify, and/or redistribute this
17
+ # software under the same terms as Ruby.
18
+ #
19
+ # This program is distributed in the hope that it will be useful, but WITHOUT
20
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21
+ # FOR A PARTICULAR PURPOSE.
22
+
23
+
24
+ # = Semaphore
25
+ #
26
+ # Technically a semaphore is simply an integer variable which
27
+ # has an execution queue associated with it.
28
+ #
29
+ class Semaphore
30
+
31
+ def initialize(initvalue = 0)
32
+ @counter = initvalue
33
+ @waiting_list = []
34
+ end
35
+
36
+ def wait
37
+ Thread.critical = true
38
+ if (@counter -= 1) < 0
39
+ @waiting_list.push(Thread.current)
40
+ Thread.stop
41
+ end
42
+ self
43
+ ensure
44
+ Thread.critical = false
45
+ end
46
+
47
+ def signal
48
+ Thread.critical = true
49
+ begin
50
+ if (@counter += 1) <= 0
51
+ t = @waiting_list.shift
52
+ t.wakeup if t
53
+ end
54
+ rescue ThreadError
55
+ retry
56
+ end
57
+ self
58
+ ensure
59
+ Thread.critical = false
60
+ end
61
+
62
+ alias_method( :down, :wait )
63
+ alias_method( :up, :signal )
64
+ alias_method( :p, :wait )
65
+ alias_method( :v, :signal )
66
+
67
+ def exclusive
68
+ wait
69
+ yield
70
+ ensure
71
+ signal
72
+ end
73
+
74
+ alias_method( :synchronize, :exclusive )
75
+
76
+ end
77
+
78
+
79
+ # _____ _
80
+ # |_ _|__ ___| |_
81
+ # | |/ _ \/ __| __|
82
+ # | | __/\__ \ |_
83
+ # |_|\___||___/\__|
84
+ #
85
+
86
+ # TODO
87
+
88
+ =begin #test
89
+
90
+ require 'test/unit'
91
+
92
+ =end
@@ -1,24 +1,3 @@
1
- # = Shellwords Extended
2
- #
3
- # Adds extensions to Shellwords, namely #escape.
4
- #
5
- # == Authors
6
- #
7
- # * Thomas Sawuer
8
- #
9
- # == Copying
10
- #
11
- # Copyright (c) 2007 Thomas Sawyer
12
- #
13
- # Ruby License
14
- #
15
- # This module is free software. You may use, modify, and/or redistribute this
16
- # software under the same terms as Ruby.
17
- #
18
- # This program is distributed in the hope that it will be useful, but WITHOUT
19
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20
- # FOR A PARTICULAR PURPOSE.
21
-
22
1
  require 'shellwords'
23
2
 
24
3
  module Shellwords
@@ -34,56 +13,50 @@ module Shellwords
34
13
 
35
14
  end
36
15
 
37
-
38
16
  class Array
39
17
 
40
18
  # Convert an array into command line parameters.
41
19
  # The array is accepted in the format of Ruby
42
20
  # method arguments --ie. [arg1, arg2, ..., hash]
43
-
44
- def to_shellwords
45
- flags = (Hash===last ? pop : {})
46
- flags = flags.to_shellwords
47
- flags + ' ' + self #join(" ")
21
+ #
22
+ def shellwords
23
+ opts, args = *flatten.partition{ |e| Hash === e }
24
+ opts = opts.inject({}){ |m,h| m.update(h); m }
25
+ opts.shellwords + args
48
26
  end
49
27
 
50
- def to_shell
51
- to_shellwords.join(' ')
28
+ def shelljoin
29
+ Shellwords.shelljoin(shellwords)
52
30
  end
53
31
 
54
- # Original name.
55
- alias_method :to_console, :to_shell
56
32
  end
57
33
 
58
-
59
34
  class Hash
60
35
 
61
- # Convert an array into command line parameters.
62
- # The array is accepted in the format of Ruby
63
- # method arguments --ie. [arg1, arg2, ..., hash]
64
-
65
- def to_shellwords
66
- flags = collect do |f,v|
36
+ #
37
+ def shellwords
38
+ argv = []
39
+ each do |f,v|
67
40
  m = f.to_s.size == 1 ? '-' : '--'
68
41
  case v
42
+ when false, nil
69
43
  when Array
70
- v.collect{ |e| "#{m}#{f}='#{e}'" }.join(' ')
44
+ v.each do |e|
45
+ argv << %[#{m}#{f}="#{e}"]
46
+ end
71
47
  when true
72
- "#{m}#{f}"
73
- when false, nil
74
- ''
48
+ argv << %[#{m}#{f}]
75
49
  else
76
- "#{m}#{f}='#{v}'"
50
+ argv << %[#{m}#{f}="#{v}"]
77
51
  end
78
52
  end
79
- flags #.join(" ")
53
+ argv
80
54
  end
81
55
 
82
- def to_shell
83
- to_shellwords.join(' ')
56
+ #
57
+ def shelljoin
58
+ shellwords.shelljoin
84
59
  end
85
60
 
86
- # Original name.
87
- alias_method :to_console, :to_shell
88
61
  end
89
62