tagen 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -32,7 +32,42 @@ use extra extension
32
32
  require "pathname"
33
33
  require "tagen/pathname"
34
34
 
35
- add #path method to Pathname, see API doc.
35
+ or
36
+
37
+ require "tagen/pathname" # auto require "pathname"
38
+
39
+ this will add #path method to Pathname, see API doc.
40
+
41
+ An Introduction to Pa
42
+ ---------------------
43
+
44
+ require "tagen/core"
45
+ pa = Pa('/home/foo')
46
+ pa.exists? #=> false
47
+ pa.dir #=> '/home'
48
+ pa.base #=> 'foo'
49
+ pa.join('a.ogg') #=> '/home/a.ogg'
50
+ pa.join(a.ogg).exists? #=> true.
51
+
52
+ Pa.exists?('/home/foo') # alternate way
53
+
54
+ which rspec
55
+
56
+ Pa('/home/foo').should be_exists
57
+
58
+ more see API doc
59
+
60
+ An Introduction to PyFormat
61
+ ---------------------------
62
+
63
+ require "tagen/core"
64
+ "I like %{fruit} and %{sport}".format('apple', 'football')
65
+ "I like %{fruit} and %{sport}".format(apple: 'apple', footbal: 'football')
66
+
67
+ "it costs %{howmatch:.2f} dollars".format(1.123) #=> "it costs 1.12 dollars"
68
+
69
+ more see API doc
70
+
36
71
 
37
72
  Documentation
38
73
  -------------
data/Rakefile CHANGED
@@ -6,11 +6,18 @@ task :release do
6
6
  sh "rm *.gem"
7
7
  end
8
8
 
9
- desc "testing the library"
9
+ desc "autotest with watchr"
10
10
  task :test do
11
11
  sh "watchr tagen.watchr"
12
12
  end
13
13
 
14
+ namespace :test do
15
+ desc "testing the whole library"
16
+ task :all do
17
+ sh "rspec --color spec"
18
+ end
19
+ end
20
+
14
21
  def sh cmd
15
22
  puts cmd
16
23
  system cmd
data/TODO ADDED
@@ -0,0 +1 @@
1
+ * Pa support home path. e.g. '~/.vimrc'
@@ -1,3 +1,4 @@
1
+ require "audioinfo"
1
2
  =begin
2
3
  * **gem**: ruby-audioinfo
3
4
  =end
@@ -1,3 +1,5 @@
1
+ require "cairo"
2
+
1
3
  # gdk_pixbuf2 for
2
4
  # Context#set_source
3
5
  # set_source_pixbuf
@@ -19,6 +19,8 @@ require "pd"
19
19
  core/object
20
20
  core/module
21
21
 
22
+ core/enumerable
23
+ core/enumerator
22
24
  core/numeric
23
25
  core/string
24
26
  core/array
@@ -38,4 +38,62 @@ class Array
38
38
  end
39
39
  indexs.length==1 ? values[0] : values
40
40
  end
41
+
42
+
43
+ # first n values, not works at Range, Range don't have #replace method
44
+ # @note modify IN PLACE
45
+ #
46
+ # @example
47
+ # a = %w(1 2 3)
48
+ # a.first!(2) #=> [1, 2]
49
+ # a #=> [3]
50
+ # @return Array
51
+ def first! n=1
52
+ i = 0
53
+ j = i + n
54
+ k = -1
55
+
56
+ ret = self[i...j]
57
+ self.replace self[j..k]
58
+ ret
59
+ end
60
+
61
+ # last n values
62
+ # @see first!
63
+ def last! n=1
64
+ i = -1
65
+ j = -1 - n + 1
66
+ k = 0
67
+
68
+ ret = self[j..i]
69
+ self.replace self[k...j]
70
+ ret
71
+ end
72
+
73
+
74
+
75
+ # same as find, but delete the finded value
76
+ def find! &blk
77
+ idx = self.find_index(&blk)
78
+ if idx
79
+ self.delete_at(idx)
80
+ else
81
+ nil
82
+ end
83
+ end
84
+
85
+ # same as find_all, but delete all finded values
86
+ def find_all! &blk
87
+ ret, rest = [], []
88
+ self.each do |k|
89
+ if blk.call(k)
90
+ ret << k
91
+ else
92
+ rest << k
93
+ end
94
+ end
95
+ self.replace rest
96
+ ret
97
+ end
98
+
41
99
  end # class Array
