tagen 1.1.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/.gitignore +4 -1
  2. data/.travis.yml +5 -0
  3. data/CHANGELOG +6 -0
  4. data/Gemfile +2 -3
  5. data/Gemfile.lock +13 -15
  6. data/README.md +20 -39
  7. data/Rakefile +2 -1
  8. data/benchmark/a.rb +14 -0
  9. data/lib/tagen/core.rb +17 -22
  10. data/lib/tagen/core/array.rb +5 -109
  11. data/lib/tagen/core/array/append.rb +3 -0
  12. data/lib/tagen/core/array/delete_values.rb +43 -0
  13. data/lib/tagen/core/array/extract_options.rb +35 -94
  14. data/lib/tagen/core/class.rb +1 -0
  15. data/lib/tagen/core/enumerable.rb +15 -18
  16. data/lib/tagen/core/enumerator.rb +22 -12
  17. data/lib/tagen/core/exception.rb +5 -3
  18. data/lib/tagen/core/file.rb +1 -0
  19. data/lib/tagen/core/hash.rb +4 -39
  20. data/lib/tagen/core/integer.rb +2 -0
  21. data/lib/tagen/core/io.rb +59 -26
  22. data/lib/tagen/core/kernel.rb +5 -64
  23. data/lib/tagen/core/kernel/deprecate.rb +5 -0
  24. data/lib/tagen/core/kernel/platform.rb +46 -0
  25. data/lib/tagen/core/kernel/shell.rb +45 -0
  26. data/lib/tagen/core/module.rb +9 -11
  27. data/lib/tagen/core/numeric.rb +4 -2
  28. data/lib/tagen/core/object.rb +6 -21
  29. data/lib/tagen/core/process.rb +6 -4
  30. data/lib/tagen/core/re.rb +2 -2
  31. data/lib/tagen/core/string.rb +12 -47
  32. data/lib/tagen/core/time.rb +30 -38
  33. data/lib/tagen/erb.rb +10 -8
  34. data/lib/tagen/net/http.rb +33 -29
  35. data/lib/tagen/pathname.rb +1 -5
  36. data/lib/tagen/rbconfig.rb +8 -0
  37. data/lib/tagen/socket.rb +8 -2
  38. data/lib/tagen/uri.rb +9 -0
  39. data/lib/tagen/version.rb +1 -1
  40. data/lib/tagen/vim.rb +8 -8
  41. data/lib/tagen/xmpp4r.rb +23 -23
  42. data/spec/spec_helper.rb +23 -17
  43. data/spec/tagen/core/array/delete_values_spec.rb +19 -0
  44. data/spec/tagen/core/array/extract_options_spec.rb +9 -29
  45. data/spec/tagen/core/enumerable_spec.rb +9 -0
  46. data/spec/tagen/core/enumerator_spec.rb +10 -12
  47. data/spec/tagen/core/exception_spec.rb +14 -9
  48. data/spec/tagen/core/io_spec.rb +20 -0
  49. data/spec/tagen/core/kernel/platform_spec.rb +92 -0
  50. data/spec/tagen/core/kernel/shell_spec.rb +27 -0
  51. data/spec/tagen/core/numeric_spec.rb +10 -0
  52. data/spec/tagen/core/process_spec.rb +14 -0
  53. data/spec/tagen/core/re_spec.rb +9 -0
  54. data/spec/tagen/core/string_spec.rb +9 -0
  55. data/spec/tagen/core/time_spec.rb +6 -51
  56. data/spec/tagen/erb_spec.rb +3 -10
  57. data/spec/tagen/pathname_spec.rb +11 -0
  58. data/spec/tagen/rbconfig_spec.rb +11 -0
  59. data/spec/tagen/socket_spec.rb +7 -5
  60. data/spec/tagen/uri_spec.rb +13 -0
  61. data/tagen.gemspec +3 -4
  62. metadata +45 -51
  63. data/TODO +0 -1
  64. data/docs/Architecture.md +0 -17
  65. data/docs/CoreExtensions.md +0 -40
  66. data/docs/ExtraExtensions.md +0 -20
  67. data/lib/tagen/RMagick.rb +0 -12
  68. data/lib/tagen/audioinfo.rb +0 -22
  69. data/lib/tagen/cairo.rb +0 -811
  70. data/lib/tagen/core/extend_hash.rb +0 -46
  71. data/lib/tagen/core/marshal.rb +0 -34
  72. data/lib/tagen/core/open_option.rb +0 -161
  73. data/lib/tagen/core/string/pyformat.rb +0 -336
  74. data/lib/tagen/core/symbol.rb +0 -8
  75. data/lib/tagen/date.rb +0 -80
  76. data/lib/tagen/gdk_pixbuf2.rb +0 -26
  77. data/lib/tagen/gtk2.rb +0 -122
  78. data/lib/tagen/ncurses.rb +0 -246
  79. data/lib/tagen/poppler.rb +0 -48
  80. data/lib/tagen/tree.rb +0 -77
  81. data/lib/tagen/xmpp4r/roster.rb +0 -20
  82. data/lib/tagen/yaml.rb +0 -38
  83. data/spec/tagen/cairo_spec.rb +0 -137
  84. data/spec/tagen/core/array_spec.rb +0 -42
  85. data/spec/tagen/core/extend_hash_spec.rb +0 -54
  86. data/spec/tagen/core/hash_spec.rb +0 -10
  87. data/spec/tagen/core/module_spec.rb +0 -14
  88. data/spec/tagen/core/open_option_spec.rb +0 -83
  89. data/spec/tagen/core/string/pyformat_spec.rb +0 -98
  90. data/spec/tagen/core/symbol_spec.rb +0 -15
  91. data/spec/tagen/core_spec.rb +0 -6
  92. data/spec/tagen/date_spec.rb +0 -146
