rmtools 1.0.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.
@@ -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
+