@@ -0,0 +1,20 @@
1
+ =begin
2
+
3
+ == enumerate it
4
+
5
+ * collect{k,v} Array#map!
6
+ * each_cons(n),{}=>nil each_slice
7
+
8
+ == retrive value
9
+ * [slice]
10
+ * first/last(),(n) Array#first!
11
+ * find{} find_index(v),{} find_all Array#find! Array#find_all!
12
+ * grep(obj),{=>v}
13
+
14
+ * Array#delete(v) delete_at(i) clear()
15
+
16
+ =end
17
+ module Enumerable
18
+
19
+
20
+ end
@@ -0,0 +1,29 @@
1
+ class Enumerator
2
+ # combine with_index and with_object
3
+ # @see with_index, with_object
4
+ #
5
+ # @example
6
+ # (1..7).each.with_iobject([]){|(*args), idx, memo|}
7
+ # (1..7).each.with_iobject(2, []){|(*args), idx, memo|} # offset is 2
8
+ #
9
+ # @overload with_iobject(*args)
10
+ # @param [Fixnum,Object] *args pass Fixnum as offset, otherwise as memo_obj
11
+ # @return Enumerator
12
+ #
13
+ # @overload with_iobject(*args)
14
+ # @yieldparam [Object] (*args)
15
+ # @yieldparam [Fixnum] idx index
16
+ # @yieldparam [Object] memo_obj
17
+ def with_iobject *args, &blk
18
+ return self.to_enum(:with_iobject, *args) unless blk
19
+
20
+ offset = args.find!{|v| Fixnum===v} || 0
21
+ raise ArgumentError "must provide memo_obj" if args.empty?
22
+ memo = args[0]
23
+
24
+ i = offset-1
25
+ self.with_object memo do |args, m|
26
+ blk.call args,i+=1,m
27
+ end
28
+ end
29
+ end
@@ -2,20 +2,21 @@ class Module
2
2
 
3
3
  alias :original_append_features :append_features
4
4
 
5
- # after include module, convert methods in ClassMethods to class methods.
5
+ # after include module, convert methods in ClassMethods to class methods. a very clean design.
6
6
  # @see ruby-core Module#append_features
7
7
  #
8
8
  # @example
9
9
  # module Guten
10
10
  # module ClassMethods
11
- # def foo; end # after include Guten, method 'foo' becomes a class method.
11
+ # def foo; end # this is class method.
12
12
  # end
13
+ #
14
+ # def bar; end # this is instance method.
13
15
  # end
14
16
  #
15
17
  # class Tag
16
- # include Guten
18
+ # include Guten # will auto Tag.extend(Guten::Classmethods)
17
19
  # end
18
- # Tag.foo
19
20
  #
20
21
  def append_features base
21
22
  original_append_features base
@@ -1,4 +1,4 @@
1
- =begin
1
+ =begin rdoc
2
2
  Pa(Path) is similary to Pathname, but more powerful.
3
3
  it combines fileutils, tmpdir, find, tempfile, File, Dir, Pathname
4
4
 
@@ -53,58 +53,37 @@ Example3:
53
53
  name n filename of a path
54
54
  ext e extname of a path, return "" or "ogg"
55
55
  fext fe return "" or ".ogg"
56
- =end
57
56
 
57
+ == used with rspec
58
+
59
+ File.exists?(path).should be_true
60
+ Pa(path).should be_exists
61
+
62
+ =end
58
63
  class Pa
59
64
  Error = Class.new Exception
60
65
  EUnkonwType = Class.new Error
61
66
 
