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

Sign up to get free protection for your applications and to get access to all the features.
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
-