facets 2.9.0.pre.1 → 2.9.0.pre.2

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 (107) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +1 -2
  3. data/HISTORY.rdoc +16 -8
  4. data/lib/core/facets/hash/subset.rb +24 -0
  5. data/lib/core/facets/hash/zip.rb +18 -0
  6. data/lib/core/facets/kernel/try.rb +3 -3
  7. data/lib/core/facets/module/home.rb +90 -0
  8. data/lib/core/facets/module/homename.rb +1 -0
  9. data/lib/core/facets/module/housing.rb +1 -0
  10. data/lib/core/facets/module/modname.rb +1 -22
  11. data/lib/core/facets/na.rb +11 -5
  12. data/lib/core/facets/object/clone.rb +1 -0
  13. data/lib/core/facets/{kernel/try_dup.rb → object/dup.rb} +41 -35
  14. data/lib/core/facets/{kernel → object}/object_state.rb +15 -18
  15. data/lib/core/facets/object/replace.rb +43 -0
  16. data/lib/core/facets/object/try_dup.rb +1 -0
  17. data/lib/core/facets/string/cleanlines.rb +2 -0
  18. data/lib/core/facets/time/ago.rb +1 -1
  19. data/lib/core/facets/time/in.rb +1 -93
  20. data/lib/core/facets/time/less.rb +1 -0
  21. data/lib/core/facets/time/shift.rb +95 -0
  22. data/lib/more/facets/interval.rb +284 -0
  23. data/lib/more/facets/math.rb +6 -0
  24. data/lib/more/facets/math/abs.rb +8 -0
  25. data/lib/more/facets/math/acot.rb +8 -0
  26. data/lib/more/facets/math/acoth.rb +8 -0
  27. data/lib/more/facets/math/acsc.rb +8 -0
  28. data/lib/more/facets/math/acsch.rb +8 -0
  29. data/lib/more/facets/math/amd.rb +17 -0
  30. data/lib/more/facets/math/approx_equal.rb +15 -0
  31. data/lib/more/facets/math/asec.rb +8 -0
  32. data/lib/more/facets/math/asech.rb +8 -0
  33. data/lib/more/facets/math/atkinson_index.rb +16 -0
  34. data/lib/more/facets/math/beta.rb +9 -0
  35. data/lib/more/facets/math/cdf.rb +10 -0
  36. data/lib/more/facets/math/ceil.rb +8 -0
  37. data/lib/more/facets/math/cot.rb +8 -0
  38. data/lib/more/facets/math/coth.rb +8 -0
  39. data/lib/more/facets/math/csc.rb +8 -0
  40. data/lib/more/facets/math/csch.rb +8 -0
  41. data/lib/more/facets/math/delta.rb +8 -0
  42. data/lib/more/facets/math/epsilon.rb +21 -0
  43. data/lib/more/facets/math/exp10.rb +8 -0
  44. data/lib/more/facets/math/exp2.rb +8 -0
  45. data/lib/more/facets/math/factorial.rb +37 -0
  46. data/lib/more/facets/math/floor.rb +8 -0
  47. data/lib/more/facets/math/gamma.rb +12 -0
  48. data/lib/more/facets/math/gcd.rb +23 -0
  49. data/lib/more/facets/math/gini_coefficient.rb +33 -0
  50. data/lib/more/facets/math/kldivergence.rb +19 -0
  51. data/lib/more/facets/math/lcm.rb +15 -0
  52. data/lib/more/facets/math/lgamma.rb +21 -0
  53. data/lib/more/facets/math/linsolve.rb +10 -0
  54. data/lib/more/facets/math/log2.rb +14 -0
  55. data/lib/more/facets/math/max.rb +1 -0
  56. data/lib/more/facets/math/mean.rb +16 -0
  57. data/lib/more/facets/math/median.rb +15 -0
  58. data/lib/more/facets/math/min.rb +35 -0
  59. data/lib/more/facets/math/pow.rb +8 -0
  60. data/lib/more/facets/math/pstd.rb +1 -0
  61. data/lib/more/facets/math/pvariance.rb +1 -0
  62. data/lib/more/facets/math/rmd.rb +16 -0
  63. data/lib/more/facets/math/root.rb +8 -0
  64. data/lib/more/facets/math/sec.rb +8 -0
  65. data/lib/more/facets/math/sech.rb +8 -0
  66. data/lib/more/facets/math/sign.rb +9 -0
  67. data/lib/more/facets/math/sinc.rb +8 -0
  68. data/lib/more/facets/math/sqr.rb +8 -0
  69. data/lib/more/facets/math/sqsolve.rb +53 -0
  70. data/lib/more/facets/math/std.rb +27 -0
  71. data/lib/more/facets/math/stderr.rb +1 -0
  72. data/lib/more/facets/math/sum.rb +16 -0
  73. data/lib/more/facets/math/summed_sqdevs.rb +14 -0
  74. data/lib/more/facets/math/theil_index.rb +24 -0
  75. data/lib/more/facets/math/variance.rb +31 -0
  76. data/lib/more/facets/thread.rb +24 -0
  77. data/lib/tour/facets/array/op_pow.rb +5 -0
  78. data/lib/tour/facets/module/enclosure.rb +15 -1
  79. data/lib/tour/facets/module/preextend.rb +26 -0
  80. data/lib/tour/facets/module/prepend.rb +39 -13
  81. data/meta/gemfile +1 -1
  82. data/qed/core/binding/caller.rdoc +1 -3
  83. data/test/core/array/test_after.rb +1 -1
  84. data/test/core/array/test_before.rb +1 -1
  85. data/test/core/array/test_conjoin.rb +1 -1
  86. data/test/core/array/test_store.rb +1 -1
  87. data/test/core/hash/test_argumentize.rb +1 -1
  88. data/test/core/hash/test_join.rb +1 -1
  89. data/test/core/kernel/test_dup.rb +1 -1
  90. data/test/core/kernel/test_get.rb +1 -1
  91. data/test/core/kernel/test_qua_class.rb +1 -1
  92. data/test/core/time/test_ago.rb +5 -117
  93. data/test/core/time/test_hence.rb +2 -2
  94. data/test/core/time/test_in.rb +4 -115
  95. data/test/core/time/test_less.rb +137 -0
  96. data/test/core/time/test_set.rb +1 -1
  97. data/test/core/time/test_shift.rb +126 -0
  98. data/test/more/test_date.rb +1 -1
  99. data/test/tour/module/test_cattr.rb +1 -1
  100. data/test/tour/module/test_class_extend.rb +1 -1
  101. data/test/tour/module/test_instance_function.rb +1 -1
  102. data/test/tour/module/test_method_space.rb +1 -1
  103. metadata +76 -10
  104. data/lib/core/facets/hash/zipnew.rb +0 -18
  105. data/lib/core/facets/kernel/clone.rb +0 -1
  106. data/lib/core/facets/kernel/dup.rb +0 -34
  107. data/lib/core/facets/kernel/replace.rb +0 -1