62
- attr_accessor :path
63
- attr_reader :absolute, :dir, :base, :name, :ext, :fext
64
- alias p path
65
- alias a absolute
66
- alias d dir
67
- alias b base
68
- alias n name
69
- alias e ext
70
- alias fe fext
71
-
72
- # @param [String,Pa,Pathname] path
73
- # @api also used by replace
67
+ attr_reader :path
68
+
69
+ # @param [String,#path] path
74
70
  def initialize path
75
- @path = case path.class.to_s
76
- when "Pathname"
77
- path.to_s
78
- when "Pa"
79
- path.path
80
- when "String"
81
- path
82
- else
83
- raise ArgumentError, path.inspect
84
- end
85
- @absolute = Pa.absolute(@path)
86
- @dir = Pa.dirname(@path)
87
- @base = Pa.basename(@path)
88
- @name, @ext = Pa.basename(@path, ext: true)
89
- @fext = @ext.empty? ? "" : "."+@ext
71
+ @path = path.respond_to?(:path) ? path.path : path
72
+ initialize_variables
90
73
  end
91
74
 
92
- # @param [String,Pa,Pathname]
93
- # @return [Pa] the same Pa object
94
- def replace path
95
- initialize path
75
+ chainable = Module.new do
76
+ def initialize_variables; end
96
77
  end
78
+ include chainable
97
79
 
98
- # add string to path
99
- #
100
- # @example
101
- # pa = Pa('/home/foo/a.txt')
102
- # pa+'~' #=> new Pa('/home/foo/a.txt~')
103
- #
104
- # @param [String] str
105
- # @return [Pa]
106
- def + str
107
- Pa(@path+str)
80
+ alias p path
81
+
82
+ # @param [String,#path]
83
+ # @return [Pa] the same Pa object
84
+ def replace path
85
+ @path = path.respond_to?(:path) ? path.path : path
86
+ initialize_variables
108
87
  end
109
88
 
110
89
  # return '#<Pa @path="foo", @absolute="/home/foo">'
@@ -112,7 +91,7 @@ class Pa
112
91
  # @return [String]
113
92
  def inspect
114
93
  ret="#<" + self.class.to_s + " "
115
- ret += "@path=\"#{@path}\", @absolute=\"#{@absolute}\""
94
+ ret += "@path=\"#{path}\", @absolute=\"#{absolute}\""
116
95
  ret += " >"
117
96
  ret
118
97
  end
@@ -124,53 +103,52 @@ class Pa
124
103
  @path
125
104
  end
126
105
 
127
- # join path
128
- #
129
- # param [String] *names
130
- # return [Pa]
131
- def join(*names)
132
- Pa(Pa.join(@path, *names))
133
- end
106
+ # missing method goes to Pa.class-method
107
+ def method_missing(name, *args, &blk)
108
+ ret = self.class.__send__(name, path, *args, &blk)
134
109
 
135
- # get parent path
136
- #
137
- # return [Pa]
138
- def parent
139
- Pa(Pa.join(@path, '..'))
140
- end
110
+ case ret
141
111
 
112
+ # e.g. readlink ..
113
+ when String
114
+ Pa(ret)
115
+
116
+ # e.g. directory?
117
+ else
118
+ ret
119
+ end
142
120
 
143
- # missing method goes to Pa.class-method
144
- # return@ [Pa,..] return Pa for some methods.
145
- def method_missing(name, *args, &blk)
146
- ret = self.class.__send__(name, *args, @path, &blk)
147
- [ :readlink ]
148
- .include?(name) ? Pa(ret) : ret
149
121
  end
150
- end
151
122
 
152
123
 
153
- require_relative "pa/path"
154
- require_relative "pa/cmd"
155
- require_relative "pa/dir"
156
- require_relative "pa/state"
124
+ end
125
+
157
126
  class Pa
158
- class << self
127
+ module ClassMethods
128
+ UNDEFS = [:open, :fstat]
159
129
 
160
130
  # missing method goes to File class method
