rmtools 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +15 -0
- data/Manifest.txt +37 -0
- data/README.txt +10 -0
- data/Rakefile +39 -0
- data/ext/extconf.rb +12 -0
- data/ext/rmtools.cpp +529 -0
- data/ext/rmtools.h +161 -0
- data/lib/rmtools.rb +53 -0
- data/lib/rmtools/arguments.rb +24 -0
- data/lib/rmtools/array.rb +189 -0
- data/lib/rmtools/binding.rb +23 -0
- data/lib/rmtools/boolean.rb +57 -0
- data/lib/rmtools/coloring.rb +82 -0
- data/lib/rmtools/cyr-time.rb +49 -0
- data/lib/rmtools/cyrilic.rb +124 -0
- data/lib/rmtools/dumps.rb +192 -0
- data/lib/rmtools/enum.rb +90 -0
- data/lib/rmtools/hash.rb +40 -0
- data/lib/rmtools/io.rb +303 -0
- data/lib/rmtools/js.rb +25 -0
- data/lib/rmtools/limited_string.rb +17 -0
- data/lib/rmtools/logging.rb +158 -0
- data/lib/rmtools/module.rb +113 -0
- data/lib/rmtools/numeric.rb +82 -0
- data/lib/rmtools/object.rb +74 -0
- data/lib/rmtools/printing.rb +41 -0
- data/lib/rmtools/proc.rb +25 -0
- data/lib/rmtools/random.rb +195 -0
- data/lib/rmtools/range.rb +100 -0
- data/lib/rmtools/setup.rb +21 -0
- data/lib/rmtools/string.rb +276 -0
- data/lib/rmtools/string_to_proc.rb +113 -0
- data/lib/rmtools/stringscanner.rb +58 -0
- data/lib/rmtools/time.rb +32 -0
- data/lib/rmtools/traceback.rb +106 -0
- data/lib/rmtools/tree.rb +71 -0
- metadata +191 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class LimitedString < String
|
3
|
+
attr_reader :len
|
4
|
+
__init__
|
5
|
+
|
6
|
+
def initialize str="", len=100
|
7
|
+
@len = len
|
8
|
+
super str
|
9
|
+
end
|
10
|
+
|
11
|
+
def inspect
|
12
|
+
@len ||= 100
|
13
|
+
size > @len ? String.new(self[0...@len]+"…").inspect : super
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module RMTools
|
3
|
+
|
4
|
+
class RMLogger
|
5
|
+
__init__
|
6
|
+
attr_accessor :mute_info, :mute_warn, :mute_log, :mute_debug
|
7
|
+
|
8
|
+
RE = /^\(?(.*?([^\/\\]+?))\)?:(\d+)(?::in `([^']+)')?$/
|
9
|
+
Modes = %w{debug log info warn}.to_syms
|
10
|
+
NOPRINT = 4
|
11
|
+
NOLOG = 2
|
12
|
+
INLINE = 1
|
13
|
+
|
14
|
+
def initialize format={}
|
15
|
+
@clr = Coloring.new
|
16
|
+
@highlight = {
|
17
|
+
:warn => @clr.red_bold("WARN"),
|
18
|
+
:log => @clr.cyan("INFO"),
|
19
|
+
:info => @clr.cyan_bold("INFO"),
|
20
|
+
:debug => @clr.gray_bold("DEBUG")
|
21
|
+
}
|
22
|
+
@file_formats = Hash.new(@default_format = {})
|
23
|
+
set_format format, :global
|
24
|
+
end
|
25
|
+
|
26
|
+
def _set_format file, format
|
27
|
+
file.print = !format.q
|
28
|
+
file.out = format.out
|
29
|
+
|
30
|
+
file.path_format = '%'.in file.out if file.out
|
31
|
+
file.tf = (format.time || ["%H:%M:%S", "%03d"]).to_a
|
32
|
+
file.cf0 = format.caller || "#{@clr.gray('%f:%l')} #{@clr.red_bold(':%m')}"
|
33
|
+
file.cf = file.cf0.sub('%F'){'\1'}.sub('%f'){'\2'}.sub('%l'){'\3'}.sub('%m'){'\4'}
|
34
|
+
file.fmt = format.format || "%time %mode [%caller]: %text"
|
35
|
+
file._time, file._caller = '%time'.in(file.fmt), '%caller'.in(file.fmt)
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_format format={}, global=nil
|
39
|
+
if global
|
40
|
+
_set_format @default_format, format
|
41
|
+
else
|
42
|
+
_set_format(file_format={}, format)
|
43
|
+
@file_formats[File.expand_path(caller[0].till ':')] = file_format
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_format file=nil
|
48
|
+
cfg = @file_formats[file && File.expand_path(file)]
|
49
|
+
modes = Modes.reject {|m| send :"mute_#{m}"}
|
50
|
+
%{<Logger #{cfg.fmt.sub('%time', "%time(#{cfg.tf*'.'})").sub('%caller', "%caller(#{cfg.cf0})")}#{' -> '+cfg.out if cfg.out} #{modes.b ? modes.inspect : 'muted'}>}
|
51
|
+
end
|
52
|
+
|
53
|
+
def _print mode, text, opts, caler, bind, cfg
|
54
|
+
log_ = opts&NOLOG==0
|
55
|
+
print_ = opts&NOPRINT==0
|
56
|
+
str = cfg.fmt.dup
|
57
|
+
str.sub! "%mode", @highlight[mode]
|
58
|
+
if bind
|
59
|
+
text = text.reports bind
|
60
|
+
elsif !text.is(String)
|
61
|
+
text = text.inspect
|
62
|
+
end
|
63
|
+
str.sub! "%text", text
|
64
|
+
str << "\n" if opts&INLINE==0
|
65
|
+
out = cfg.out
|
66
|
+
if cfg._time or cfg.path_format
|
67
|
+
now = Time.now
|
68
|
+
if cfg._time
|
69
|
+
time = now.strftime cfg.tf[0]
|
70
|
+
time << ".#{cfg.tf[1]%[now.usec/1000]}" if cfg.tf[1]
|
71
|
+
str.sub! "%time", time
|
72
|
+
end
|
73
|
+
out = now.strftime cfg.out if cfg.path_format
|
74
|
+
end
|
75
|
+
str.sub! "%caller", caler.sub(RE, cfg.cf) if caler
|
76
|
+
log_str = @clr.clean str
|
77
|
+
RMTools.write out, log_str if log_
|
78
|
+
Kernel.print str if print_
|
79
|
+
end
|
80
|
+
|
81
|
+
def check_binding a
|
82
|
+
a[0].is(Binding) ? [a[0], a[1] || 0] : [nil, a[0] || 0]
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_config!
|
86
|
+
@file_formats.empty? ? @default_format : @file_formats[File.expand_path(caller[1].till ':')]
|
87
|
+
end
|
88
|
+
|
89
|
+
# controllers:
|
90
|
+
# - $panic: print debug messages
|
91
|
+
# - $verbose: print log messages
|
92
|
+
# - $quiet: print only warn messages regardless of other globals
|
93
|
+
# - @mute_warn, @mute_info, @mute_log: do not print
|
94
|
+
# this messages regardless of any globals
|
95
|
+
# - @out_all: write to file any messages
|
96
|
+
|
97
|
+
def warn text=nil, *a
|
98
|
+
cfg = get_config!
|
99
|
+
if (cfg.out or cfg.print) && !@mute_warn
|
100
|
+
bind, opts = check_binding a
|
101
|
+
opts |= NOLOG if !cfg.out
|
102
|
+
opts |= NOPRINT if !cfg.print
|
103
|
+
text ||= yield if block_given?
|
104
|
+
_print(:warn, text, opts, cfg._caller && caller[0], bind, cfg)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def log text=nil, *a
|
109
|
+
cfg = get_config!
|
110
|
+
if (cfg.out or cfg.print && !$quiet && $verbose) && !@mute_log
|
111
|
+
bind, opts = check_binding a
|
112
|
+
opts |= NOLOG if !cfg.out
|
113
|
+
opts |= NOPRINT if !(cfg.print && !$quiet && $verbose)
|
114
|
+
text ||= yield if block_given?
|
115
|
+
_print(:log, text, opts, cfg._caller && caller[0], bind, cfg)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def info text=nil, *a
|
120
|
+
cfg = get_config!
|
121
|
+
if (cfg.print && !$quiet or cfg.out && cfg.out_all) && !@mute_info
|
122
|
+
bind, opts = check_binding a
|
123
|
+
opts |= NOLOG if !(cfg.out && cfg.out_all)
|
124
|
+
opts |= NOPRINT if !(cfg.print && !$quiet)
|
125
|
+
text ||= yield if block_given?
|
126
|
+
_print(:info, text, opts, cfg._caller && caller[0], bind, cfg)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def debug text=nil, *a
|
131
|
+
cfg = get_config!
|
132
|
+
if (cfg.print && $panic && !$quiet or cfg.out && cfg.out_all) && !@mute_debug
|
133
|
+
bind, opts = check_binding a
|
134
|
+
opts |= NOLOG if !(cfg.out && cfg.out_all)
|
135
|
+
opts |= NOPRINT if !(cfg.print && $panic && !$quiet)
|
136
|
+
text ||= yield if block_given?
|
137
|
+
_print(:debug, text, opts, cfg._caller && caller[0], bind, cfg)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
alias << info
|
142
|
+
alias < warn
|
143
|
+
|
144
|
+
Modes.each {|m| define_method("#{m}=") {|b| send :"mute_#{m}=", !b}}
|
145
|
+
|
146
|
+
def outall=(x) @default_format.out_all = x end
|
147
|
+
def print=(x) @default_format.print = x end
|
148
|
+
def out=(x) @default_format.out = x end
|
149
|
+
|
150
|
+
def out_all() @default_format.out_all end
|
151
|
+
def print() @default_format.print end
|
152
|
+
def out() @default_format.out end
|
153
|
+
|
154
|
+
def inspect() get_format end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class Module # :nodoc:
|
3
|
+
|
4
|
+
def children
|
5
|
+
constants.map! {|c| module_eval c}.find_all {|c| c.kinda Module rescue()}
|
6
|
+
end
|
7
|
+
|
8
|
+
def each_child
|
9
|
+
constants.map! {|c| module_eval c}.each {|c| yield c if c.kinda Module}
|
10
|
+
constants
|
11
|
+
end
|
12
|
+
|
13
|
+
def self_name
|
14
|
+
@self_name ||= name.rsplit('::', 2)[1] || name
|
15
|
+
end
|
16
|
+
|
17
|
+
def my_methods filter=//
|
18
|
+
self.singleton_methods.sort!.grep(filter)
|
19
|
+
end
|
20
|
+
alias personal_methods my_methods
|
21
|
+
|
22
|
+
private
|
23
|
+
# example:
|
24
|
+
#
|
25
|
+
# def divide_ten_by x
|
26
|
+
# 10 / x
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# def maybe(*args)
|
30
|
+
# yield *args rescue(puts $!)
|
31
|
+
# end
|
32
|
+
# ...
|
33
|
+
#
|
34
|
+
# decorate :divide_ten_by, :maybe # =>
|
35
|
+
# def divide_ten_by x
|
36
|
+
# 10 / x rescue(puts $!)
|
37
|
+
# end
|
38
|
+
def decorate f1, f2
|
39
|
+
f1_clone = f1.to_s.dup
|
40
|
+
f1_clone.bump! '_' while method_defined? f1_clone.to_sym
|
41
|
+
class_eval do
|
42
|
+
alias :"#{f1_clone}" :"#{f1}"
|
43
|
+
define_method(f1) {|*args| send(f2, *args, &method(f1_clone))}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# some FP, example:
|
48
|
+
#
|
49
|
+
# def divide_ten_by x
|
50
|
+
# 10 / x
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# def maybe
|
54
|
+
# lambda {|*args| yield *args rescue(puts $!)}
|
55
|
+
# end
|
56
|
+
# ...
|
57
|
+
#
|
58
|
+
# decorated_fof :divide_ten_by, :maybe # =>
|
59
|
+
# def divide_ten_by
|
60
|
+
# lambda {|x| 10 / x rescue(puts $!)}
|
61
|
+
# end
|
62
|
+
def decorated_fof f1, f2
|
63
|
+
f1_clone = f1.to_s.dup
|
64
|
+
f1_clone.bump! '_' while method_defined? f1_clone
|
65
|
+
class_eval do
|
66
|
+
alias :"#{f1_clone}" :"#{f1}"
|
67
|
+
define_method(f1) {send(f2, &method(f1_clone))}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
class Class
|
74
|
+
|
75
|
+
# define python-like initializer form
|
76
|
+
def __init__
|
77
|
+
modname, classname = name.rsplit('::', 2)
|
78
|
+
classname ||= modname
|
79
|
+
mod = '::'.in(name) ? eval(modname) : RMTools
|
80
|
+
mod.module_eval "def #{classname} *args; #{name}.new *args end
|
81
|
+
module_function :#{classname}"
|
82
|
+
if mod != RMTools
|
83
|
+
mod.each_child {|c| c.class_eval "include #{mod}; extend #{mod}" if !c.in c.children}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_proxy *vars
|
88
|
+
buffered_missing = instance_methods.grep(/method_missing/).sort.last || 'method_missing'
|
89
|
+
# next arg overrides previous
|
90
|
+
vars.each {|v|
|
91
|
+
class_eval "
|
92
|
+
alias #{buffered_missing.bump! '_'} method_missing
|
93
|
+
def method_missing *args, &block
|
94
|
+
#{v}.send *args, &block
|
95
|
+
rescue NoMethodError
|
96
|
+
#{buffered_missing} *args, &block
|
97
|
+
end"
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def personal_methods filter=//
|
102
|
+
(self.singleton_methods - self.superclass.singleton_methods).sort!.grep(filter)
|
103
|
+
end
|
104
|
+
|
105
|
+
def my_instance_methods filter=//
|
106
|
+
(self.public_instance_methods - Object.public_instance_methods).sort!.grep(filter)
|
107
|
+
end
|
108
|
+
|
109
|
+
def personal_instance_methods filter=//
|
110
|
+
(self.public_instance_methods - self.superclass.public_instance_methods).sort!.grep(filter)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class Integer
|
3
|
+
|
4
|
+
def digits
|
5
|
+
nums = []
|
6
|
+
while (int ||= self) > 0
|
7
|
+
nums << int%10
|
8
|
+
int /= 10
|
9
|
+
end
|
10
|
+
nums
|
11
|
+
end
|
12
|
+
|
13
|
+
def mult_of(subj) # allready implemented in ActiveSupport though
|
14
|
+
self%subj == 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def each_bit # descending order
|
18
|
+
to_s(2).each_byte {|b| yield(b == 49)}
|
19
|
+
end
|
20
|
+
|
21
|
+
def blur_bm
|
22
|
+
to_s(2).gsub(/.?1.?/) {|m| m.size==3?'111':'11'}.to_i(2)
|
23
|
+
end
|
24
|
+
|
25
|
+
def hex
|
26
|
+
sprintf "%x", self
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_array(base=10)
|
30
|
+
int = self
|
31
|
+
ary = []
|
32
|
+
begin
|
33
|
+
a = int.divmod base
|
34
|
+
ary << a[1]
|
35
|
+
int = a[0]
|
36
|
+
end while int != 0
|
37
|
+
ary.reverse!
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class Numeric
|
43
|
+
|
44
|
+
def ceil_to(i)
|
45
|
+
self + i - self%i
|
46
|
+
end
|
47
|
+
|
48
|
+
def floor_to(i)
|
49
|
+
self - self%i
|
50
|
+
end
|
51
|
+
|
52
|
+
def round_to(i)
|
53
|
+
[ceil_to(i), floor_to(i)].max
|
54
|
+
end
|
55
|
+
|
56
|
+
def between(min, max)
|
57
|
+
min < self and self < max
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
class Float
|
63
|
+
|
64
|
+
def partial(range=100)
|
65
|
+
return to_i.to_s if to_i == self
|
66
|
+
a = abs
|
67
|
+
(2..range-1).each {|i| (1..range).each {|j|
|
68
|
+
n = j.to_f/i
|
69
|
+
break if n > a
|
70
|
+
return "#{'-' if self != a}#{j}/#{i}" if n == a
|
71
|
+
} }
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
module Math
|
78
|
+
|
79
|
+
def logb(b, x) log(x)/log(b) end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class Object
|
3
|
+
alias :resto :respond_to?
|
4
|
+
|
5
|
+
def requrie file
|
6
|
+
require file
|
7
|
+
end
|
8
|
+
#alias :requrie :require # most frequent typo, lol
|
9
|
+
|
10
|
+
def is klass
|
11
|
+
if Array === klass
|
12
|
+
instance_of?(Array) && self[0].instance_of?(klass[0])
|
13
|
+
else instance_of? klass
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def kinda klass
|
18
|
+
if Array === klass
|
19
|
+
kind_of?(Array) && self[0].kind_of?(klass[0])
|
20
|
+
else kind_of? klass
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def my_methods filter=//
|
25
|
+
(self.public_methods - Object.public_instance_methods).sort!.grep(filter)
|
26
|
+
end
|
27
|
+
|
28
|
+
def personal_methods filter=//
|
29
|
+
(self.public_methods - self.class.superclass.public_instance_methods).sort!.grep(filter)
|
30
|
+
end
|
31
|
+
|
32
|
+
def my_methods_with params
|
33
|
+
m = my_methods
|
34
|
+
params.each {|p,val| m.reject! {|_| ''.method(_).send(p) != val}}
|
35
|
+
m
|
36
|
+
end
|
37
|
+
|
38
|
+
def personal_methods_with params
|
39
|
+
m = personal_methods
|
40
|
+
params.each {|p,val| m.reject! {|_| ''.method(_).send(p) != val}}
|
41
|
+
m
|
42
|
+
end
|
43
|
+
|
44
|
+
def readable_variables
|
45
|
+
public_methods.to_ss & instance_variables.map(&'[1..-1]')
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_from(obj)
|
49
|
+
readable_variables.each {|v| instance_variable_set("@#{v}", obj.instance_variable_get("@#{v}"))}
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def in *container
|
54
|
+
container.size == 1 ? container[0].include?(self) : container.include?(self)
|
55
|
+
end
|
56
|
+
|
57
|
+
def require! file
|
58
|
+
%w{.rb .so .dll}.each {|ext| $".delete "#{file}#{ext}"}
|
59
|
+
require file
|
60
|
+
end
|
61
|
+
|
62
|
+
def b; self end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class BlackHole
|
67
|
+
|
68
|
+
# Think twice before use it. It may devour your code!
|
69
|
+
def method_missing *args
|
70
|
+
BlackHole.new
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|