data/AUTHORS CHANGED
@@ -9,6 +9,7 @@
9
9
  The following developers have recently contributed to the development of Facets.
10
10
  They are held in the highest regard for their efforts.
11
11
 
12
+ * Alexey Petrushin Some methods from `ruby-ext` project.
12
13
  * Michael Harmer Documentation Improvements
13
14
  * Lavir the Whiolet Improved Range#at_rand and added File#ext.
14
15
  * Jean-Denis Vauguet Added Pathname#visit.
data/COPYING CHANGED
@@ -1,8 +1,7 @@
1
1
 
2
2
  Ruby Facets
3
3
 
4
- Copyright (c) 2005 Thomas Sawyer
5
- Copyright (c) 2008 TigerOps / Thomas Sawyer
4
+ Copyright (c) 2005,2010 Thomas Sawyer
6
5
 
7
6
 
8
7
  THE RUBY LICENSE
@@ -27,6 +27,10 @@ extensions you want, thus avoiding any conflicts. There are actually only a
27
27
  dozen or so overlaps and all are intended to compatible, but it doesn't hurt
28
28
  to be sure.
29
29
 
30
+ Lastly, it is worth mentioning that this release has been more thuroughly
31
+ tested than any version of Facets to date. Thanks to RVM this release runs
32
+ green on Ruby 1.8.6, 1.8.7 and 1.9.2.
33
+
30
34
  Changes:
31
35
 
32
36
  * New Features
@@ -44,10 +48,13 @@ Changes:
44
48
  * Add Module#anonymous?
45
49
  * Add Module#copy_inheritor
46
50
  * Add Indexable#from and Indexable#upto
47
- * Add Array#from and Array#upto
51
+ * Add Array#from and Array#thru
48
52
  * Add NA class via na.rb
49
53
  * Add Memoizable in memoizable.rb for a more robust memoization system
50
54
  * Add Module#safe_memo in thread.rb for thread safe memoization
55
+ * Add Kernel#sandbox in thread.rb for threaded $SAFE=4 evaluation
56
+ * Add Hash#subset
57
+ * Add numerous Math extensions
51
58
 
52
59
  * Deprecations
53
60
 
@@ -59,9 +66,8 @@ Changes:
59
66
  * Deprecate Kernel#populate and #set_from (use #assign and #assign_from)
60
67
  * Deprecate Kernel#non_nil? since #not_nil? is enough
61
68
  * Deprecate #__HERE__ b/c implementation was unreliable
62
- * Deprecate Array#upto and Indexable#upto, use #thru instead
63
- * Deprecate Time#since, use #ago instead
64
- * Deprecate Time#advance, use #in instead TODO
69
+ * Deprecate Time#since, use #less instead
70
+ * Deprecate Time#advance, use #shift instead
65
71
  * Deprecate Kernel#super_as (no good way to get callers method name)
66
72
  * Deprecate Integer#clear_bit, use #bit_clear instead
67
73
  * Deprecate Kernel#resc, use String#to_re or #to_rx instead
@@ -90,6 +96,8 @@ Changes:
90
96
  * Rename String#chars to String#characters
91
97
  * Rename String#outdent to String#unindent
92
98
  * Rename Time#round to Time#round_to
99
+ * Rename Time#hence to Time#shift (but keep aliases)
100
+ * Rename Hash#zipnew to Hash#zip
93
101
 
94
102
  * Moved Libraries
95
103
 
@@ -121,15 +129,15 @@ Changes:
121
129
  * Improved Features
122
130
 
123
131
  * New lib/tour division of libraries
124
- * Module#class_extend synamically creates append_features method
132
+ * Module#class_extend dynamically creates append_features method
125
133
  * Kernel#require_all is only for relative requires
126
134
  * __DIR__ can take subdirectory arguments
127
135
  * Hash#join has more sensible default separator (' ')
128
- * A few OpEsc escapes have been renamed
136
+ * Some OpEsc escapes have been renamed
129
137
  * Kernel#assign does not accept a block
130
- * Kernel#try is like ActiveSupport version
138
+ * Kernel#try is now like ActiveSupport's
131
139
  * Improved #respond (which is like old #try)
132
- * Remove all `if defined?(ActiveSupport)`
140
+ * Remove all `if defined?(ActiveSupport)` conditions
133
141
  * Use #random_range to support specialized Range#at_rand functionality
134
142
  * Use Comparable.[] instead of Comparable()
135
143
  * Array#rotate rotates in opposite direction than before (b/c or Ruby 1.9)