161
131
  def method_missing name, *args, &blk
162
- return if args.size>1
132
+ raise NoMethodError, name.inspect if UNDEFS.include?(name)
133
+ return if args.size>1
163
134
  File.__send__ name, get(args[0]), &blk
164
135
  end
165
-
166
136
  end
167
137
  end
168
138
 
139
+ require_relative "pa/path"
140
+ require_relative "pa/cmd"
141
+ require_relative "pa/dir"
142
+ require_relative "pa/state"
169
143
  class Pa
170
- extend Path
171
- extend Directory
172
- extend State
173
- extend Cmd
144
+ extend ClassMethods
145
+ extend ClassMethods::Path
146
+ extend ClassMethods::Dir
147
+ extend ClassMethods::State
148
+ extend ClassMethods::Cmd
149
+
150
+ include Path
151
+ include State
174
152
  end
175
153
 
176
154
  module Kernel
@@ -9,7 +9,7 @@ rm family
9
9
  rmdir path # it's clear: remove a directory
10
10
  =end
11
11
  class Pa
12
- module Cmd
12
+ module ClassMethods::Cmd
13
13
 
14
14
  # chroot
15
15
  # @see {Dir.chroot}
@@ -39,14 +39,12 @@ module Cmd
39
39
  def _touch(paths, o)
40
40
  o[:mode] ||= 0644
41
41
  paths.map!{|v|get(v)}
