ruby-nuggets 0.8.9 → 0.9.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 (101) hide show
  1. checksums.yaml +7 -0
  2. data/README +3 -3
  3. data/Rakefile +1 -1
  4. data/lib/nuggets/all.rb +1 -1
  5. data/lib/nuggets/all_mixins.rb +1 -1
  6. data/lib/nuggets/array/boost.rb +5 -0
  7. data/lib/nuggets/array/boost_mixin.rb +78 -0
  8. data/lib/nuggets/array/combination.rb +1 -1
  9. data/lib/nuggets/array/correlation_mixin.rb +2 -2
  10. data/lib/nuggets/array/flatten_once.rb +1 -1
  11. data/lib/nuggets/array/format.rb +1 -1
  12. data/lib/nuggets/array/histogram_mixin.rb +1 -1
  13. data/lib/nuggets/array/in_order.rb +1 -1
  14. data/lib/nuggets/array/limit_mixin.rb +1 -1
  15. data/lib/nuggets/array/mean_mixin.rb +1 -1
  16. data/lib/nuggets/array/median_mixin.rb +1 -1
  17. data/lib/nuggets/array/mode_mixin.rb +1 -1
  18. data/lib/nuggets/array/monotone.rb +1 -1
  19. data/lib/nuggets/array/only.rb +1 -1
  20. data/lib/nuggets/array/rand.rb +1 -1
  21. data/lib/nuggets/array/regression_mixin.rb +100 -20
  22. data/lib/nuggets/array/runiq_mixin.rb +1 -1
  23. data/lib/nuggets/array/shuffle.rb +1 -1
  24. data/lib/nuggets/array/standard_deviation_mixin.rb +1 -1
  25. data/lib/nuggets/array/to_hash.rb +1 -1
  26. data/lib/nuggets/array/variance_mixin.rb +2 -2
  27. data/lib/nuggets/enumerable/agrep.rb +1 -1
  28. data/lib/nuggets/enumerable/all_any_extended.rb +1 -1
  29. data/lib/nuggets/enumerable/minmax.rb +1 -1
  30. data/lib/nuggets/env/set_mixin.rb +1 -1
  31. data/lib/nuggets/env/user_encoding_mixin.rb +1 -1
  32. data/lib/nuggets/env/user_home_mixin.rb +1 -1
  33. data/lib/nuggets/file/ext_mixin.rb +1 -1
  34. data/lib/nuggets/file/replace_mixin.rb +1 -1
  35. data/lib/nuggets/file/sub_mixin.rb +1 -1
  36. data/lib/nuggets/file/which_mixin.rb +1 -1
  37. data/lib/nuggets/hash/at.rb +1 -1
  38. data/lib/nuggets/hash/deep_merge_mixin.rb +1 -1
  39. data/lib/nuggets/hash/in_order.rb +1 -1
  40. data/lib/nuggets/hash/insert.rb +1 -1
  41. data/lib/nuggets/hash/nest_mixin.rb +1 -1
  42. data/lib/nuggets/hash/only.rb +1 -1
  43. data/lib/nuggets/hash/seen.rb +5 -0
  44. data/lib/nuggets/hash/seen_mixin.rb +59 -0
  45. data/lib/nuggets/hash/unroll_mixin.rb +1 -1
  46. data/lib/nuggets/integer/factorial.rb +1 -1
  47. data/lib/nuggets/integer/length_mixin.rb +1 -1
  48. data/lib/nuggets/integer/map_mixin.rb +1 -1
  49. data/lib/nuggets/integer/to_binary_s.rb +1 -1
  50. data/lib/nuggets/io/agrep.rb +1 -1
  51. data/lib/nuggets/io/interact_mixin.rb +1 -1
  52. data/lib/nuggets/io/modes.rb +1 -1
  53. data/lib/nuggets/io/null_mixin.rb +1 -1
  54. data/lib/nuggets/io/redirect_mixin.rb +1 -1
  55. data/lib/nuggets/net/success.rb +1 -1
  56. data/lib/nuggets/numeric/duration.rb +1 -1
  57. data/lib/nuggets/numeric/limit.rb +1 -1
  58. data/lib/nuggets/numeric/signum.rb +1 -1
  59. data/lib/nuggets/numeric/to_multiple.rb +1 -1
  60. data/lib/nuggets/object/blank_mixin.rb +1 -1
  61. data/lib/nuggets/object/boolean_mixin.rb +1 -1
  62. data/lib/nuggets/object/msend_mixin.rb +1 -1
  63. data/lib/nuggets/object/silence_mixin.rb +1 -1
  64. data/lib/nuggets/object/singleton_class_mixin.rb +1 -1
  65. data/lib/nuggets/proc/bind_mixin.rb +1 -1
  66. data/lib/nuggets/range/quantile_mixin.rb +1 -1
  67. data/lib/nuggets/statistics.rb +1 -0
  68. data/lib/nuggets/statistics_mixins.rb +1 -0
  69. data/lib/nuggets/string/camelscore_mixin.rb +1 -1
  70. data/lib/nuggets/string/capitalize_first.rb +1 -1
  71. data/lib/nuggets/string/case.rb +1 -1
  72. data/lib/nuggets/string/evaluate_mixin.rb +1 -1
  73. data/lib/nuggets/string/msub.rb +1 -1
  74. data/lib/nuggets/string/nsub.rb +1 -1
  75. data/lib/nuggets/string/sub_with_md.rb +1 -1
  76. data/lib/nuggets/string/wc_mixin.rb +1 -1
  77. data/lib/nuggets/string/word_wrap.rb +1 -1
  78. data/lib/nuggets/string/xor_mixin.rb +1 -1
  79. data/lib/nuggets/tempfile/open.rb +1 -1
  80. data/lib/nuggets/uri/content_type_mixin.rb +1 -1
  81. data/lib/nuggets/uri/exist_mixin.rb +1 -1
  82. data/lib/nuggets/uri/redirect_mixin.rb +1 -1
  83. data/lib/nuggets/util/ansicolor2css.rb +1 -1
  84. data/lib/nuggets/util/cli.rb +1 -1
  85. data/lib/nuggets/util/content_type.rb +1 -1
  86. data/lib/nuggets/util/dotted_decimal.rb +1 -1
  87. data/lib/nuggets/util/i18n.rb +1 -1
  88. data/lib/nuggets/util/lazy_attr.rb +1 -1
  89. data/lib/nuggets/util/log_parser/apache.rb +1 -1
  90. data/lib/nuggets/util/log_parser/rails.rb +1 -1
  91. data/lib/nuggets/util/log_parser.rb +1 -1
  92. data/lib/nuggets/util/mysql.rb +209 -0
  93. data/lib/nuggets/util/pluggable.rb +1 -1
  94. data/lib/nuggets/util/ruby.rb +1 -1
  95. data/lib/nuggets/version.rb +2 -2
  96. data/lib/nuggets.rb +1 -1
  97. data/spec/nuggets/array/boost_spec.rb +52 -0
  98. data/spec/nuggets/array/regression_spec.rb +16 -0
  99. data/spec/nuggets/hash/seen_spec.rb +38 -0
  100. data/spec/spec_helper.rb +3 -0
  101. metadata +155 -150
