Module: RMTools
- Included in:
- Object
- Defined in:
- lib/rmtools/fs/io.rb,
lib/rmtools/require.rb,
lib/rmtools/version.rb,
lib/rmtools/fs/tools.rb,
lib/rmtools/dev/timer.rb,
lib/rmtools/lang/ansi.rb,
lib/rmtools/rand/array.rb,
lib/rmtools/dev/logging.rb,
lib/rmtools/rand/string.rb,
lib/rmtools/dev/watching.rb,
lib/rmtools/time/helpers.rb,
lib/rmtools/dev/highlight.rb,
lib/rmtools/core/threadify.rb,
lib/rmtools/text/textilize.rb,
lib/rmtools/console/coloring.rb,
lib/rmtools/console/printing.rb,
lib/rmtools/console/printing.rb,
lib/rmtools/dev/trace_format.rb,
lib/rmtools/enumerable/set_ops.rb,
lib/rmtools/enumerable/traversal.rb
Defined Under Namespace
Modules: Cyrillic, KeyValueTraversal, SmarterSetOps, ValueTraversal Classes: FileWatcher, KeyValueTraversable, Painter, RMLogger, ScpHelper, TempPrinter, ValueTraversable
Constant Summary collapse
- VERSION =
'2.5.0'
- ENCODINGS_PATTERNS =
{}
- ICONVS =
{}
- ANSI2UTF =
Cyrillic::ANSI2UTF = lambda {|str| str.encode("WINDOWS-1251", :invalid => :replace, :undef => :replace, :replace => "").encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "") }
- UTF2ANSI =
Cyrillic::UTF2ANSI = lambda {|str| str.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "").encode("WINDOWS-1251", :invalid => :replace, :undef => :replace, :replace => "") }
- Numbers =
'0123456789'
- Chars =
'abcdefghijklmnopqrstuvwxyz'
- Alphanum =
Chars + Chars.upcase + Numbers
- ASCII_readable =
'!"#$%&\'()*+,-./[\]^_`{|}~:;<=>?@ ' + Alphanum
- RuChars =
UTF2ANSI[Cyrillic::RU_LETTERS[0]]
- RuAlphanum =
UTF2ANSI[Cyrillic::RU_LETTERS.join] + Numbers
- IgnoreFiles =
%r{/irb(/|\.rb$)|/active_support/dependencies.rb$}
Class Method Summary collapse
- .format_trace(a) ⇒ Object
-
.format_trace_to_html(a) ⇒ Object
disclaimer: Firefox (at least 3.6+) on Windoze does not allow to use file:// protocol T_T.
- .highlighted_line(file, line) ⇒ Object
- .prepare_write(df, value) {|df, value| ... } ⇒ Object
- .putdate ⇒ Object
- .puttime(ms = nil) ⇒ Object
- .randarr(len, &b) ⇒ Object
- .randstr(len = 8, what = :alphanum) ⇒ Object
-
.read(*dests) ⇒ Object
read(‘filename’) => ‘text from filename’ read(‘nonexistent_filename’) couldn’t read from “nonexistent_filename” (called from (irb):9001) => nil read([‘file1’, ‘file2’, ‘file3’]) => ‘text from first of file1, file2, file3 that exists’ read([‘file1’, ‘file2’], [‘nonexistent_file1’, ‘nonexistent_file2’]) coludn’t read from neither “nonexistent_file1”, nor “nonexistent_file2” (called from (irb):9003) => [‘text from first of file1, file2 that exists’, nil] read(‘file1’, ‘file2’) => [‘text from file1’, ‘text from file2] read(’file1’, [‘file2’, ‘file3’]) => [‘text from file1’, ‘text from first of file2 and file3 that exists’].
- .read_lines(df, *lines) ⇒ Object
-
.require(location, mask = nil) ⇒ Object
‘ RMTools::require __FILE__, “*” ’ requires all ruby files from dir named as file under ‘rmtools-gem/lib/rmtools’ ‘ RMTools::require “folder”, “mask” ’ requires all files come within ‘mask’ from dir ‘folder’ under ‘rmtools-gem/lib/rmtools’ ‘RMTools::require “file” ’ requires ‘file.rb’ under ‘rmtools-gem/lib/rmtools’.
- .rw(df, value = nil) ⇒ Object
- .tail(file, bytes = 1000) ⇒ Object
- .tail_n(file, qty = 10) ⇒ Object
- .threadify(ary, max_threads = 4) ⇒ Object
- .tick! ⇒ Object
- .tick_while ⇒ Object
- .timer(ts = 1, output = true) ⇒ Object
- .write(df, value = '', pos = 0) ⇒ Object
Instance Method Summary collapse
Class Method Details
.format_trace(a) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/rmtools/dev/trace_format.rb', line 30 def format_trace(a) return [] if a.empty? bt, steps, i = [], [], 0 m = a[0].parse:caller # seems like that bug is fixed for now #m.line -= 1 if m and m.file =~ /\.haml$/ while i < a.size m2 = a[i+1] && a[i+1].parse(:caller) #m2.line -= 1 if m2 and m2.file =~ /\.haml$/ if m and m.path !~ IgnoreFiles step = a[i] if step["\n"] # already formatted bt << step else if m.block_level # > 1.9 step = step.sub(/block (\(\d+ levels\) )?in/, '{'+m.block_level+'}') end if m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line] steps << " -> `#{'{'+m.block_level+'} ' if m.block_level}#{m.func}'" elsif m and m.line != 0 and line = RMTools.highlighted_line(m.path, m.line) bt << "#{step}#{steps.join}\n#{line}" steps = [] else bt << step end end end i += 1 m = m2 end # Magic numbers! If a size of a backtrace array > 16 (line count doesn't affect), IRB forgets to print newline after an exception trace! I don't even want to know, why the hell it's going this way! if bt.size > 16 and bt.last[-1] != "\n" bt.last << "\n" end bt end |
.format_trace_to_html(a) ⇒ Object
disclaimer: Firefox (at least 3.6+) on Windoze does not allow to use file:// protocol T_T
70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rmtools/dev/trace_format.rb', line 70 def format_trace_to_html(a) a.map! do |lines| caller_string, snippet = lines/"\n" caler = caller_string.parse(:caller) if caler path = caler.path lines = ["<a href='#{CGI.escape 'file://'+path}'>#{path}</a>:#{caler.line} in #{caler.func}"] lines << RMTools::Painter.clean(snippet) if snippet lines * "\n" else lines end end end |
.highlighted_line(file, line) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/rmtools/dev/highlight.rb', line 6 def highlighted_line(file, line) if defined? SCRIPT_LINES__ and SCRIPT_LINES__[file] " >> #{Painter.green((SCRIPT_LINES__[file][line.to_i - 1] || "<line #{line} is not found> ").chop)}" else file = Readline::TEMPLOG if file == '(irb)' and defined? Readline::TEMPLOG if File.file? file line_read = read_lines(file, line.to_i) || "<line #{line} is not found> " if defined? SCRIPT_LINES__ SCRIPT_LINES__[file] = IO.readlines(file) highlighted_line file, line else " #{Painter.cyan '>>'} #{Painter.green line_read.chop}" end end end end |
.prepare_write(df, value) {|df, value| ... } ⇒ Object
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/rmtools/fs/io.rb', line 16 def self.prepare_write(df, value) return false if value.nil? value = value.inspect unless value.class == String value = value.force_encoding('UTF-8') if RUBY_VERSION > '1.9' df = df.tr '\\', '/' path = File.dirname(df) FileUtils.mkpath(path) if !File.directory?(path) yield df, value value.size end |
.putdate ⇒ Object
13 14 15 |
# File 'lib/rmtools/time/helpers.rb', line 13 def putdate Time.now.strftime("%d.%m.%y") end |
.puttime(ms = nil) ⇒ Object
4 5 6 7 8 9 10 11 |
# File 'lib/rmtools/time/helpers.rb', line 4 def puttime(ms=nil) t = Time.now if ms t.strftime("%H:%M:%S")+sprintf(".%03d ", t.usec/1000) else t.strftime("%d.%m.%y %H:%M:%S ") end end |
.randarr(len, &b) ⇒ Object
6 7 8 9 |
# File 'lib/rmtools/rand/array.rb', line 6 def randarr(len, &b) a = (0...len).to_a.shuffle block_given? ? a.map!(&b) : a end |
.randstr(len = 8, what = :alphanum) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rmtools/rand/string.rb', line 19 def randstr(len=8, what=:alphanum) s = '' res = case what when :bytes, :binary if Urandom SecureRandom.random_bytes len else len.times {s.concat rand 256}; s end when :ascii if Urandom SecureRandom.random_bytes(len*3).tr("^ -~", '')[0...len] else len.times {s.concat ASCII_readable[rand 95].ord}; s end when :char if Urandom res = SecureRandom.base64(len*2).tr("^a-z", '')[0...len] else len.times {s.concat Chars[rand 26].ord}; s end when :alphanum if Urandom res = SecureRandom.base64(len).tr("+/=", '')[0...len] else len.times {s.concat Alphanum[rand 62].ord}; s end when :num, :digit if Urandom res = SecureRandom.hex(len).tr("^0-9", '')[0...len] else len.times {s.concat Numbers[rand 10].ord}; s end when :hex if Urandom res = SecureRandom.hex len/2 else len.times {s.concat Numbers[rand 10].ord}; s end when :cyr, :cyrilic if Urandom res = ANSI2UTF[SecureRandom.random_bytes(len*8).tr("^\270\340-\377", '')[0...len]] else len.times {s.concat RuChars[rand 33].ord}; ANSI2UTF[s] end when :cyr_full, :cyr_alphanum if Urandom res = ANSI2UTF[SecureRandom.random_bytes(len*3.5).tr("^0-9\250\270\340-\377\300-\337", '')[0...len]] else len.times {s.concat RuAlphanum[rand 76].ord}; ANSI2UTF[s] end when Symbol then raise ArgumentError, "invalid symbol :#{what}, valid symbols are :bytes, :binary, :char, :alphanum, :num, :digit, :hex, :cyr, :cyrilic, :cyr_full, :cyr_alphanum" when String then res = randstr(len*10, :bytes).tr("^#{what}", '') else raise ArgumentError, "invalid argument #{what}, class #{(what.class)}" end res << randstr((len-res.size)*2, what) while res.size < len res[0...len] end |
.read(*dests) ⇒ Object
read(‘filename’)
> ‘text from filename’
read('nonexistent_filename')
couldn’t read from “nonexistent_filename” (called from (irb):9001)
> nil
read(['file1', 'file2', 'file3'])
> ‘text from first of file1, file2, file3 that exists’
read(['file1', 'file2'], ['nonexistent_file1', 'nonexistent_file2'])
coludn’t read from neither “nonexistent_file1”, nor “nonexistent_file2” (called from (irb):9003)
> [‘text from first of file1, file2 that exists’, nil]
read('file1', 'file2')
> [‘text from file1’, ‘text from file2]
read('file1', ['file2', 'file3'])
> [‘text from file1’, ‘text from first of file2 and file3 that exists’]
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rmtools/fs/io.rb', line 65 def read(*dests) texts = dests.map {|dest| dest = dest[0] if dest.size == 1 if dest.is Array if file = dest.find {|f| File.file?(f.tr '\\', '/')} File.open(file.tr('\\', '/'), File::RDONLY) {|f| f.read} else warn "couldn't read from neither #{dest[0].inspect} nor #{dest[1..-1].inspects*' nor '}; files missed (called from #{caller[2]})" end else if File.file? dest.tr('\\', '/') File.open(dest.tr('\\', '/'), File::RDONLY) {|f| f.read} else warn "couldn't read from #{dest.inspect}; file missed (called from #{caller[2]})" end end } texts = texts[0] if texts.size == 1 texts end |
.read_lines(df, *lines) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rmtools/fs/tools.rb', line 32 def read_lines(df, *lines) return if !lines or lines.empty? str = "" last = lines.max lines_found = false if File.file?(df) File.open(df, 'r') {|f| f.each {|line| no = f.lineno if no.in lines str << line lines_found = true end break if no == last }} lines_found && str else STDERR.puts "#{df} is missed!" end end |
.require(location, mask = nil) ⇒ Object
‘ RMTools::require __FILE__, “*” ’ requires all ruby files from dir named as file under ‘rmtools-gem/lib/rmtools’ ‘ RMTools::require “folder”, “mask” ’ requires all files come within ‘mask’ from dir ‘folder’ under ‘rmtools-gem/lib/rmtools’ ‘RMTools::require “file” ’ requires ‘file.rb’ under ‘rmtools-gem/lib/rmtools’
6 7 8 9 10 11 12 13 |
# File 'lib/rmtools/require.rb', line 6 def self.require(location, mask=nil) if !mask location, mask = File.dirname(__FILE__), location # /path/to/gems/rmtools end mask += '.rb' unless mask['.'] location = File.(location).chomp('.rb') Dir.glob(File.join location, mask) {|file| Kernel.require file} end |
.rw(df, value = nil) ⇒ Object
27 28 29 30 31 |
# File 'lib/rmtools/fs/io.rb', line 27 def rw(df, value=nil) RMTools::prepare_write df, value do File.open(df, File::CREAT|File::WRONLY|File::TRUNC) {|f| f << value} end end |
.tail(file, bytes = 1000) ⇒ Object
6 7 8 9 10 11 12 |
# File 'lib/rmtools/fs/tools.rb', line 6 def tail(file, bytes=1000) if File.file?(file) IO.read(file, bytes, File.size(file)-bytes) else STDERR.puts "#{file} is missed!" end end |
.tail_n(file, qty = 10) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/rmtools/fs/tools.rb', line 14 def tail_n(file, qty=10) if !File.file?(file) return STDERR.puts "#{file} is missed!" end size = File.size(file) lines = [] strlen = 0 step = qty*100 while qty > 0 and (offset = size-strlen-step) >= 0 and !(str = IO.read(file, step, offset)).empty? i = str.index("\n") || str.size strlen += step - i new_lines = str[i+1..-1]/"\n" qty -= new_lines.size lines = new_lines.concat(lines) end lines[-qty..-1] end |
.threadify(ary, max_threads = 4) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 |
# File 'lib/rmtools/core/threadify.rb', line 3 def threadify(ary, max_threads=4) forks = [] ary.each do |e| if max_threads > forks.size forks << fork { yield e } end if max_threads == forks.size forks.delete Process.wait end end Process.waitall end |
.tick! ⇒ Object
53 54 55 |
# File 'lib/rmtools/console/printing.rb', line 53 def tick! print %W{|\b /\b -\b \\\b +\b X\b}.rand end |
.tick_while ⇒ Object
57 58 59 60 61 62 |
# File 'lib/rmtools/console/printing.rb', line 57 def tick_while ticker = thread {loop {RMTools::tick!}} res = yield ticker.kill res end |
.timer(ts = 1, output = true) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/rmtools/dev/timer.rb', line 5 def timer(ts=1, output=true) timez = ts - 1 quiet, mute_warn = $quiet, $log.mute_warn $quiet = $log.mute_warn = true t1 = Time.now begin timez.times {yield} if timez > 0 rescue $quiet, $log.mute_warn = quiet, mute_warn raise $! end res = yield t2 = Time.now ts.times {} t3 = Time.now.to_f*1000 t2 = t2.to_f*1000 t1 = t1.to_f*1000 delta = (t2 - t1 - (t3 - t2)).round.to_f $quiet, $log.mute_warn = quiet, mute_warn res = res.inspect puts "#{output ? "res: #{res.size > 1000 ? res[0...999]+"…" : res}\n" : "size of res string: #{res.to_s.size}, "}one: #{Painter.gray '%0.4fms'%[delta/ts]}, total: #{Painter.gray "#{delta}ms"}" end |
.write(df, value = '', pos = 0) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rmtools/fs/io.rb', line 33 def write(df, value='', pos=0) RMTools::prepare_write df, value do if pos == 0 File.open(df, File::CREAT|File::WRONLY|File::APPEND) {|f| f << value} else if pos < 0 if !File.file?(df) raise IndexError, "file #{df} does not exist, can't write from position #{pos}" elsif (size = File.size(df)) < -pos raise IndexError, "file #{df} is shorter than #{(-pos).bytes}, can't write from position #{pos}" end pos = size - pos end File.open(df, File::CREAT|File::WRONLY) {|f| f.pos = pos; f << value} end end end |
Instance Method Details
#dump_recurse(obj, depth, maxdepth) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/rmtools/text/textilize.rb', line 4 def dump_recurse(obj, depth, maxdepth) res = '' case obj when Hash if depth <= maxdepth res = "{\n" obj.each { |i, j| i = i.inspect unless i.is_a? String childinfo = dump_recurse(j,depth+1,maxdepth) res << "%s %s => %s、\n"%[(" "*depth), i, childinfo] } res << " "*depth+" }" else res = obj.inspect end res when Array if depth <= maxdepth res = "[\n" obj.each_with_index { |j, i| childinfo = dump_recurse(j,depth+1,maxdepth) res << "%s %0*d: %s、\n"%[(" "*depth), (obj.size-1).to_s.size, i, childinfo] } res << " "*depth+" ]" else res = obj.inspect end res when String then obj else obj.inspect end end |