@@ -0,0 +1,24 @@
1
+ class Hash
2
+
3
+ # Take a subset of the hash, based on keys given or a block
4
+ # that evaluates to true for each hash key.
5
+ #
6
+ # {'a'=>1, 'b'=>2}.subset('a') #=> {'a'=>1}
7
+ # {'a'=>1, 'b'=>2}.subset{|k| k == 'a' } #=> {'a'=>1}
8
+ #
9
+ # CREDIT: Alexey Petrushin
10
+ def subset(keys=nil, &block)
11
+ h = {}
12
+ if keys
13
+ self.each do |k, v|
14
+ h[k] = v if keys.include?(k)
15
+ end
16
+ else
17
+ self.each do |k, v|
18
+ h[k] = v if block.call(k)
19
+ end
20
+ end
21
+ h
22
+ end
23
+
24
+ end
@@ -0,0 +1,18 @@
1
+ class Hash
2
+
3
+ # Creates a new hash from two separate arrays, a +keys+ array and
4
+ # a +values+ array.
5
+ #
6
+ # Hash.zip(["a","b","c"], [1,2,3])
7
+ # # => { "a"=>1, "b"=>2, "c"=>3 }
8
+ #
9
+ # CREDIT: Trans, Ara T. Howard
10
+
11
+ def self.zip(keys,values) # or some better name
12
+ h = {}
13
+ keys.size.times{ |i| h[ keys[i] ] = values[i] }
14
+ h
15
+ end
16
+
17
+ end
18
+
@@ -18,7 +18,7 @@ module Kernel
18
18
  #
19
19
  # or:
20
20
  #
21
- # @example? @example.name : nil
21
+ # @example ? @example.name : nil
22
22
  #
23
23
  # But with try
24
24
  #
@@ -26,9 +26,9 @@ module Kernel
26
26
  #
27
27
  # or
28
28
  #
29
- # @example.try.name #=> "bob"
29
+ # @example.try.name #=> "bob"
30
30
  #
31
- # It also accepts arguments and/or a block, for the method it is trying:
31
+ # It also accepts arguments and a block, for the method it is trying:
32
32
  #
33
33
  # @people.try(:collect){ |p| p.name }
34
34
  #
@@ -0,0 +1,90 @@
1
+ class Module
2
+
3
+ # Returns the module or class containing the receiver.
4
+ #
5
+ # module ::HomeExample
6
+ # module M
7
+ # module N
8
+ # end
9
+ # end
10
+ # end
11
+ #
12
+ # HomeExample::M::N.home #=> HomeExample::M
13
+ #
14
+ # The home of a top-level module/class is Object.
15
+ #
16
+ # HomeExample.home #=> Object
17
+ #
18
+ # This method is called *home* because techinally a module or class
19
+ # is just a constant reference, and as such can reside with multiple
20
+ # namespaces, like any variable. For example:
21
+ #
22
+ # module OtherPlace
23
+ # M = ::HomeExample::M
24
+ # end
25
+ #
26
+ # In this example, you might think that +OtherPlace::M+'s home would be
27
+ # +OtherPlace+, but +OtherPlace::M+ is the same object as +HomeExample::M+,
28
+ # and it can have only one "home" --the original location of it's definition.
29
+ def home
30
+ #homename = /::[^:]+\Z/ =~ name ? $` : nil
31
+ if homename
32
+ homename.split(/::/).inject(self) do |mod, cref|
33
+ if /\:(0x.*?)\>$/ =~ cref # TODO: does this ever happen?
34
+ #p $1.to_i(16)
35
+ ObjectSpace._idref($1.to_i(16))
36
+ else
37
+ mod.const_get(cref)
38
+ end
39
+ end
40
+ else
41
+ Object
42
+ end
43
+ end
44
+
45
+ # Returns the name of module or class containing the receiver.
46
+ #
47
+ # module ::HomeExample
48
+ # module M
49
+ # module N
50
+ # end
51
+ # end
52
+ # end
53
+ #
54
+ # HomeExample::M::N.homename #=> "HomeExample::M"
55
+ #
56
+ # See also Module#basename.
57
+ def homename
58
+ /::[^:]+\Z/ =~ name ? $` : nil
59
+ end
60
+
61
+ # Original name for #homename.
62
+ alias_method :modname, :homename
63
+
64
+ # Returns all the namespaces of this module according ordered from
65
+ # nearest and moving outwards. The receiver is not contained within
66
+ # the result.
67
+ #
68
+ # module ::HouseExample
69
+ # module M
70
+ # module N
71
+ # end
72
+ # end
73
+ # end
74
+ #
75
+ # HouseExample.housing #=> [Object]
76
+ # HouseExample::M.housing #=> [HouseExample, Object]
77
+ # HouseExample::M::N.housing #=> [HouseExample::M, HouseExample, Object]
78
+ #
79
+ # Compare this to +Module.nesting+.
80
+ def housing
81
+ n = []
82
+ name.split(/::/).inject(self) do |mod, cref|
83
+ c = mod.const_get(cref) ; n.unshift(c) ; c
84
+ end
85
+ n << Object # ?
86
+ n.shift # we really don't need +self+ too.
87
+ n
88
+ end
89
+
90
+ end
@@ -0,0 +1 @@
1
+ require 'facets/module/home'
@@ -0,0 +1 @@
1
+ require 'facets/module/home'
@@ -1,22 +1 @@
1
- class Module
2
-
3
- # Returns the name of the module containing this one.
4
- #
5
- # module ::NSExample
6
- # module M
7
- # module N
8
- # end
9
- # end
10
- # end
11
- #
12
- # NSExample::M::N.modname #=> "NSExample::M"
13
- #
14
- # See also Module#basename.
15
- def modname
16
- unless defined? @_modname
17
- @_modname = name =~ /::[^:]+\Z/ ? $`.freeze : nil
18
- end
19
- @_modname
20
- end
21
-
22
- end
1
+ require 'facets/module/homename'
@@ -6,10 +6,16 @@
6
6
  #