42
- paths.each {|p|
43
- if exists?(p)
44
- o[:force] ? next : raise(Errno::EEXIST, "File exist -- #{p}")
42
+ paths.each {|path|
43
+ if File.exists?(path)
44
+ o[:force] ? next : raise(Errno::EEXIST, "File exist -- #{path}")
45
45
  end
46
46
 
47
- if o[:mkdir]
48
- mkdir(dirname(p))
49
- end
47
+ mkdir(File.dirname(p)) if o[:mkdir]
50
48
 
51
49
  if win32?
52
50
  # win32 BUG. must f.write("") then file can be deleted.
@@ -137,9 +135,9 @@ module Cmd
137
135
  collision = 0
138
136
  path = "#{o[:dir]}/#{o[:prefix]}#{$$}-#{(Time.time*100_000).to_i.to_s(36)}"
139
137
  orgi_path = path.dup
140
- while exists?(path)
141
- path = orgi_path+ collision.to_s
142
- collision +=1
138
+ while File.exists?(path)
139
+ path = orgi_path+ collision.to_s
140
+ collision +=1
143
141
  end
144
142
  path << o[:suffix]
145
143
 
@@ -153,7 +151,7 @@ module Cmd
153
151
  # @return [nil]
154
152
  def rm(*paths)
155
153
  glob(*paths) { |pa|
156
- next if not pa.exists?
154
+ next if not File.exists?(pa.p)
157
155
  File.delete(pa.p)
158
156
  }
159
157
  end
@@ -164,7 +162,7 @@ module Cmd
164
162
  # @return [nil]
165
163
  def rmdir *paths
166
164
  glob(*paths) { |pa|
167
- raise Errno::ENOTDIR, "-- #{pa}" if not pa.directory?
165
+ raise Errno::ENOTDIR, "-- #{pa}" if not File.directory?(pa.p)
168
166
  _rmdir(pa)
169
167
  }
170
168
  end
@@ -175,8 +173,8 @@ module Cmd
175
173
  # @return [nil]
176
174
  def rm_r(*paths)
177
175
  glob(*paths){ |pa|
178
- next if not pa.exists?
179
- pa.directory? ? _rmdir(pa) : File.delete(pa.p)
176
+ next if not File.exists?(pa.p)
177
+ File.directory?(pa.p) ? _rmdir(pa) : File.delete(pa.p)
180
178
  }
181
179
  end
182
180
 
@@ -201,11 +199,11 @@ module Cmd
201
199
  # I'm recusive
202
200
  # param@ [Pa] path
203
201
  def _rmdir(pa, o={})
204
- return if not pa.exists?
202
+ return if not File.exists?(pa.p)
205
203
  pa.each {|pa1|
206
- pa1.directory? ? _rmdir(pa1, o) : File.delete(pa1.p)
204
+ File.directory?(pa1.p) ? _rmdir(pa1, o) : File.delete(pa1.p)
207
205
  }
208
- pa.directory? ? Dir.rmdir(pa.p) : File.delete(pa.p)
206
+ File.directory?(pa.p) ? Dir.rmdir(pa.p) : File.delete(pa.p)
209
207
  end
210
208
  private :_rmdir
211
209
 
@@ -233,25 +231,26 @@ module Cmd
233
231
  # @option o [Boolean] :verbose puts cmd when execute
234
232
  # @option o [Boolean] :folsymlink follow symlink
235
233
  # @option o [Boolean] :overwrite overwrite dest file if dest is a file
234
+ # @option o [Boolean] :special special copy, when cp a directory, only mkdir, not cp the directory's content, usefull in Pa.each_r
236
235
  # @return [nil]
237
236
  # @overload cp(src_s, dest, o)
238
237
  # @yield [src,dest,o]
239
238
  # @return [nil]
240
239
  def cp(src_s, dest, o={}, &blk)
241
- srcs = glob(*Array.wrap(src_s))
242
- dest = Pa(dest)
240
+ srcs = glob(*Array.wrap(src_s)).map{|v| v.path}
241
+ dest = Pa.get(dest)
243
242
 
244
- if o[:mkdir] and (not dest.exists?)
245
- mkdir dest
243
+ if o[:mkdir] and (not File.exists?(dest))
244
+ Pa.mkdir dest
246
245
  end
247
246
 
248
247
  # cp file1 file2 .. dir
249
- if srcs.size>1 and (not dest.directory?)
248
+ if srcs.size>1 and (not File.directory?(dest))
250
249
  raise Errno::ENOTDIR, "dest not a directory when cp more than one src -- #{dest}"
251
250
  end
252
251
 
253
252
  srcs.each do |src|
254
- dest1 = dest.directory? ? dest.join(src.b) : dest
253
+ dest1 = File.directory?(dest) ? File.join(dest, File.basename(src)) : dest
255
254
 
256
255
  if blk
257
256
  blk.call src, dest1, o, proc{_copy(src, dest1, o)}
@@ -265,41 +264,49 @@ module Cmd
265
264
 
266
265
  # I'm recursive
267
266
  #
268
- # @param [Pa] src
269
- # @param [Pa] dest
267
+ # @param [String] src
268
+ # @param [String] dest
270
269
  def _copy(src, dest, o={})
271
- raise Errno::EEXIST, "dest exists -- #{dest}" if dest.exists? and (not o[:overwrite])
270
+ raise Errno::EEXIST, "dest exists -- #{dest}" if File.exists?(dest) and (not o[:overwrite])
271
+
272
+
273
+ case type=File.ftype(src)
272
274
 
273
- case type=src.type
274
275
  when "file", "socket"
275
276
  puts "cp #{src} #{dest}" if o[:verbose]
276
- File.copy_stream(src.p, dest.p)
277
+ File.copy_stream(src, dest)
278
+
277
279
  when "directory"
278
280
  begin
279
- mkdir dest
281
+ Pa.mkdir dest
280
282
  puts "mkdir #{dest}" if o[:verbose]
281
283
  rescue Errno::EEXIST
282
284
  end
285
+
286
+ return if o[:special]
287
+
283
288
  each(src) { |pa|
284
- _copy(pa, dest.join(pa.b), o)
289
+ _copy(pa.p, File.join(dest, File.basename(pa.p)), o)
285
290
  }
286
- when "symlink"
291
+
292
+ when "link" # symbol link
287
293
  if o[:folsymlink]
288
- _copy(src.readlink, dest)
294
+ _copy(Pa.readlink(src), dest)
289
295
  else
290
- symln(src.readlink, dest, force: true)
296
+ Pa.symln(Pa.readlink(src), dest, force: true)
291
297
  puts "symlink #{src} #{dest}" if o[:verbose]
292
298
  end
299
+
293
300
  when "unknow"
294
301
  raise EUnKnownType, "Can't handle unknow type(#{:type}) -- #{src}"
295
302
  end
296
303
 
297
304
  # chmod chown utime
298
- src_stat = o[:folsymlink] ? stat(src) : lstat(src)
305
+ src_stat = o[:folsymlink] ? File.stat(src) : File.lstat(src)
299
306
  begin
300
- chmod(src_stat.mode, dest)
301
- chown(src_stat.uid, src_stat.gid, dest)
302
- utime(src_stat.atime, src_stat.mtime, dest)
307
+ File.chmod(src_stat.mode, dest)
308
+ #File.chown(src_stat.uid, src_stat.gid, dest)
309
+ File.utime(src_stat.atime, src_stat.mtime, dest)
303
310
  rescue Errno::ENOENT
304
311
  end
305
312
  end # _copy
@@ -314,20 +321,20 @@ module Cmd
314
321
  # @option o [Boolean] :overwrite
315
322
  # @return [nil]
316
323
  def mv(src_s, dest, o={}, &blk)
317
- srcs = glob(*Array.wrap(src_s))
318
- dest = Pa(dest)
324
+ srcs = glob(*Array.wrap(src_s)).map{|v| get(v)}
325
+ dest = get(dest)
319
326
 
320
- if o[:mkdir] and (not dest.exists?)
327
+ if o[:mkdir] and (not File.exists?(dest))
321
328
  mkdir dest
322
329
  end
323
330
 
324
331
  # mv file1 file2 .. dir
325
- if srcs.size>1 and (not dest.directory?)
332
+ if srcs.size>1 and (not File.directory?(dest))
326
333
  raise Errno::ENOTDIR, "dest not a directory when mv more than one src -- #{dest}"
327
334
  end
328
335
 
329
336
  srcs.each do |src|
330
- dest1 = dest.directory? ? dest.join(src.b) : dest
337
+ dest1 = File.directory?(dest) ? File.join(dest, File.basename(src)) : dest
331
338
 
332
339
  if blk
333
340
  blk.call src, dest1, o, proc{_move(src, dest1, o)}
@@ -342,27 +349,27 @@ module Cmd
342
349
  #
343
350
  # _move "file", "dir/file"
344
351
  #
345
- # @param [Pa] src
346
- # @param [Pa] dest
352
+ # @param [String] src
353
+ # @param [String] dest
347
354
  def _move(src, dest, o)
348
- raise Errno::EEXIST, "dest exists -- #{dest}" if dest.exists? and (not o[:overwrite])
355
+ raise Errno::EEXIST, "dest exists -- #{dest}" if File.exists?(dest) and (not o[:overwrite])
349
356
 
350
357
  # overwrite. mv "dir", "dira" and 'dira' exists and is a directory.
351
- if dest.exists? and dest.directory?
358
+ if File.exists?(dest) and File.directory?(dest)
352
359
  ls(src) { |pa|
353
- dest1 = dest.join(pa.b)
354
- _move pa, dest1, o
360
+ dest1 = File.join(dest, File.basename(pa.p))
361
+ _move pa.p, dest1, o
355
362
  }
356
- rm_r src
363
+ Pa.rm_r src
357
364
 
358
365
  else
359
366
  begin
360
- rm_r dest if o[:overwrite] and dest.exists?
367
+ Pa.rm_r dest if o[:overwrite] and File.exists?(dest)
361
368
  puts "rename #{src} #{dest}" if o[:verbose]
362
- File.rename(src.p, dest.p)
369
+ File.rename(src, dest)
363
370
  rescue Errno::EXDEV # cross-device
364
371
  _copy(src, dest, o)
365
- rm_r src
372
+ Pa.rm_r src
366
373
  end
367
374
 
368
375
  end