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
@@ -1,9 +1,9 @@
1
1
  class Array
2
2
 
3
- # This is more advnaced form of #join. It allows for fine control
3
+ # This is more advanced form of #join. It allows for fine control
4
4
  # of separators.
5
5
  #
6
- # NOTE: The old version used to default it's separator to ", " and
6
+ # NOTE: The old version used to default its separator to ", " and
7
7
  # default the terminating separator to " and ". This is no longer
8
8
  # the case. You must specifically provide these parameters.
9
9
  #
@@ -1,6 +1,6 @@
1
1
  class Array
2
2
 
3
- # Pad an array with a given <tt>value</tt> upto a given <tt>length</tt>.
3
+ # Pad an array with a given <tt>value</tt> up to a given <tt>length</tt>.
4
4
  #
5
5
  # [0,1,2].pad(6,"a") #=> [0,1,2,"a","a","a"]
6
6
  #
@@ -1,7 +1,7 @@
1
1
  class Array
2
2
 
3
- # Apply a block to hash, and recursively apply that block
4
- # to each subhash.
3
+ # Apply a block to array, and recursively apply that block
4
+ # to each subarray.
5
5
  #
6
6
  # arr = ["a", ["b", "c", nil], nil]
7
7
  # arr.recursively{|a| a.compact! }
@@ -2,7 +2,7 @@ class Array
2
2
 
3
3
  # Splice acts a combination of #slice! and #store.
4
4
  # If two arguments are given it calls #store.
5
- # If a single argument is give it calls slice!.
5
+ # If a single argument is given it calls slice!.
6
6
  #
7
7
  # a = [1,2,3]
8
8
  # a.splice(1) #=> 2
@@ -29,8 +29,7 @@ class Binding
29
29
  # tester #=> :tester
30
30
  #
31
31
  def __callee__