7
7
  # NA is also used to represent an argument "slot" for Proc#partial.
8
8
  #
9
- # NA is a subclass of ArgumentError.
9
+ # NA is an instance of ArgumentError.
10
10
 
11
- class NA < ArgumentError
12
- class << self
13
- def method_missing(*); self; end
14
- end
11
+ class << NA = ArgumentError.new
12
+ def inspect ; 'N/A' ; end
13
+ def method_missing(*); self; end
15
14
  end
15
+
16
+ # NA is a subclass of ArgumentError.
17
+ #class NA < ArgumentError
18
+ # class << self
19
+ # def method_missing(*); self; end
20
+ # end
21
+ #end
@@ -0,0 +1 @@
1
+ require 'facets/object/dup'
@@ -1,73 +1,79 @@
1
- module Kernel
1
+ class Object
2
2
  # Override this in a child class if it cannot be dup'ed.
3
3
  #
4
4
  # obj1 = Object.new
5
- # obj2 = obj1.try_dup
5
+ # obj2 = obj1.dup!
6
6
  # obj2.equal?(obj1) #=> false
7
7
  #
8
8
  # CREDIT: Dan Kubb (extlib)
9
- def try_dup
9
+ def dup!
10
10
  dup
11
11
  end
12
12
 
13
- # Alternative name for #try_dup.
14
- def dup!
15
- try_dup
13
+ # Alternative name for #dup!
14
+ def try_dup
15
+ dup!
16
16
  end
17
+
18
+ # Can you safely call #dup on this object?
19
+ #
20
+ # Returns +false+ for +nil+, +false+, +true+, symbols, and numbers;
21
+ # +true+ otherwise.
22
+ def dup? ; true ; end
23
+ def clone? ; true ; end
17
24
  end
18
25
 
19
- class TrueClass
20
- # Since TrueClass is immutable it cannot be duplicated.
26
+ class NilClass
27
+ # Since NilClass is immutable it cannot be duplicated.
21
28
  # For this reason #try_dup returns +self+.
22
29
  #
23
- # true.try_dup #=> true
30
+ # nil.dup! #=> nil
24
31
  #
25
- def try_dup
26
- self
27
- end
32
+ def dup! ; self ; end
33
+ def dup? ; false ; end
34
+ def clone? ; false ; end
28
35
  end
29
36
 
30
37
  class FalseClass
31
38
  # Since FalseClass is immutable it cannot be duplicated.
32
39
  # For this reason #try_dup returns +self+.
33
40
  #
34
- # false.try_dup #=> false
41
+ # false.dup! #=> false
35
42
  #
36
- def try_dup
37
- self
38
- end
43
+ def dup! ; self ; end
44
+ def dup? ; false ; end
45
+ def clone? ; false ; end
39
46
  end
40
47
 
41
- class NilClass
42
- # Since NilClass is immutable it cannot be duplicated.
48
+ class TrueClass
49
+ # Since TrueClass is immutable it cannot be duplicated.
43
50
  # For this reason #try_dup returns +self+.
