rmtools 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/Manifest.txt +84 -26
- data/Rakefile +7 -4
- data/ext/extconf.rb +1 -1
- data/ext/rmtools.cpp +27 -12
- data/ext/rmtools.h +6 -5
- data/lib/rmtools/b.rb +18 -0
- data/lib/rmtools/console/coloring.rb +72 -0
- data/lib/rmtools/console/highlight.rb +13 -0
- data/lib/rmtools/{printing.rb → console/printing.rb} +17 -2
- data/lib/rmtools/console.rb +1 -0
- data/lib/rmtools/conversions/enum.rb +23 -0
- data/lib/rmtools/conversions/int.rb +47 -0
- data/lib/rmtools/conversions/string.rb +26 -0
- data/lib/rmtools/conversions.rb +1 -0
- data/lib/rmtools/core/arguments.rb +52 -0
- data/lib/rmtools/{boolean.rb → core/boolean.rb} +0 -13
- data/lib/rmtools/core/class.rb +41 -0
- data/lib/rmtools/core/js.rb +45 -0
- data/lib/rmtools/core/kernel.rb +28 -0
- data/lib/rmtools/{module.rb → core/module.rb} +0 -41
- data/lib/rmtools/core/numeric.rb +35 -0
- data/lib/rmtools/{object.rb → core/object.rb} +2 -23
- data/lib/rmtools/core/proc.rb +18 -0
- data/lib/rmtools/core/regexp.rb +11 -0
- data/lib/rmtools/core/string_compliance.rb +31 -0
- data/lib/rmtools/core.rb +1 -0
- data/lib/rmtools/db/active_record.rb +54 -0
- data/lib/rmtools/db.rb +7 -0
- data/lib/rmtools/debug/binding.rb +56 -0
- data/lib/rmtools/debug/highlight.rb +23 -0
- data/lib/rmtools/debug/logging.rb +176 -0
- data/lib/rmtools/debug/present.rb +38 -0
- data/lib/rmtools/debug/timer.rb +19 -0
- data/lib/rmtools/debug/traceback.rb +92 -0
- data/lib/rmtools/debug.rb +1 -0
- data/lib/rmtools/debug_notrace.rb +1 -0
- data/lib/rmtools/enumerable/array.rb +134 -0
- data/lib/rmtools/enumerable/array_iterators.rb +33 -0
- data/lib/rmtools/enumerable/common.rb +49 -0
- data/lib/rmtools/{hash.rb → enumerable/hash.rb} +8 -8
- data/lib/rmtools/enumerable/object_space.rb +19 -0
- data/lib/rmtools/enumerable/range.rb +201 -0
- data/lib/rmtools/enumerable.rb +1 -0
- data/lib/rmtools/experimental/blackhole.rb +12 -0
- data/lib/rmtools/experimental/deprecation.rb +36 -0
- data/lib/rmtools/experimental/dumps.rb +28 -0
- data/lib/rmtools/{numeric.rb → experimental/numeric.rb} +22 -51
- data/lib/rmtools/experimental/rails_backtrace.rb +29 -0
- data/lib/rmtools/experimental/string.rb +56 -0
- data/lib/rmtools/{tree.rb → experimental/tree.rb} +0 -0
- data/lib/rmtools/experimental.rb +1 -0
- data/lib/rmtools/fs/dir.rb +89 -0
- data/lib/rmtools/fs/file.rb +104 -0
- data/lib/rmtools/fs/io.rb +58 -0
- data/lib/rmtools/fs/tools.rb +49 -0
- data/lib/rmtools/fs.rb +1 -0
- data/lib/rmtools/functional/fold.rb +32 -0
- data/lib/rmtools/{string_to_proc.rb → functional/string_to_proc.rb} +2 -22
- data/lib/rmtools/functional/unfold.rb +16 -0
- data/lib/rmtools/functional.rb +1 -0
- data/lib/rmtools/ip/numeric.rb +35 -0
- data/lib/rmtools/ip/string.rb +45 -0
- data/lib/rmtools/ip.rb +1 -0
- data/lib/rmtools/lang/ansi.rb +17 -0
- data/lib/rmtools/lang/cyrillic.rb +106 -0
- data/lib/rmtools/lang/regexp.rb +8 -0
- data/lib/rmtools/lang/shortcuts.rb +20 -0
- data/lib/rmtools/lang.rb +1 -0
- data/lib/rmtools/rand/array.rb +39 -0
- data/lib/rmtools/rand/enum.rb +26 -0
- data/lib/rmtools/rand/range.rb +13 -0
- data/lib/rmtools/{random.rb → rand/string.rb} +13 -107
- data/lib/rmtools/rand.rb +1 -0
- data/lib/rmtools/require.rb +13 -0
- data/lib/rmtools/setup.rb +6 -5
- data/lib/rmtools/text/string_parse.rb +60 -0
- data/lib/rmtools/{stringscanner.rb → text/string_scanner.rb} +3 -2
- data/lib/rmtools/text/string_simple.rb +75 -0
- data/lib/rmtools/text/string_split.rb +148 -0
- data/lib/rmtools/text/textilize.rb +44 -0
- data/lib/rmtools/text.rb +1 -0
- data/lib/rmtools/time/global.rb +17 -0
- data/lib/rmtools/time/russian.rb +47 -0
- data/lib/rmtools/time.rb +1 -32
- data/lib/rmtools/xml/document.rb +28 -0
- data/lib/rmtools/xml/finders.rb +84 -0
- data/lib/rmtools/xml/libxml.rb +11 -0
- data/lib/rmtools/xml/node.rb +196 -0
- data/lib/rmtools/xml/string.rb +43 -0
- data/lib/rmtools/xml/xpath.rb +32 -0
- data/lib/rmtools/xml.rb +7 -0
- data/lib/rmtools.rb +8 -44
- metadata +97 -72
- data/lib/rmtools/arguments.rb +0 -24
- data/lib/rmtools/array.rb +0 -189
- data/lib/rmtools/binding.rb +0 -23
- data/lib/rmtools/coloring.rb +0 -82
- data/lib/rmtools/cyr-time.rb +0 -49
- data/lib/rmtools/cyrilic.rb +0 -124
- data/lib/rmtools/dumps.rb +0 -192
- data/lib/rmtools/enum.rb +0 -90
- data/lib/rmtools/io.rb +0 -303
- data/lib/rmtools/js.rb +0 -25
- data/lib/rmtools/limited_string.rb +0 -17
- data/lib/rmtools/logging.rb +0 -158
- data/lib/rmtools/proc.rb +0 -25
- data/lib/rmtools/range.rb +0 -100
- data/lib/rmtools/string.rb +0 -276
- data/lib/rmtools/traceback.rb +0 -106
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class String
|
3
|
+
|
4
|
+
def bytes
|
5
|
+
arr = []
|
6
|
+
each_byte {|b| arr << b.hex}
|
7
|
+
arr
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_limited len=100
|
11
|
+
LimitedString.new self, len
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class Indent < String
|
17
|
+
attr_reader :indent
|
18
|
+
|
19
|
+
def initialize(indent=' ')
|
20
|
+
@indent = indent
|
21
|
+
super ''
|
22
|
+
end
|
23
|
+
|
24
|
+
def +@
|
25
|
+
self << @indent
|
26
|
+
end
|
27
|
+
|
28
|
+
def -@
|
29
|
+
self.chomp! @indent
|
30
|
+
end
|
31
|
+
|
32
|
+
def i(&block)
|
33
|
+
+self
|
34
|
+
res = yield
|
35
|
+
-self
|
36
|
+
res
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# Compact string inspect
|
42
|
+
class LimitedString < String
|
43
|
+
attr_reader :len
|
44
|
+
__init__
|
45
|
+
|
46
|
+
def initialize str="", len=100
|
47
|
+
@len = len
|
48
|
+
super str
|
49
|
+
end
|
50
|
+
|
51
|
+
def inspect
|
52
|
+
@len ||= 100
|
53
|
+
size > @len ? String.new(self[0...@len]+"…").inspect : super
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
require_with_path __FILE__, '*'
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_with_path 'fs/file'
|
2
|
+
|
3
|
+
class Dir
|
4
|
+
|
5
|
+
def include?(name)
|
6
|
+
#content.map {|f| File.split(f)[1]}.include? name
|
7
|
+
entries.include? name
|
8
|
+
end
|
9
|
+
|
10
|
+
def recursive_content(flat=true)
|
11
|
+
list = []
|
12
|
+
cont = content.map {|f|
|
13
|
+
if File.directory?(f)
|
14
|
+
rc = Dir.new(f).recursive_content.map {|f| f.sub(/^\.\//, '')}
|
15
|
+
flat ? list.concat(rc) : rc
|
16
|
+
else flat ? (list << f) : f
|
17
|
+
end
|
18
|
+
}
|
19
|
+
(flat ? list : cont)
|
20
|
+
end
|
21
|
+
|
22
|
+
def content
|
23
|
+
list = Dir["#{path}/**"]
|
24
|
+
list.empty? ? to_a[2..-1].sort.map {|c| File.join path, c} : list
|
25
|
+
end
|
26
|
+
|
27
|
+
def parent
|
28
|
+
newpath = File.dirname(path)
|
29
|
+
Dir.new(newpath) if newpath != path
|
30
|
+
end
|
31
|
+
|
32
|
+
def child(idx)
|
33
|
+
df = content[idx]
|
34
|
+
if File.file?(df)
|
35
|
+
File.new(df)
|
36
|
+
elsif File.directory?(df)
|
37
|
+
Dir.new(df)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def children
|
42
|
+
content.map {|df|
|
43
|
+
if File.file?(df)
|
44
|
+
File.new(df)
|
45
|
+
elsif File.directory?(df)
|
46
|
+
Dir.new(df)
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def refresh
|
52
|
+
return if !File.directory?(path)
|
53
|
+
Dir.new(path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
displaypath = case path
|
58
|
+
when /^(\/|\w:)/ then path
|
59
|
+
when /^\./ then File.join(Dir.pwd, path[1..-1])
|
60
|
+
else File.join(Dir.pwd, path)
|
61
|
+
end
|
62
|
+
"<#Dir \"#{displaypath}\" #{to_a.size - 2} elements>"
|
63
|
+
end
|
64
|
+
|
65
|
+
def name
|
66
|
+
File.basename(path)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Fixing windoze path problems
|
70
|
+
# requires amatch gem for better performance
|
71
|
+
def real_name
|
72
|
+
n, p, count = name, parent, []
|
73
|
+
return n if !p
|
74
|
+
pp, pc, sc = parent.path, parent.to_a[2..-1], to_a
|
75
|
+
if defined? Amatch
|
76
|
+
ms = pc.sizes.max
|
77
|
+
count = [:hamming_similar, :levenshtein_similar, :jaro_similar].sum {|m| pc.group_by {|_| _.upcase.ljust(ms).send(m, n)}.max[1]}.count.to_a
|
78
|
+
max = count.lasts.max
|
79
|
+
res = count.find {|c|
|
80
|
+
c[1] == max and File.directory?(df=File.join(pp, c[0])) and Dir.new(df).to_a == sc
|
81
|
+
}
|
82
|
+
return res[0] if res
|
83
|
+
end
|
84
|
+
(pc - count).find {|c|
|
85
|
+
File.directory?(df=File.join(pp, c)) and Dir.new(df).to_a == sc
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require_with_path 'fs/io'
|
2
|
+
|
3
|
+
class File
|
4
|
+
|
5
|
+
def inspect
|
6
|
+
"<#File \"#{path}\" #{closed? ? 'closed' : stat.size.bytes}>"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.include?(name, str)
|
10
|
+
f = new name, 'r'
|
11
|
+
incl = f.include? str
|
12
|
+
f.close
|
13
|
+
incl
|
14
|
+
end
|
15
|
+
|
16
|
+
def include?(str)
|
17
|
+
while s = gets do return true if s.include? str end
|
18
|
+
end
|
19
|
+
|
20
|
+
def parent
|
21
|
+
newpath = File.dirname(path)
|
22
|
+
Dir.new(newpath) if newpath != path
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
File.basename(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def ext
|
30
|
+
name[/[^.]+$/]
|
31
|
+
end
|
32
|
+
|
33
|
+
def refresh
|
34
|
+
return if !File.file?(path)
|
35
|
+
close
|
36
|
+
File.new(path,'r')
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.modify(file, bak=true)
|
40
|
+
orig_text = read file
|
41
|
+
text = yield orig_text
|
42
|
+
rename file, file+'.bak' if bak
|
43
|
+
RMTools.rw(file, text.is(String) ? text : orig_text)
|
44
|
+
end
|
45
|
+
|
46
|
+
def cp(df)
|
47
|
+
dir = File.dirname df
|
48
|
+
FileUtils.mkpath dir unless File.directory? dir
|
49
|
+
FileUtils.cp path, df
|
50
|
+
end
|
51
|
+
|
52
|
+
def mv(df)
|
53
|
+
dir = File.dirname df
|
54
|
+
FileUtils.mkpath dir unless File.directory? dir
|
55
|
+
rename df
|
56
|
+
end
|
57
|
+
|
58
|
+
# Fixing windoze path problems
|
59
|
+
# requires amatch gem for better performance
|
60
|
+
def real_name
|
61
|
+
n, p, count = name, parent, []
|
62
|
+
pp, pc, ss = parent.path, parent.to_a[2..-1], stat
|
63
|
+
ms = pc.sizes.max
|
64
|
+
n, ext = n.rsplit('.', 2)
|
65
|
+
if ext
|
66
|
+
re = /\.#{ext}$/i
|
67
|
+
pc.reject! {|f| !f[re]}
|
68
|
+
end
|
69
|
+
if defined? Amatch
|
70
|
+
count = [:hamming_similar, :levenshtein_similar, :jaro_similar].sum {|m| pc.group_by {|f| (ext ? f[0..-(ext.size+2)] : f).upcase.ljust(ms).send(m, n)}.max[1]}.count.to_a
|
71
|
+
max = count.lasts.max
|
72
|
+
res = count.find {|c|
|
73
|
+
c[1] == max and File.file?(df=File.join(pp, c[0])) and File.stat(df) == ss
|
74
|
+
}
|
75
|
+
return res[0] if res
|
76
|
+
end
|
77
|
+
(pc - count).find {|c|
|
78
|
+
File.file?(df=File.join(pp, c)) and File.stat(df) == ss
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
PathMemo = {} if !defined? PathMemo
|
83
|
+
def self.real_path path, memo=1
|
84
|
+
a = expand_path(path).split(/[\/\\]/)
|
85
|
+
a.each_index {|i|
|
86
|
+
if a[j=-(i+1)]['~']
|
87
|
+
n = i+2>a.size ? a[j] : join(a[0..-(i+2)], a[j])
|
88
|
+
a[j] = PathMemo[n] || real_name(n)
|
89
|
+
PathMemo[n] = a[j] if memo
|
90
|
+
else break
|
91
|
+
end
|
92
|
+
}
|
93
|
+
a*'/'
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.real_name(df)
|
97
|
+
if file?(df)
|
98
|
+
new(df).real_name
|
99
|
+
elsif directory?(df)
|
100
|
+
Dir.new(df).real_name
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
class IO
|
5
|
+
|
6
|
+
def gets2
|
7
|
+
str = ''
|
8
|
+
str << (c = read 1) until c and "\r\n\b".include? c or eof?
|
9
|
+
str
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
module RMTools
|
15
|
+
|
16
|
+
def rw(df, value=nil)
|
17
|
+
return false if value.nil?
|
18
|
+
df.gsub!('\\', '/')
|
19
|
+
path = File.dirname(df)
|
20
|
+
FileUtils.mkpath(path) if !File.directory?(path)
|
21
|
+
mode = RUBY_VERSION > '1.9' ? :wb : 'wb'
|
22
|
+
File.open(df, mode) {|f| f << value}
|
23
|
+
value.size
|
24
|
+
end
|
25
|
+
|
26
|
+
def write(df, value='', pos=0)
|
27
|
+
return false if value.nil?
|
28
|
+
df.gsub!('\\', '/')
|
29
|
+
path = File.dirname(df)
|
30
|
+
FileUtils.mkpath(path) if !File.directory?(path)
|
31
|
+
if pos == 0
|
32
|
+
mode = RUBY_VERSION > '1.9' ? :ab : 'ab'
|
33
|
+
File.open(df, mode) {|f| f << value}
|
34
|
+
else
|
35
|
+
if pos < 0
|
36
|
+
if !File.file?(df)
|
37
|
+
raise IndexError, "file #{df} does not exist, can't write from position #{pos}"
|
38
|
+
elsif (size = File.size(df)) < -pos
|
39
|
+
raise IndexError, "file #{df} is shorter than #{(-pos).bytes}, can't write from position #{pos}"
|
40
|
+
end
|
41
|
+
pos = size - pos
|
42
|
+
end
|
43
|
+
File.open(df, 'r+') {|f| f.pos = pos; f << value}
|
44
|
+
end
|
45
|
+
value.size
|
46
|
+
end
|
47
|
+
|
48
|
+
def read(df, mode=(RUBY_VERSION > '1.9' ? :rb : 'rb'))
|
49
|
+
df.gsub!('\\', '/')
|
50
|
+
if File.file?(df)
|
51
|
+
File.open(df, mode) {|f| f.read}
|
52
|
+
else
|
53
|
+
STDERR.puts "#{df} is missed!"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module_function :rw, :write, :read
|
58
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_with_path 'fs/io'
|
2
|
+
|
3
|
+
module RMTools
|
4
|
+
|
5
|
+
def tail(file, bytes=1000)
|
6
|
+
if File.file?(file)
|
7
|
+
IO.read(file, bytes, File.size(file)-bytes)
|
8
|
+
else
|
9
|
+
STDERR.puts "#{file} is missed!"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def tail_n(file, qty=10)
|
14
|
+
if !File.file?(file)
|
15
|
+
return STDERR.puts "#{file} is missed!"
|
16
|
+
end
|
17
|
+
size = File.size(file)
|
18
|
+
lines = []
|
19
|
+
strlen = 0
|
20
|
+
step = qty*100
|
21
|
+
while qty > 0 and (offset = size-strlen-step) >= 0 and (str = IO.read(file, step, offset)).b
|
22
|
+
i = str.index("\n") || str.size
|
23
|
+
strlen += step - i
|
24
|
+
new_lines = str[i+1..-1]/"\n"
|
25
|
+
qty -= new_lines.size
|
26
|
+
lines = new_lines.concat(lines)
|
27
|
+
end
|
28
|
+
lines[-qty..-1]
|
29
|
+
end
|
30
|
+
|
31
|
+
def read_lines(df, *lines)
|
32
|
+
return if !lines or lines.empty?
|
33
|
+
str = ""
|
34
|
+
last = lines.max
|
35
|
+
if File.file?(df)
|
36
|
+
File.open(df, 'r') {|f|
|
37
|
+
f.each {|line|
|
38
|
+
no = f.lineno
|
39
|
+
str << line if no.in lines
|
40
|
+
break if no == last
|
41
|
+
}}
|
42
|
+
str
|
43
|
+
else
|
44
|
+
STDERR.puts "#{df} is missed!"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module_function :tail, :tail_n, :read_lines
|
49
|
+
end
|
data/lib/rmtools/fs.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_with_path __FILE__, '*'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
def foldl(o, m=nil)
|
4
|
+
case o
|
5
|
+
when Proc
|
6
|
+
block_given? ?
|
7
|
+
reduce(m && yield(m)) {|m, i| m ? o.call(m, yield(i)) : yield(i)} :
|
8
|
+
reduce(m) {|m, i| m ? o.call(m, i) : i}
|
9
|
+
when Symbol
|
10
|
+
block_given? ?
|
11
|
+
reduce(m && yield(m)) {|m, i| m ? m.send(o, yield(i)) : yield(i)} :
|
12
|
+
reduce(m) {|m, i| m ? m.send(o, i) : i}
|
13
|
+
else TypeError! o, Proc, Symbol
|
14
|
+
end
|
15
|
+
end
|
16
|
+
alias :fold :foldl
|
17
|
+
|
18
|
+
def foldr(o, m=nil)
|
19
|
+
case o
|
20
|
+
when Proc
|
21
|
+
block_given? ?
|
22
|
+
reverse.reduce(m && yield(m)) {|m, i| m ? o.call(yield(i), m) : yield(i)} :
|
23
|
+
reverse.reduce(m) {|m, i| m ? o.call(i, m) : i}
|
24
|
+
when Symbol
|
25
|
+
block_given? ?
|
26
|
+
reverse.reduce(m && yield(m)) {|m, i| m ? yield(i).send(o, m) : yield(i)} :
|
27
|
+
reverse.reduce(m) {|m, i| m ? i.send(o, m) : i}
|
28
|
+
else TypeError! o, Proc, Symbol
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -9,25 +9,6 @@
|
|
9
9
|
#
|
10
10
|
# (c) 2007 Reginald Braithwaite
|
11
11
|
# Portions Copyright (c) 2006 Oliver Steele
|
12
|
-
#
|
13
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
14
|
-
# a copy of this software and associated documentation files (the
|
15
|
-
# "Software"), to deal in the Software without restriction, including
|
16
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
17
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
19
|
-
# the following conditions:
|
20
|
-
#
|
21
|
-
# The above copyright notice and this permission notice shall be
|
22
|
-
# included in all copies or substantial portions of the Software.
|
23
|
-
#
|
24
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
25
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
27
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
28
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
29
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
30
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
12
|
|
32
13
|
|
33
14
|
class String
|
@@ -70,7 +51,7 @@ class String
|
|
70
51
|
RMTools::String_to_proc_cache = {}
|
71
52
|
def to_proc &block
|
72
53
|
# improving performance
|
73
|
-
if
|
54
|
+
if proc = RMTools::String_to_proc_cache[[self, block]]
|
74
55
|
return proc
|
75
56
|
end
|
76
57
|
params = []
|
@@ -103,8 +84,7 @@ class String
|
|
103
84
|
end
|
104
85
|
Proc.eval "|#{params.join(', ')}| #{expr}", block && block.binding
|
105
86
|
end
|
106
|
-
RMTools::String_to_proc_cache[self]
|
107
|
-
proc
|
87
|
+
RMTools::String_to_proc_cache[[self, block]] ||= proc
|
108
88
|
end
|
109
89
|
|
110
90
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
# &splitter must return a pair
|
4
|
+
def unfold(break_if=lambda{|x|x==0}, &splitter)
|
5
|
+
obj, container = self, []
|
6
|
+
until begin
|
7
|
+
result = splitter[obj]
|
8
|
+
container.unshift result[1]
|
9
|
+
break_if[result[0]]
|
10
|
+
end
|
11
|
+
obj = result[0]
|
12
|
+
end
|
13
|
+
container
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_with_path __FILE__, '*'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Integer
|
2
|
+
|
3
|
+
def from_ip
|
4
|
+
self
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_ip
|
8
|
+
"#{(self >> 24) & 0xff}.#{(self >> 16) & 0xff}.#{(self >> 8) & 0xff}.#{self & 0xff}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def mask_ip(val)
|
12
|
+
if val < 0
|
13
|
+
maskv = 32+val
|
14
|
+
else
|
15
|
+
maskv = val
|
16
|
+
val = 32 - val
|
17
|
+
end
|
18
|
+
self - (self & 2**val - 1)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
class Range
|
24
|
+
|
25
|
+
def mask_ip
|
26
|
+
i = nil
|
27
|
+
31.downto(12) {|i|
|
28
|
+
lm = last.mask_ip(i)
|
29
|
+
break if first.mask_ip(i) == lm and (last+1).mask_ip(i) != lm
|
30
|
+
i = nil
|
31
|
+
}
|
32
|
+
i || 32
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'scanf'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
def from_ip(range=nil)
|
6
|
+
int = to_i
|
7
|
+
return int if int.to_s == self
|
8
|
+
if range
|
9
|
+
arr = []
|
10
|
+
split(' - ').each {|s|
|
11
|
+
res = s.scanf '%d.%d.%d.%d'
|
12
|
+
arr << (res[0] << 24) + (res[1] << 16) + (res[2] << 8) + res[3]
|
13
|
+
}
|
14
|
+
"ip between #{arr[0]} and #{arr[1]}"
|
15
|
+
else
|
16
|
+
res = scanf '%d.%d.%d.%d'
|
17
|
+
(res[0] << 24) + (res[1] << 16) + (res[2] << 8) + res[3]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_ip
|
22
|
+
from_ip.to_ip
|
23
|
+
end
|
24
|
+
|
25
|
+
def mask_ip(val)
|
26
|
+
int = from_ip
|
27
|
+
if val < 0
|
28
|
+
maskv = 32+val
|
29
|
+
else
|
30
|
+
maskv = val
|
31
|
+
val = 32 - val
|
32
|
+
end
|
33
|
+
"#{(int - (int & 2**val - 1)).to_ip}/#{maskv}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def scan_ip
|
37
|
+
scan(/(\d+\.\d+\.\d+\.\d+)(?::(\d+))?/)
|
38
|
+
end
|
39
|
+
|
40
|
+
def parseips
|
41
|
+
deprecation "Use #scan_ip"
|
42
|
+
scan_ip
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/rmtools/ip.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_with_path __FILE__, '*'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'iconv'
|
2
|
+
|
3
|
+
module RMTools
|
4
|
+
ANSI2UTF = Iconv.new("UTF-8", "WINDOWS-1251").method :iconv
|
5
|
+
UTF2ANSI = Iconv.new("WINDOWS-1251", "UTF-8").method :iconv
|
6
|
+
|
7
|
+
module Cyrillic
|
8
|
+
RU_LETTERS = "абвгдеёжзийклмнопрстуфхцчшщьыъэюя", "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ"
|
9
|
+
|
10
|
+
if RUBY_VERSION >= '1.9'
|
11
|
+
ANSI_LETTERS_UC = ["\270\340-\377", "\250\300-\337"].force_encodings "Windows-1251"
|
12
|
+
ANSI_LETTERS_DC = ANSI_LETTERS_UC.reverse
|
13
|
+
ANSI_YOYE = ["\270\250", "\345\305"].force_encodings "Windows-1251"
|
14
|
+
ANSI_ENCODING = ANSI_LETTERS_UC[0].encoding
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require_with_path 'lang/ansi'
|
2
|
+
|
3
|
+
class String
|
4
|
+
include RMTools::Cyrillic
|
5
|
+
|
6
|
+
def cyr_ic
|
7
|
+
gsub(/[ёЁ]/, '[ёЁ]').gsub(/[йЙ]/, '[йЙ]').gsub(/[цЦ]/, '[цЦ]').gsub(/[уУ]/, '[уУ]').gsub(/[кК]/, '[кК]').gsub(/[еЕ]/, '[еЕ]').gsub(/[нН]/, '[нН]').gsub(/[гГ]/, '[гГ]').gsub(/[шШ]/, '[шШ]').gsub(/[щЩ]/, '[щЩ]').gsub(/[зЗ]/, '[зЗ]').gsub(/[хХ]/, '[хХ]').gsub(/[ъЪ]/, '[ъЪ]').gsub(/[фФ]/, '[фФ]').gsub(/[ыЫ]/, '[ыЫ]').gsub(/[вВ]/, '[вВ]').gsub(/[аА]/, '[аА]').gsub(/[пП]/, '[пП]').gsub(/[рР]/, '[рР]').gsub(/[оО]/, '[оО]').gsub(/[лЛ]/, '[лЛ]').gsub(/[дД]/, '[дД]').gsub(/[жЖ]/, '[жЖ]').gsub(/[эЭ]/, '[эЭ]').gsub(/[яЯ]/, '[яЯ]').gsub(/[чЧ]/, '[чЧ]').gsub(/[сС]/, '[сС]').gsub(/[мМ]/, '[мМ]').gsub(/[иИ]/, '[иИ]').gsub(/[тТ]/, '[тТ]').gsub(/[ьЬ]/, '[ьЬ]').gsub(/[бБ]/, '[бБ]').gsub(/[юЮ]/, '[юЮ]')
|
8
|
+
end
|
9
|
+
alias :ci :cyr_ic
|
10
|
+
|
11
|
+
def translit
|
12
|
+
gsub(/[ёЁ]/, 'yo').gsub(/[йЙ]/, 'y').gsub(/[цЦ]/, 'c').gsub(/[уУ]/, 'u').gsub(/[кК]/, 'k').gsub(/[еЕ]/, 'e').gsub(/[нН]/, 'n').gsub(/[гГ]/, 'g').gsub(/[шШ]/, 'sh').gsub(/[щЩ]/, 'sch').gsub(/[зЗ]/, 'z').gsub(/[хХ]/, 'h').gsub(/[ьЬъЪ]/, "'").gsub(/[фФ]/, 'f').gsub(/[иИыЫ]/, 'i').gsub(/[вВ]/, 'v').gsub(/[аА]/, 'a').gsub(/[пП]/, 'p').gsub(/[рР]/, 'r').gsub(/[оО]/, 'o').gsub(/[лЛ]/, 'l').gsub(/[дД]/, 'd').gsub(/[жЖ]/, 'j').gsub(/[эЭ]/, 'e').gsub(/[яЯ]/, 'ya').gsub(/[чЧ]/, 'ch').gsub(/[сС]/, 's').gsub(/[мМ]/, 'm').gsub(/[тТ]/, 't').gsub(/[бБ]/, 'b').gsub(/[юЮ]/, 'yu')
|
13
|
+
end
|
14
|
+
|
15
|
+
def swap
|
16
|
+
sub(/([a-zA-Z])|([а-яА-ЯёЁ])/) {|m| return $~[1]? en2ru: ru2en}
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def caps?
|
21
|
+
self =~ /^[А-ЯЁ][А-ЯЁ\d ]+$/
|
22
|
+
end
|
23
|
+
|
24
|
+
def cyr?
|
25
|
+
self !~ /[^а-яА-ЯёЁ]/
|
26
|
+
end
|
27
|
+
|
28
|
+
def csqueeze
|
29
|
+
ANSI2UTF[UTF2ANSI[self].squeeze]
|
30
|
+
end
|
31
|
+
|
32
|
+
if RUBY_VERSION >= "1.9"
|
33
|
+
|
34
|
+
def ru2en
|
35
|
+
tr "ёйцукенгшщзхъфывапролдэячсмить/.ю?,б\"№;:жЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИВТЬБЮ", "`qwertyuiop[]asdfghjkl'zxcvbnm|/.&?,@\#$^;~QWERTYUIOP{}ASDFGHJKL:\"ZXCVBDNM<>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def en2ru
|
39
|
+
tr "`qwertyuiop[]asdfghjkl;:'zxcvbnm,./|?\"@\#$^&~QWERTYUIOP{}ASDFGHJKLZXCVBNM<>", "ёйцукенгшщзхъфывапролджЖэячсмитьбю./,Э\"№;:?ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЯЧСМИТЬБЮ"
|
40
|
+
end
|
41
|
+
|
42
|
+
def cupcase
|
43
|
+
encoding != ANSI_ENCODING ?
|
44
|
+
ANSI2UTF[UTF2ANSI[self].tr(*ANSI_LETTERS_UC)]:
|
45
|
+
tr(*ANSI_LETTERS_UC)
|
46
|
+
end
|
47
|
+
|
48
|
+
def cdowncase
|
49
|
+
encoding != ANSI_ENCODING ?
|
50
|
+
ANSI2UTF[UTF2ANSI[self].tr(*ANSI_LETTERS_DC)]:
|
51
|
+
tr(*ANSI_LETTERS_DC)
|
52
|
+
end
|
53
|
+
|
54
|
+
def ccap
|
55
|
+
self[0].cupcase + self[1..-1]
|
56
|
+
end
|
57
|
+
|
58
|
+
def cuncap
|
59
|
+
self[0].cdowncase + self[1..-1]
|
60
|
+
end
|
61
|
+
|
62
|
+
def rmumlaut
|
63
|
+
encoding != ANSI_ENCODING ?
|
64
|
+
ANSI2UTF[UTF2ANSI[self].tr(*ANSI_YOYE)]:
|
65
|
+
tr(*ANSI_YOYE)
|
66
|
+
end
|
67
|
+
|
68
|
+
else
|
69
|
+
|
70
|
+
def cupcase(encode=1)
|
71
|
+
encode ?
|
72
|
+
ANSI2UTF[UTF2ANSI[self].tr("\270\340-\377", "\250\300-\337")]:
|
73
|
+
tr("\270\340-\377", "\250\300-\337")
|
74
|
+
end
|
75
|
+
|
76
|
+
def cdowncase(encode=1)
|
77
|
+
encode ?
|
78
|
+
ANSI2UTF[UTF2ANSI[self].tr("\250\300-\337", "\270\340-\377")]:
|
79
|
+
tr("\250\300-\337", "\270\340-\377")
|
80
|
+
end
|
81
|
+
|
82
|
+
def ccap(encode=1)
|
83
|
+
self[0,2].cupcase(encode) + self[2..-1]
|
84
|
+
end
|
85
|
+
|
86
|
+
def cuncap(encode=1)
|
87
|
+
self[0,2].cdowncase(encode) + self[2..-1]
|
88
|
+
end
|
89
|
+
|
90
|
+
def rmumlaut(encode=1)
|
91
|
+
encode ?
|
92
|
+
ANSI2UTF[UTF2ANSI[self].tr("\270\250", "\345\305")]:
|
93
|
+
tr("\270\250", "\345\305")
|
94
|
+
end
|
95
|
+
|
96
|
+
def ru2en
|
97
|
+
gsub("ё", "`").gsub("й", "q").gsub("ц", "w").gsub("у", "e").gsub("к", "r").gsub("е", "t").gsub("н", "y").gsub("г", "u").gsub("ш", "i").gsub("щ", "o").gsub("з", "p").gsub("х", "[").gsub("ъ", "]").gsub("ф", "a").gsub("ы", "s").gsub("в", "d").gsub("а", "f").gsub("п", "g").gsub("р", "h").gsub("о", "j").gsub("л", "k").gsub("д", "l").gsub("э", "'").gsub("я", "z").gsub("ч", "x").gsub("с", "c").gsub("м", "v").gsub("и", "b").gsub("т", "n").gsub("ь", "m").gsub("/", "|").gsub(".", "/").gsub("ю", ".").gsub("?", "&").gsub(",", "?").gsub("б", ",").gsub("\"", "@").gsub("№", "#").gsub(";", "$").gsub(":", "^").gsub("ж", ";").gsub("Ё", "~").gsub("Й", "Q").gsub("Ц", "W").gsub("У", "E").gsub("К", "R").gsub("Е", "T").gsub("Н", "Y").gsub("Г", "U").gsub("Ш", "I").gsub("Щ", "O").gsub("З", "P").gsub("Х", "{").gsub("Ъ", "}").gsub("Ф", "A").gsub("Ы", "S").gsub("В", "D").gsub("А", "F").gsub("П", "G").gsub("Р", "H").gsub("О", "J").gsub("Л", "K").gsub("Д", "L").gsub("Ж", ":").gsub("Э", "\"").gsub("Я", "Z").gsub("Ч", "X").gsub("С", "C").gsub("М", "V").gsub("И", "B").gsub("Т", "N").gsub("Ь", "M").gsub("Б", "<").gsub("Ю", ">")
|
98
|
+
end
|
99
|
+
|
100
|
+
def en2ru
|
101
|
+
gsub("`", "ё").gsub("q", "й").gsub("w", "ц").gsub("e", "у").gsub("r", "к").gsub("t", "е").gsub("y", "н").gsub("u", "г").gsub("i", "ш").gsub("o", "щ").gsub("p", "з").gsub("[", "х").gsub("]", "ъ").gsub("a", "ф").gsub("s", "ы").gsub("d", "в").gsub("f", "а").gsub("g", "п").gsub("h", "р").gsub("j", "о").gsub("k", "л").gsub("l", "д").gsub(";", "ж").gsub(":", "Ж").gsub("'", "э").gsub("z", "я").gsub("x", "ч").gsub("c", "с").gsub("v", "м").gsub("b", "и").gsub("n", "т").gsub("m", "ь").gsub(",", "б").gsub(".", "ю").gsub("/", ".").gsub("|", "/").gsub("?", ",").gsub("\"", "Э").gsub("@", "\"").gsub("#", "№").gsub("$", ";").gsub("^", ":").gsub("&", "?").gsub("~", "Ё").gsub("Q", "Й").gsub("W", "Ц").gsub("E", "У").gsub("R", "К").gsub("T", "Е").gsub("Y", "Н").gsub("U", "Г").gsub("I", "Ш").gsub("O", "Щ").gsub("P", "З").gsub("{", "Х").gsub("}", "Ъ").gsub("A", "Ф").gsub("S", "Ы").gsub("D", "В").gsub("F", "А").gsub("G", "П").gsub("H", "Р").gsub("J", "О").gsub("K", "Л").gsub("L", "Д").gsub("Z", "Я").gsub("X", "Ч").gsub("C", "С").gsub("V", "М").gsub("B", "И").gsub("N", "Т").gsub("M", "Ь").gsub("<", "Б").gsub(">", "Ю")
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|