@@ -0,0 +1,209 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of ruby-nuggets, some extensions to the Ruby programming #
5
+ # language. #
6
+ # #
7
+ # Copyright (C) 2007-2013 Jens Wille #
8
+ # #
9
+ # Authors: #
10
+ # Jens Wille <jens.wille@gmail.com> #
11
+ # #
12
+ # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
+ # under the terms of the GNU Affero General Public License as published by #
14
+ # the Free Software Foundation; either version 3 of the License, or (at your #
15
+ # option) any later version. #
16
+ # #
17
+ # ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License #
20
+ # for more details. #
21
+ # #
22
+ # You should have received a copy of the GNU Affero General Public License #
23
+ # along with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
24
+ # #
25
+ ###############################################################################
26
+ #++
27
+
28
+ module Util
29
+
30
+ module MySQL
31
+
32
+ class Parser
33
+
34
+ DEFAULT_NAME = '__DEFAULT__'
35
+ DEFAULT_TABLE = '__DEFAULT__'
36
+
37
+ USE_RE = /\AUSE\s+`(.+?)`/i
38
+ CREATE_TABLE_RE = /\ACREATE\s+TABLE\s+`(.+?)`/i
39
+ TABLE_COLUMN_RE = /\A\s+`(.+?)`/
40
+ FINISH_TABLE_RE = /\A\).*;\Z/
41
+ INSERT_VALUES_RE = /\AINSERT\s+INTO\s+`(.+?)`\s+(?:\((.+?)\)\s+)?VALUES\s*(.*);\Z/i
42
+ CLEAN_COLUMNS_RE = /[\s`]+/
43
+
44
+ def self.parse(input, &block)
45
+ parser = new.parse(input, &block)
46
+ block_given? ? parser : parser.tables
47
+ end
48
+
49
+ def initialize
50
+ reset
51
+ end
52
+
53
+ def reset
54
+ @name = DEFAULT_NAME
55
+ @table = DEFAULT_TABLE
56
+ @tables = {}
57
+ @columns = Hash.new { |h, k| h[k] = [] }
58
+ @value_parser = ValueParser.new
59
+ end
60
+
61
+ attr_reader :tables
62
+
63
+ def parse(input, &block)
64
+ unless block
65
+ tables, block = @tables, lambda { |_, name, table, columns, values|
66
+ ((tables[name] ||= {})[table] ||= []) << fields = {}
67
+
68
+ values.each_with_index { |value, index|
69
+ if column = columns[index]
70
+ fields[column] = value
71
+ end
72
+ }
73
+ }
74
+ end
75
+
76
+ name, table, columns, value_parser, block_given =
77
+ @name, @table, @columns, @value_parser, block_given?
78
+
79
+ input.each { |line|
80
+ case line
81
+ when USE_RE
82
+ name = $1
83
+ yield :use, name if block_given
84
+ when CREATE_TABLE_RE
85
+ table = $1
86
+ when TABLE_COLUMN_RE
87
+ columns[table] << $1 if table
88
+ when FINISH_TABLE_RE
89
+ yield :table, name, table, columns[table] if block_given
90
+ table = nil
91
+ when INSERT_VALUES_RE
92
+ _table, _columns, _values = $1, $2, $3
93
+
94
+ _columns = _columns.nil? ? columns[_table] :
95
+ _columns.gsub(CLEAN_COLUMNS_RE, '').split(',')
96
+
97
+ value_parser.parse(_values) { |values|
98
+ block[:insert, name, _table, _columns, values]
99
+ } unless _columns.empty?
100
+ end
101
+ }
102
+
103
+ @name, @table = name, table
104
+
105
+ self
106
+ end
107
+
108
+ end
109
+
110
+ class ValueParser
111
+
112
+ AST = Struct.new(:value)
113
+
114
+ def self.parse(input)
115
+ new.parse(input)
116
+ end
117
+
118
+ def parse(input)
119
+ @input = StringScanner.new(input)
120
+
121
+ rows, block_given = [], block_given?
122
+
123
+ while result = parse_row
124
+ row = result.value
125
+ block_given ? yield(row) : rows << row
126
+ break unless @input.scan(/,\s*/)
127
+ end
128
+
129
+ @input.scan(/;/) # optional
130
+
131
+ error('Unexpected data') unless @input.eos?
132
+
133
+ rows unless block_given
134
+ end
135
+
136
+ def parse_row
137
+ return unless @input.scan(/\(/)
138
+
139
+ row = []
140
+
141
+ while result = parse_value
142
+ row << result.value
143
+ break unless @input.scan(/,\s*/)
144
+ end
145
+
146
+ error('Unclosed row') unless @input.scan(/\)/)
147
+
148
+ AST.new(row)
149
+ end
150
+
151
+ def parse_value
152
+ parse_string ||
153
+ parse_number ||
154
+ parse_keyword
155
+ end
156
+
157
+ def parse_string
158
+ return unless @input.scan(/'/)
159
+
160
+ string = ''
161
+
162
+ while contents = parse_string_content || parse_string_escape
163
+ string << contents.value
164
+ end
165
+
166
+ error('Unclosed string') unless @input.scan(/'/)
167
+
168
+ AST.new(string)
169
+ end
170
+
171
+ def parse_string_content
172
+ if @input.scan(/[^\\']+/)
173
+ AST.new(@input.matched)
174
+ end
175
+ end
176
+
177
+ def parse_string_escape
178
+ if @input.scan(/\\[abtnvfr]/)
179
+ AST.new(eval(%Q{"#{@input.matched}"}))
180
+ elsif @input.scan(/\\.|''/)
181
+ AST.new(@input.matched[-1, 1])
182
+ end
183
+ end
184
+
185
+ def parse_number
186
+ if @input.scan(/-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/)
187
+ AST.new(eval(@input.matched))
188
+ end
189
+ end
190
+
191
+ def parse_keyword
192
+ if @input.scan(/null/i)
193
+ AST.new(nil)
194
+ end
195
+ end
196
+
197
+ def error(message)
198
+ if @input.eos?
199
+ raise "Unexpected end of input (#{message})."
200
+ else
201
+ raise "#{message} at #{$.}:#{@input.pos}: #{@input.peek(16).inspect}"
202
+ end
203
+ end
204
+
205
+ end
206
+
207
+ end
208
+
209
+ end
@@ -7,7 +7,7 @@
7
7
  # Copyright (C) 2007-2011 Jens Wille #
8
8
  # #
9
9
  # Authors: #
10
- # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # Jens Wille <jens.wille@gmail.com> #
11
11
  # #
12
12
  # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
13
  # under the terms of the GNU Affero General Public License as published by #
@@ -7,7 +7,7 @@
7
7
  # Copyright (C) 2007-2011 Jens Wille #
8
8
  # #
9
9
  # Authors: #
10
- # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # Jens Wille <jens.wille@gmail.com> #
11
11
  # #
12
12
  # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
13
  # under the terms of the GNU Affero General Public License as published by #
@@ -3,8 +3,8 @@ module Nuggets
3
3
  module Version
4
4
 
5
5
  MAJOR = 0
6
- MINOR = 8
7
- TINY = 9
6
+ MINOR = 9
7
+ TINY = 0
8
8
 
9
9
  class << self
10
10
 
data/lib/nuggets.rb CHANGED
@@ -6,7 +6,7 @@
6
6
  # Copyright (C) 2007-2011 Jens Wille #
7
7
  # #
8
8
  # Authors: #
9
- # Jens Wille <jens.wille@uni-koeln.de> #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
10
  # #
11
11
  # ruby-nuggets is free software; you can redistribute it and/or modify it #
12
12
  # under the terms of the GNU Affero General Public License as published by #
@@ -0,0 +1,52 @@
1
+ require 'nuggets/array/boost'
2
+
3
+ describe Array, 'when extended by', Nuggets::Array::BoostMixin do
4
+
5
+ it { Array.ancestors.should include(Nuggets::Array::BoostMixin) }
6
+
7
+ example {
8
+ lambda { [].boost_factor([]) }.should raise_error(NoMethodError)
9
+ }
10
+
11
+ example {
12
+ lambda { [1].boost_factor([]) }.should raise_error(NoMethodError)
13
+ }
14
+
15
+ example {
16
+ lambda { [].boost_factor([1]) }.should raise_error(TypeError)
17
+ }
18
+
19
+ example {
20
+ a, b = [0].boof([0]), Float::NAN
21
+
22
+ a.class.should == b.class
23
+ a.to_s.should == b.to_s
24
+ }
25
+
26
+ example {
27
+ 1.step(100, 10) { |i| [i].boof([0]).should == -1 }
28
+ }
29
+
30
+ example {
31
+ 1.step(100, 10) { |i| [0].boof([i]).should == Float::INFINITY }
32
+ }
33
+
34
+ example {
35
+ a, b = [1.5, 1.6, 1.4], [0.7, 0.8, 0.8]
36
+
37
+ a.boof(b).should equal_float(-0.48888888888888893)
38
+ a.boof(b, &:max).should equal_float(-0.5)
39
+ a.boof(b, &:geomean).should equal_float(-0.4891270450709646)
40
+ a.boof(b) { |x| x.inject(:-) }.should equal_float(-0.3999999999999999)
41
+ }
42
+
43
+ [
44
+ [[1], [1], :mean],
45
+ [[1], [1, 2, 3], :mean],
46
+ [[1.5, 1.6, 1.4], [0.7, 0.8, 0.8], :mean],
47
+ [[1.5, 1.6, 1.4], [0.7, 0.8, 0.8], :geomean]
48
+ ].each { |a, b, m|
49
+ example { a.boost(a.boof(b, &m)).send(m).should equal_float(b.send(m)) }
50
+ }
51
+
52
+ end
@@ -37,4 +37,20 @@ describe Array, 'when extended by', Nuggets::Array::RegressionMixin do
37
37
  }
38
38
  }
39
39
 
40
+ [
41
+ [],
42
+ [0],
43
+ [1, 1],
44
+ [1, 2, 4, -2],
45
+ [2.3, 1.6, 0.9, 0.2],
46
+ [1, 2, -1, 3, -2, 4, -3]
47
+ ].each { |a|
48
+ example {
49
+ a.llsq.zip(a.llsqi.to_a).each { |(x1, y1), (x2, y2)|
50
+ x1.should == x2
51
+ y1.should equal_float(y2)
52
+ }
53
+ }
54
+ }
55
+
40
56
  end
@@ -0,0 +1,38 @@
1
+ require 'nuggets/hash/seen'
2
+
3
+ describe Hash, 'when extended by', Nuggets::Hash::SeenMixin do
4
+
5
+ it { (class << Hash; self; end).ancestors.should include(Nuggets::Hash::SeenMixin) }
6
+
7
+ example do
8
+ hash = Hash.seen
9
+ hash.should be_an_instance_of(Hash)
10
+
11
+ hash[:a].should be_false
12
+ hash.should have_key(:a)
13
+
14
+ hash[:a].should be_true
15
+ hash[:a].should be_true
16
+ end
17
+
18
+ example do
19
+ hash = Hash.seen(0, 1)
20
+ hash.should be_an_instance_of(Hash)
21
+
22
+ hash[:a].should == 1
23
+ hash.should have_key(:a)
24
+
25
+ hash[:a].should == 0
26
+ hash[:a].should == 0
27
+ end
28
+
29
+ example do
30
+ hash = Hash.seen.update(:a => :b)
31
+ hash.should be_an_instance_of(Hash)
32
+
33
+ hash[:a].should == :b
34
+ hash[:a].should == :b
35
+ hash.should have_key(:a)
36
+ end
37
+
38
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  $:.unshift('lib') unless $:.first == 'lib'
2
2
 
3
+ Float::NAN = 0 / 0.0 unless Float.const_defined?(:NAN)
4
+ Float::INFINITY = 1 / 0.0 unless Float.const_defined?(:INFINITY)
5
+
3
6
  RSpec.configure { |config|
4
7
  config.include(Module.new {
5
8
  def equal_float(value, precision = 1.0e-14)