@@ -1,46 +0,0 @@
1
- class ExtendHash < Hash
2
- class << self
3
- def [](hash)
4
- case hash
5
- when ExtendHash
6
- hash
7
- when Hash
8
- eh = self.new
9
- eh.replace deep_convert(hash)
10
- else
11
- raise ArgumentError, "must be a Hash or ExtendHash"
12
- end
13
- end
14
-
15
- private
16
- # convert string key to symbol key.
17
- # I'm rescurive
18
- def deep_convert(hash)
19
- ret = {}
20
- hash.each { |k,v|
21
- ret[k.to_sym] = Hash===v ? deep_convert(v) : v
22
- }
23
- ret
24
- end
25
- end
26
-
27
- def []=(key, value)
28
- key = key.to_sym if String === key
29
- super(key, value)
30
- end
31
-
32
- def [](key)
33
- key = key.to_sym if String === key
34
- super(key)
35
- end
36
-
37
- def method_missing(name, *args)
38
- if name =~ /=$/
39
- store(name[0...-1].to_sym, args[0])
40
- elsif has_key?(name)
41
- fetch(name)
42
- else
43
- raise NoMethodError, "-- :#{name}, #{args.inspect}"
44
- end
45
- end
46
- end
@@ -1,34 +0,0 @@
1
- module Marshal
2
- class <<self
3
-
4
- alias :original_load :load
5
-
6
- # add support with Pa
7
- #
8
- # Marshal.load(Pa(path))
9
- #
10
- # @param [IO,String,Pa] obj
11
- # @return [String]
12
- def load(obj) original_load Pa===obj ? File.read(obj.p) : obj end
13
-
14
- alias :original_dump :dump
15
-
16
- # add support with Pa
17
- #
18
- # Marshal.dump(obj, Pa(path))
19
- # dump(con, [obj], limit=-1)
20
- #
21
- # @param [String,Pa] obj
22
- # @return [String]
23
- def dump(obj, *args)
24
- case args[0]
25
- when String, Pa
26
- path = String===args[0] ? args[0] : args[0].p
27
- open(path, "wb"){|f| f.write(original_dump(con))}
28
- else
29
- original_dump con, *args
30
- end
31
- end
32
-
33
- end
34
- end
@@ -1,161 +0,0 @@
1
- =begin
2
-
3
- main purpose of this Class is provide an option support.
4
-
5
- Example:
6
-
7
- o = OpenOption.new
8
- o.name = 'alice'
9
- p o.name #=> 'alice'
10
-
11
- o.force = true
12
- p o.force? #=> true
13
-
14
- Overview:
15
-
16
- o = OpenOption.new
17
-
18
- define value, they are all the same
19
-
20
- o.key = value
21
- o[:symbol] = value
22
- o["string"] = value
23
-
24
- access value, they are all the same
25
-
26
- o[:symbol]
27
- o["string"]
28
- o.key
29
- o.key?
30
-
31
- access hash method, some are special
32
-
33
- o._keys #=> [:a]
34
- o._merge(a: 1) #=> a new <#OpenOption a: 1>
35
- o._merge!(a: 1) #=> self
36
-
37
- access data
38
-
39
- o._data #=> {a: 1}
40
-
41
-
42
- new(data={})
43
- ------------
44
-
45
- data's key can be string or symbol, but internal store key is use symbol.
46
-
47
- data = { "a" => 1 }
48
-
49
- same as
50
-
51
- data = { :a => 1 }
52
-
53
- it is a deep convertion of Hash.
54
-
55
- a = { a: {b: 1} }
56
- o = OpenOption.new(a)
57
- o #=> <#OpenOption a: <#OpenOption b:1> >
58
- # so you can access b by o.a.b
59
-
60
- inheritance
61
- -----------
62
-
63
- class Foo < OpenOption
64
- def initialize data={}
65
- super
66
- @data[:x] = data[:x].to_i
67
- end
68
- end
69
-
70
- =end
71
- class OpenOption
72
-
73
- class <<self
74
- # I'm rescurive
75
- # deep convert hash to OpenOption
76
- def convert_hash data, ret={}
77
- data.each do |k,v|
78
- if Hash === v
79
- new_v = self.new(v)
80
- ret[k.to_sym] = new_v
81
- convert_hash(data[k], ret[k.to_sym])
82
- else
83
- ret[k.to_sym] = v
84
- end
85
- end
86
- ret
87
- end
88
- end
89
-
90
- attr_accessor :_data
91
-
92
- def initialize(data={})
93
- @data = OpenOption.convert_hash(data)
94
- end # def initialize
95
-
96
- def _data() @data end
97
- def _data=(data) @data = data end
98
-
99
- # method return value
100
- # _method goes to Hash
101
- # method? return !!value
102
- # method= define a new key
103
- def method_missing(name, *args, &blk)
104
- if name =~ /^_(.*)/
105
- return @data.send($1.to_sym, *args, &blk)
106
- elsif name =~ /(.*)\?$/
107
- return !!@data[$1.to_sym]
108
- elsif name =~ /(.*)=$/
109
- @data[$1.to_sym] = args[0]
110
- else
111
- return @data[name.to_sym]
112
- end
113
- end
114
-
115
- def marshal_dump
116
- @data
117
- end
118
-
119
- def marshal_load data
120
- @data = data
121
- end
122
-
123
- def ==(other)
124
- return false unless other.kind_of?(self.class)
125
- @data == other._data
126
- end
127
-
128
- def eql?(other) @data == other._data end
129
-
130
- def []=(key, value) @data[key.to_sym] = value end
131
-
132
- def [](key) @data[key.to_sym] end
133
-
134
- def hash() @data.hash end
135
-
136
- def dup
137
- @data.dup
138
- end
139
-
140
- def inspect
141
- out = "#<#{self.class} "
142
- out << @data.map{|k,v| "#{k}: #{v.inspect}"}.join(', ')
143
- out << ">"
144
- end
145
-
146
- alias to_s inspect
147
-
148
- def _replace data
149
- @data = data
150
- end
151
-
152
- def _merge *args
153
- self.class.new @data.merge(*args)
154
- end
155
-
156
- def _merge! *args
157
- @data.merge! *args
158
- return self
159
- end
160
-
161
- end
@@ -1,336 +0,0 @@
1
- =begin rdoc
2
-
3
- == Overview
4
-
5
- a python like string format libraray.
6
-
7
- 1. "this is #{guten}" # Ruby Builtin
8
- 2. "this is %s" % "guten" # Ruby Builtin
9
- 3. "this is %{guten}".format(guten: 'x')
10
-
11
- use "#{var}" is easy and quick in many cases, but some times we need a more powerful format support.
12
-
13
- "I like %s and %s" % %(apple, football)
14
- "I like %{fruit} and %{sport}".format('apple', 'football') # it has semantic meaning.
15
-
16
- == Usage
17
-
18
- require "tagen/core"
19
- "it costs %{:.2f} dollars".format(1.123) #=> "it costs 1.12 dollars"
20
-
21
- * support abritry-argument or hash-argument
22
- "%{} %{}".format(1,2) #=> "1 2"
23
- "%{a} %{b}".format(a:1, b:2) #=> "1 2"
24
- "%{a} %{b}".format(1, b:2) #=> "1 2"
25
-
26
- * escape
27
- "my \\%{name} is %{name}".format("guten") #=> my name is guten.
28
-
29
- == Examples
30
-
31
- "%{:.2f}"
32
- "%{name:.2f}"
33
-
34
- "I'm %{guten} and is #{age} years old".format(guten: "guten") # combine Ruby Buintin with PyFormat
35
-
36
-
37
- == Specification
38
-
39
- format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
40
- fill ::= <a character other than '}'> default is " "
41
- align ::= "<" | ">" | "=" | "^" default is >. = is padding after sign. eg. +000000120
42
- sign ::= "+" | "-" | " "
43
- # ::= <prefix 0b 0o 0x>
44
- 0 ::= <zero_padding> equal to fill is 0
45
- , ::= <comma_sep> also type n
46
- precision ::= string truncate with
47
- type ::= s c b o d x X f/F g/G e/E n %
48
-
49
- f/F fixed point. nan/NAN inf/INF
50
- e/E exponent notation.
51
- g/G gernal format. 1.0 => 1
52
- n number. thounds sep based on local setting
53
-
54
- == Resources
55
-
56
- * http://docs.python.org/py3k/library/string.html#formatstrings
57
-
58
- =end
59
- class PyFormat
60
- Error = Class.new Exception
61
- EFormatSpec = Class.new Error
62
- EFieldName = Class.new Error
63
-
64
- # @param [String] fmt
65
- def initialize fmt
66
- @fmt = fmt
67
- end
68
-
69
- # format a string
70
- #
71
- # @param [Object] *args
72
- # @return [String]
73
- def format *args
74
- # if 'field' in argh
75
- # return argh[field]
76
- # else
77
- # return args.shift
78
- # end
79
-
80
- # args -> argh and args
81
- argh = Hash===args[-1] ? args.pop : {}
82
-
83
- # "%{0:.5f}"
84
- pat = /
85
- \\%{.*?} # esacpe
86
- | %{ (.*?)? (?: :(.*?) )? } # %{0:.f}
87
- /x
88
-
89
- ret = @fmt.gsub(pat) do |m|
90
- if m.start_with? "\\%{"
91
- m
92
- else
93
- field, spec = $1, $2
94
- field = field.to_sym
95
-
96
- if argh.has_key? field
97
- arg = argh[field]
98
- else
99
- arg = args.shift
100
-
101
- # can't use if arg==nil then ..
102
- #
103
- # class Guten
104
- # def <=> other
105
- # "{}".format(self)
106
- # end
107
- #
108
- # => SystemStackError
109
- #
110
- if NilClass === arg then raise EFieldName, "not enought arguments --#{args}" end
111
- end
112
-
113
- Field.parse spec, arg
114
- end
115
- end
116
- ret
117
- end
118
-
119
- class Field
120
- PAT = /^
121
- (?: (?<fill>[^}]+)? (?<align>[<>=^]) )?
122
- (?<sign>[ +-])?
123
- (?<alternate>\#)?
124
- (?<zero_padding>0)?
125
- (?<width>\d+)?
126
- (?<comma_sep>,)?
127
- (?: \.(?<precision>\d+) )?
128
- (?<type>[bcdeEfFgGnosxX%])? /x
129
-
130
-
131
- def self.parse spec, arg
132
- f = self.new
133
- f.parse_spec spec if spec
134
- f.format arg
135
- end
136
-
137
- def initialize
138
- # default options
139
- @o = {
140
- fill: " ",
141
- align: ">",
142
- sign: "-",
143
- alternate: false,
144
- zero_padding: false,
145
- width: 0,
146
- comma_sep: false,
147
- precision: nil,
148
- type: nil,
149
- }
150
- end
151
-
152
- # parse a spec string
153
- #
154
- # parse_spec "this is {:.2f}"
155
- # return @o
156
- #
157
- # @param [String] spec
158
- # @return [nil]
159
- def parse_spec spec
160
- matched = PAT.match(spec)
161
- raise EFormatSpec, spec if not matched
162
- matched = matched.to_hash
163
-
164
- # merge @o and matched
165
- @o.each do |k,v|
166
- @o[k] = matched[k] ? matched[k] : v
167
- end
168
-
169
- # handle keys
170
- @o = @o.each.with_object({}) do |(k,v),o|
171
- case k
172
- when :width, :precision
173
- o[k] = v.to_i if v
174
- when :zero_padding
175
- if v
176
- o[:fill] = "0"
177
- end
178
- when :precision
179
- o[:precision] = 1 if v<1
180
- else
181
- o[k] = v
182
- end
183
- end
184
-
185
- if @o[:align] == "="
186
- @o[:fill] = "0"
187
- @o[:sign] = "+"
188
- end
189
-
190
- end
191
-
192
- # format a <#Field> by @o
193
- #
194
- # @param [Object] arg
195
- # @return [String]
196
- def format arg
197
- # arg is int str ..
198
- # ret is str.
199
-
200
- case arg
201
- when Integer
202
- @o[:type] ||= 'd'
203
- else # default is s
204
- @o[:type] ||= 's'
205
- end
206
-
207
- ret = case @o[:type]
208
- when 's'
209
- arg = arg.to_s
210
- @o[:precision] ? arg[0...@o[:precision]] : arg
211
- when 'c'
212
- arg.chr
213
-
214
- when 'b','o','d','x','X'
215
- arg = arg.to_i
216
-
217
- case @o[:type]
218
- when 'b'
219
- ret1 = arg.to_s 2
220
- ret1 = do_comma ret1
221
- @o[:alternate] ? '0b'+ret1 : ret1
222
- when 'o'
223
- ret1 = arg.to_s 8
224
- ret1 = do_comma ret1
225
- @o[:alternate] ? '0'+ret1 : ret1
226
- when 'd'
227
- ret1 = arg.to_s 10
228
- do_comma ret1
229
- when 'x', 'X'
230
- ret1 = arg.to_s 16
231
- ret1.upcase! if @o[:type]=='X'
232
- ret1 = do_comma ret1
233
- @o[:alternate] ? "0#{@o[:type]}"+ret1 : ret1
234
- end
235
-
236
- # for float, need handle 'precision'
237
- when 'f','F','g','G','e','E', '%'
238
- type = @o[:type]
239
-
240
- num = arg.to_f
241
-
242
- if type=='%'
243
- num = num*100
244
- type = 'g'
245
- elsif type=='F'
246
- type = 'f'
247
- end
248
-
249
- # remove 0 1.00000
250
- if type=='f'
251
- sa, sb = num.to_s.split('.')
252
- prec = sb.length
253
- @o[:precision] = prec if not @o[:precision]
254
- elsif type=='e'
255
- # not implement yet
256
- end
257
-
258
- spec = "%"
259
- spec += '.' + @o[:precision].to_s if @o[:precision]
260
- spec += type
261
-
262
- ret1 = spec % num
263
-
264
- # '%g' % 1.0 => 1
265
-
266
- # 'comma_sep'
267
- if not %w(g G).include? type
268
- a, b = ret1.split('.')
269
- a = do_comma a
270
- ret1 = b==nil ? a : a+'.'+b
271
- end
272
-
273
- ret1 += '%' if @o[:type]=='%'
274
- ret1
275
-
276
- end # case
277
-
278
- ## sign
279
- if @o[:sign] != '-'
280
- sign = arg.to_f>=0 ? @o[:sign] : '-'
281
- ret = sign+ret
282
- end
283
-
284
-
285
- ## width
286
- n = @o[:width] - ret.length
287
- if n > 0
288
- fill = ''
289
- @o[:fill].chars.cycle do |c|
290
- fill << c
291
- break if fill.length == n
292
- end
293
-
294
- ret = case @o[:align]
295
- when '>' then fill + ret
296
- when '<' then ret + fill
297
- when '^' then fill[0...fill.length/2] + ret + fill[fill.length/2..-1]
298
- when '=' then ret[0] + fill + ret[1..-1]
299
- end
300
-
301
- end
302
-
303
-
304
- ret
305
- end # def format
306
-
307
- private
308
- # convert '1234' -> ['1', '234'] -> '1,234'
309
- #
310
- # loop
311
- # [l:h]
312
- # break if h==length
313
- # l = h ; h += 3
314
- def do_comma src
315
- # [l:h]
316
- l = 0
317
- h = (src.length % 3)
318
- srcs = []
319
-
320
- loop do
321
- pice = src[l...h]
322
- srcs << pice if not pice==""
323
- break if h == src.length
324
- l = h ; h += 3
325
- end
326
-
327
- srcs.join ','
328
- end
329
- end # class Field
330
- end # class PyFormat
331
-
332
- class String
333
- def format(*args) PyFormat.new(self).format *args end
334
- end
335
-
336
- # vim:foldnestmax=4