44
51
  #
45
- # nil.try_dup #=> nil
52
+ # true.dup! #=> true
46
53
  #
47
- def try_dup
48
- self
49
- end
54
+ def dup! ; self ; end
55
+ def dup? ; false ; end
56
+ def clone? ; false ; end
50
57
  end
51
58
 
52
- class Numeric
53
- # Since Numeric is immutable it cannot be duplicated.
59
+ class Symbol
60
+ # Since Symbol is immutable it cannot be duplicated.
54
61
  # For this reason #try_dup returns +self+.
55
62
  #
56
- # 1.try_dup #=> 1
63
+ # :a.dup! #=> :a
57
64
  #
58
- def try_dup
59
- self
60
- end
65
+ def dup! ; self ; end
66
+ def dup? ; false ; end
67
+ def clone? ; false ; end
61
68
  end
62
69
 
63
- class Symbol
64
- # Since Symbol is immutable it cannot be duplicated.
70
+ class Numeric
71
+ # Since Numeric is immutable it cannot be duplicated.
65
72
  # For this reason #try_dup returns +self+.
66
73
  #
67
- # :a.try_dup #=> :a
74
+ # 1.dup! #=> 1
68
75
  #
69
- def try_dup
70
- self
71
- end
76
+ def dup! ; self ; end
77
+ def dup? ; false ; end
78
+ def clone? ; false ; end
72
79
  end
73
-
@@ -1,5 +1,6 @@
1
- class Object # module Kernel ?
2
- # Get or set state of object.
1
+ class Object
2
+ # Get or set state of object. You can think of #object_state as an in-code
3
+ # form of marshalling.
3
4
  #
4
5
  # class StateExample
5
6
  # attr_reader :a, :b
@@ -12,13 +13,18 @@ class Object # module Kernel ?
12
13
  # obj.a #=> 1
13
14
  # obj.b #=> 2
14
15
  #
16
+ # obj.object_state #=> {:a=>1, :b=>2}
17
+ #
15
18
  # obj.object_state(:a=>3, :b=>4)
16
19
  # obj.a #=> 3
17
20
  # obj.b #=> 4
18
21
  #
19
- # TODO: Would #instance_state be a more appropriate name?
20
- #
21
- # TODO: Consider how this relates to #instance.
22
+ # For most object's this is essentially the same as <code>instance.to_h</code>.
23
+ # But for data structures like Array and Hash it returns a snapshot of their
24
+ # contents, not the state of their instance variables.
25
+ #--
26
+ # TODO: Should this be in module Kernel ?
27
+ #++
22
28
  def object_state(data=nil)
23
29
  if data
24
30
  instance_variables.each do |iv|
@@ -34,35 +40,31 @@ class Object # module Kernel ?
34
40
  data
35
41
  end
36
42
  end
37
-
38
- # Replace state of object.
39
- def replace(data)
40
- instance_variables.each do |iv|
41
- name = iv.to_s.sub(/^[@]/, '').to_sym
42
- instance_variable_set(iv, data[name])
43
- end
44
- end
45
43
  end
46
44
 
47
45
  class Array
46
+ #
48
47
  def object_state(data=nil)
49
48
  data ? replace(data) : dup
50
49
  end
51
50
  end
52
51
 
53
52
  class String
53
+ #
54
54
  def object_state(data=nil)
55
55
  data ? replace(data) : dup
56
56
  end
57
57
  end
58
58
 
59
59
  class Hash
60
+ #
60
61
  def object_state(data=nil)
61
62
  data ? replace(data) : dup
62
63
  end
63
64
  end
64
65
 
65
66
  class Struct
67
+ #
66
68
  def object_state(data=nil)
67
69
  if data
68
70
  data.each_pair {|k,v| send(k.to_s + "=", v)}
@@ -72,9 +74,4 @@ class Struct
72
74
  data
73
75
  end
74
76
  end
75
-
76
- def replace(data)
77
- data.each_pair {|k,v| send(k.to_s + "=", v)}
78
- end
79
77
  end
80
-