32
- name = /\`([^\']+)\'/.match(caller(1).first)[1]
33
- return name.to_sym
32
+ eval('__callee__')
34
33
  end
35
34
 
36
35
  # There is a lot of debate on what to call this.
@@ -41,8 +40,7 @@ class Binding
41
40
  # tester #=> "tester"
42
41
  #
43
42
  def __method__
44
- name = /\`([^\']+)\'/.match(caller(1).first)[1]
45
- return name
43
+ eval('__method__')
46
44
  end
47
45
 
48
46
  end
@@ -13,9 +13,9 @@
13
13
 
14
14
  class Module
15
15
 
16
- # Automatically generate sorting defintions base on attribute fields.
16
+ # Automatically generate sorting definitions based on attribute fields.
17
17
  #
18
- # include SortOn(:a, :b)
18
+ # include Comparable(:a, :b)
19
19
  #
20
20
  # is equivalent to including a module containing:
21
21
  #
@@ -16,6 +16,9 @@ class Dir
16
16
  #
17
17
  # CREDIT: Daniel Berger, Jeffrey Schwab
18
18
 
19
+ # TODO: make it work with windows too
20
+ # use FileTest.root?
21
+
19
22
  def self.ascend(dir, inclusive=true, &blk)
20
23
  dir = dir.dup
21
24
  blk.call(dir) if inclusive
@@ -4,6 +4,10 @@ class Dir
4
4
  # to the given block.
5
5
  #
6
6
  # CREDIT: George Moschovitis
7
+ #
8
+ # TODO: If fully compatible, reimplement as alias of Find.find,
9
+ # or just copy and paste Find.find code here if it looks more robust.
10
+ #
7
11
  def self.recurse(path='.', &block)
8
12
  list = []
9
13
  stoplist = ['.', '..']
@@ -1,34 +1,32 @@
1
- class Object #:nodoc:
1
+ class Object
2
2
  # Can you safely call #dup on this object?
3
3
  # False for nil, false, true, symbols, and numbers; true otherwise.
4
4
  def dup? ; true ; end
5
5
  def clone? ; true ; end
6
6
  end
7
7
 
8
- class NilClass #:nodoc:
8
+ class NilClass
9
9
  def dup? ; false ; end
10
10
  def clone? ; false ; end
11
11
  end
12
12
 
13
- class FalseClass #:nodoc:
13
+ class FalseClass
14
14
  def dup? ; false ; end
15
15
  def clone? ; false ; end
16
16
  end
17
17
 
18
- class TrueClass #:nodoc:
18
+ class TrueClass
19
19
  def dup? ; false ; end
20
20
  def clone? ; false ; end
21
21
  end
22
22
 
23
- class Symbol #:nodoc:
23
+ class Symbol
24
24
  def dup? ; false ; end
25
25
  def clone? ; false ; end
26
26
  end
27
27
 
28
- class Numeric #:nodoc:
28
+ class Numeric
29
29
  def dup? ; false ; end
30
30
  def clone? ; false ; end
31
31
  end
32
32
 
33
- # :facets: extra
34
-
@@ -1,28 +1,37 @@
1
+ require 'facets/hash/count'
2
+
1
3
  module Enumerable
2
4
 
3
5
  unless method_defined?(:count)
4
6
 
5
7
  # Count the number of items in an enumerable
6
- # equal (==) to the given object.
8
+ # equal (==) to the given object(s).
7
9
  #
8
10
  # e = [ 'a', '1', 'a' ]
9
- # e.count('1') #=> 1
10
- # e.count('a') #=> 2
11
+ # e.count('1') #=> 1
12
+ # e.count('a') #=> 2
13
+ # e.count('a', 1) #=> 3
11
14
  #
12
- # Count can also handle multiple-valued blocks.
15
+ # Note that Hash#count only considers values.
13
16
  #
14
- # e = { 'a' => 2, 'a' => 2, 'b' => 1 }
15
- # e.count('a',2) #=> 1
17
+ # e = { 'a' => 2, 'x' => 2, 'b' => 1 }
18
+ # e.count(1) #=> 1
19
+ # e.count(2) #=> 2
16
20
  #
17
21
  # CREDIT: Trans
18
22
 
19
- def count(item=ArgumentError, &blk)
20
- return select(&blk).size if block_given?
21
- return select{ |*i| item == i }.size if ArgumentError == item
22
- begin
23
- size
24
- rescue
25
- (i=0; each{|e| i+=1 }; i)
23
+ def count(*items, &block)
24
+ if block || !items.empty?
25
+ r = self
26
+ r = r.select(&block) if block
27
+ r = r.select{ |x| items.any?{ |i| i == x } } if !items.empty?
28
+ r.size
29
+ else
30
+ begin
31
+ size
32
+ rescue
33
+ i=0; each{ |e| i+=1 }; i
34
+ end
26
35
  end
27
36
  end
28
37
 
@@ -0,0 +1,28 @@
1
+ module Enumerable
2
+
3
+ # Yield each element to the block. Returns the result of
4
+ # the block when the block is true, terminating early as detect does.
5
+ #
6
+ # obj1.foo? #=> false
7
+ # obj2.foo? #=> true
8
+ #
9
+ # obj2.foo #=> "a value"
10
+ #
11
+ # [obj1, obj2].map_detect { |obj| obj.foo if obj.foo? } #=> "a value"
12
+ #
13
+ # If the block is never true, return the object given in the first parameter,
14
+ # or nil if none specified.
15
+ #
16
+ # [1,2,3].map_detect { |_| false } #=> nil
17
+ # [false].map_detect(1) { |_| false } #=> 1
18
+ #
19
+ def map_detect(value_for_none_matching = nil)
20
+ each do |member|
21
+ if result = yield(member)
22
+ return result
23
+ end
24
+ end
25
+
26
+ value_for_none_matching
27
+ end
28
+ end
@@ -13,14 +13,22 @@ module Enumerable
13
13
 
14
14
  def mash(&yld)
15
15
  if yld
16
- inject({}) do |h, *kv| # Used to be inject({}) do |h,kv|
17
- r = *yld[*kv] # The *-op works differnt from to_a on single element hash!!!
18
- nk, nv = *r # Used to be nk, nv = *yld[*kv].to_a.flatten
16
+ h = {}
17
+ each do |*kv|
18
+ r = yld[*kv]
19
+ case r
20
+ when Hash
21
+ nk, nv = *r.to_a[0]
22
+ when Range
23
+ nk, nv = r.first, r.last
24
+ else
25
+ nk, nv = *r
26
+ end
19
27
  h[nk] = nv
20
- h
21
28
  end
29
+ h
22
30
  else
23
- Enumerator.new(self,:graph) # Used to be Hash[*self.to_a] or Hash[*self.to_a.flatten]
31
+ Enumerator.new(self,:mash)
24
32
  end
25
33
  end
26
34
 
@@ -1,8 +1,10 @@
1
1
  require 'facets/functor'
2
2
 
3
+ #--
3
4
  # TODO: Consider Enumerator methods
5
+ #++
4
6
 
5
- module Enumerable #:nodoc:
7
+ module Enumerable
6
8
 
7
9
  # Per element meta-functor.
8
10
  #
@@ -0,0 +1,14 @@
1
+ require 'facets/enumerable/count'
2
+
3
+ class Hash
4
+
5
+ # Like Enumerable#count, but counts hash values.
6
+ #
7
+ # {:A=>1, :B=>1}.count(1) #=> 2
8
+ #
9
+ def count(value)
10
+ values.count(value)
11
+ end
12
+
13
+ end
14
+
@@ -0,0 +1,14 @@
1
+ require 'facets/functor'
2
+
3
+ class Hash
4
+
5
+ # TODO: The name of this method may change.
6
+ #
7
+ def data
8
+ Functor.new() do |op|
9
+ self[op]
10
+ end
11
+ end
12
+
13
+ end
14
+
@@ -19,7 +19,7 @@ module Kernel
19
19
 
20
20
  end
21
21
 
22
- unless method_defined?(:__callee__) # 1.9+ # TODO: Is this so?
22
+ unless method_defined?(:__callee__) # 1.9+
23
23
 
24
24
  # Retreive the current running method name.
25
25
  #
@@ -6,17 +6,18 @@ module Kernel
6
6
  #
7
7
  # produces
8
8
  #
9
- # /home/dave/projects/foo.rb, 38
10
- # "hi"
9
+ # "hi" (/home/dave/projects/foo.rb, 38)
11
10
  #
12
- # TODO: This is borderline "prime". Keep here?
13
- # Another copy of it exits in dtools.rb
14
-
15
11
  def d(*x)
16
- puts "#{__FILE__}, #{__LINE__}"
17
- x.each{ |e| puts e.inspect } #p(*x)
18
- x.size > 1 ? x : x.last #x.last
12
+ puts "#{x.inspect} #{caller[0]}"
13
+ return *x
19
14
  end
20
15
 
16
+ #def d(*x)
17
+ # puts "#{__FILE__}, #{__LINE__}"
18
+ # x.each{ |e| puts e.inspect } #p(*x)
19
+ # x.size > 1 ? x : x.last #x.last
20
+ #end
21
+
21
22
  end
22
23
 
@@ -0,0 +1,20 @@
1
+ module Kernel
2
+
3
+ # During this trying time when no one can get their
4
+ # techie catchwords to stick to the refrigerator no
5
+ # matter how hard they slap it # with the enchanted
6
+ # magnetic spatula, it’s good to know that the
7
+ # contrived phrases really do fly, graceful and
8
+ # unclasped and bearing north toward chilled shrimp.
9
+ # I know what my Hallowe’en pumpkin is going to say.
10
+ #
11
+ # -- why the lucky stiff
12
+ #
13
+ # CREDIT: WhyTheLuckyStiff
14
+
15
+ def eigenclass
16
+ (class << self; self; end)
17
+ end
18
+
19
+ end
20
+
@@ -0,0 +1,10 @@
1
+ module Kernel
2
+
3
+ alias_method :_extend, :extend
4
+
5
+ def extend(*mod, &blk)
6
+ _extend *mod unless mod.empty?
7
+ _extend Module.new(&blk) if blk
8
+ end
9
+
10
+ end
@@ -13,6 +13,7 @@ module Kernel
13
13
  # block is provided to eval against it.
14
14
  #
15
15
  # It is what it is.
16
+ # But I think I like this one best.
16
17
  #
17
18
  # CREDIT: Trans
18
19
 
@@ -40,15 +40,16 @@ class InstanceVariables
40
40
 
41
41
  def []=(name, value)
42
42
  name = atize(name)
43
- @delegate.instance_varaible_set(name,value)
43
+ @delegate.instance_variable_set(name,value)
44
44
  end
45
45
 
46
46
  def <<(pair)
47
47
  name, value = *pair
48
48
  name = atize(name)
49
- @delegate.instance_varaible_set(name, value)
49
+ @delegate.instance_variable_set(name, value)
50
50
  end
51
51
 
52
+ # (See also: Kernel#populate, which uses accessor method rather than setting instance variables directly.)
52
53
  def update(hash)
53
54
  hash.each do |pair|
54
55
  self << pair
@@ -82,7 +83,6 @@ class InstanceVariables
82
83
  end
83
84
 
84
85
  =begin demo
85
-
86
86
  class Friend
87
87
  attr_accessor :name, :age, :phone
88
88
  def initialize(name, age, phone)
@@ -91,7 +91,7 @@ end
91
91
  end
92
92
 
93
93
  f1 = Friend.new("John", 30, "555-1212")
94
- p f1.variables
95
- p f1.variables.to_hash
96
-
94
+ p f1.instance_vars
95
+ f1.instance_vars.update({:name=>'Jerry'})
96
+ p f1.instance_vars
97
97
  =end
@@ -0,0 +1,18 @@
1
+ module Kernel
2
+
3
+ # Alias a method defined in the metaclass (ie. singleton class).
4
+ #
5
+ # def X.y?; "y?" ; end
6
+ # X.meta_alias "ynot?", "y?"
7
+ # X.ynot? #=> y?
8
+ #
9
+ # CREDIT: Trans
10
+
11
+ def meta_alias(*args)
12
+ meta_class do
13
+ alias_method(*args)
14
+ end
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,17 @@
1
+ module Kernel
2
+
3
+ # Easy access to an object's "special" class,
4
+ # otherwise known as it's metaclass or singleton class.
5
+
6
+ def meta_class(&block)
7
+ if block_given?
8
+ (class << self; self; end).class_eval(&block)
9
+ else
10
+ (class << self; self; end)
11
+ end
12
+ end
13
+
14
+ alias_method :metaclass, :meta_class
15
+
16
+ end
17
+