rmtools 1.1.6 → 1.1.9
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.
- data/Manifest.txt +3 -3
- data/README.txt +29 -1
- data/Rakefile +9 -10
- data/ext/rmtools.cpp +7 -7
- data/lib/rmtools.rb +1 -0
- data/lib/rmtools/conversions/string.rb +3 -3
- data/lib/rmtools/core/class.rb +5 -0
- data/lib/rmtools/core/module.rb +3 -56
- data/lib/rmtools/core/string_compliance.rb +3 -55
- data/lib/rmtools/db.rb +5 -0
- data/lib/rmtools/debug/binding.rb +26 -10
- data/lib/rmtools/debug/highlight.rb +9 -1
- data/lib/rmtools/debug/logging.rb +4 -2
- data/lib/rmtools/debug/observing.rb +28 -0
- data/lib/rmtools/debug/trace_format.rb +77 -0
- data/lib/rmtools/debug/traceback.rb +10 -71
- data/lib/rmtools/debug_notrace.rb +1 -1
- data/lib/rmtools/experimental/blackhole.rb +1 -1
- data/lib/rmtools/functional/decorate.rb +57 -0
- data/lib/rmtools/install.rb +5 -10
- data/lib/rmtools/load.rb +0 -1
- data/lib/rmtools/require.rb +3 -3
- data/lib/rmtools/text/string_parse.rb +1 -1
- data/lib/rmtools/xml/finders.rb +4 -2
- data/lib/rmtools_notrace.rb +1 -0
- metadata +7 -11
- data/History.txt +0 -18
- data/lib/rmtools/functional/string_to_proc.rb +0 -94
data/Manifest.txt
CHANGED
@@ -55,6 +55,7 @@ lib/rmtools/debug/observing.rb
|
|
55
55
|
lib/rmtools/debug/traceback.rb
|
56
56
|
lib/rmtools/debug/binding.rb
|
57
57
|
lib/rmtools/debug/logging.rb
|
58
|
+
lib/rmtools/debug/trace_format.rb
|
58
59
|
lib/rmtools/debug/highlight.rb
|
59
60
|
lib/rmtools/debug/timer.rb
|
60
61
|
lib/rmtools/fs.rb
|
@@ -64,7 +65,7 @@ lib/rmtools/functional.rb
|
|
64
65
|
lib/rmtools/load.rb
|
65
66
|
lib/rmtools/experimental.rb
|
66
67
|
lib/rmtools/install.rb
|
67
|
-
lib/rmtools/functional/
|
68
|
+
lib/rmtools/functional/decorate.rb
|
68
69
|
lib/rmtools/functional/fold.rb
|
69
70
|
lib/rmtools/functional/unfold.rb
|
70
71
|
lib/rmtools/text.rb
|
@@ -97,5 +98,4 @@ lib/rmtools_no_b.rb
|
|
97
98
|
./Rakefile
|
98
99
|
./Manifest.txt
|
99
100
|
./License.txt
|
100
|
-
./README.txt
|
101
|
-
./History.txt
|
101
|
+
./README.txt
|
data/README.txt
CHANGED
@@ -7,4 +7,32 @@ This work is licensed under the same license as Ruby language.
|
|
7
7
|
Methods for basic classes addon collection.
|
8
8
|
|
9
9
|
== CHANGES
|
10
|
-
|
10
|
+
|
11
|
+
=== Version 1.1.8
|
12
|
+
|
13
|
+
* Deleted String#to_proc. It's anyway inconsistent and causes bug in ActiveRecord 3.0.5 Base#interpolate_and_sanitize_sql and potentially somewhere else
|
14
|
+
* Solved problem with String#sub methods in 1.9: that's associated with String#to_hash in some mystic way. #to_hash is now #to_params
|
15
|
+
* Completed Binding#inspect_env
|
16
|
+
|
17
|
+
=== Version 1.1.7
|
18
|
+
|
19
|
+
* Cosmetic fixes for txts here
|
20
|
+
|
21
|
+
=== Version 1.1.6
|
22
|
+
|
23
|
+
* Rewrited few functions
|
24
|
+
* Fixed bug with RDoc and RI
|
25
|
+
* Compatible with 1.9
|
26
|
+
* Binding#start_interaction and RMTools::Observer for debugging purposes
|
27
|
+
* To require any file from lib/rmtools now RMTools::require is used
|
28
|
+
* In order to not overload Rails apps initialization tracing is lightened and gem now may be also required as "rmtools_nodebug" and "rmtools_notrace"
|
29
|
+
|
30
|
+
=== Version 1.1.0
|
31
|
+
|
32
|
+
* Fixed some bugs
|
33
|
+
* Divided by semantics
|
34
|
+
* Compatible with ruby 1.8.7 (2010-08-16 patchlevel 302)
|
35
|
+
|
36
|
+
=== Version 1.0.0
|
37
|
+
|
38
|
+
* Divided by classes and packed as gem
|
data/Rakefile
CHANGED
@@ -2,19 +2,18 @@ require 'rake'
|
|
2
2
|
require 'lib/rmtools/install'
|
3
3
|
compile_manifest
|
4
4
|
|
5
|
-
RMTOOLS_VERSION = '1.1.
|
5
|
+
RMTOOLS_VERSION = '1.1.9'
|
6
6
|
begin
|
7
7
|
require 'hoe'
|
8
|
-
config = Hoe.spec 'rmtools' do
|
9
|
-
|
8
|
+
config = Hoe.spec 'rmtools' do
|
9
|
+
developer("Shinku", "tinbka@gmail.com")
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
self.summary = 'Yet another Ruby applied framework'
|
12
|
+
self.description = 'Applied framework primarily for debug and text/arrays/files operation.'
|
13
|
+
self.changes = paragraphs_of('README.txt', 5..-1).join("\n\n")
|
14
|
+
self.url = 'http://github.com/tinbka'
|
15
15
|
|
16
|
-
|
17
|
-
h.extra_deps << ['activesupport','>= 2.3.8']
|
16
|
+
self.extra_deps = [['rake','>= 0.8.7'], ['activesupport','>= 2.3.8']]
|
18
17
|
end
|
19
18
|
config.spec.extensions << 'ext/extconf.rb'
|
20
19
|
rescue LoadError
|
@@ -25,7 +24,7 @@ rescue Exception => e
|
|
25
24
|
end
|
26
25
|
|
27
26
|
ruby = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
28
|
-
windoze =
|
27
|
+
windoze = RUBY_PLATFORM =~ /mswin32/
|
29
28
|
make = windoze ? 'nmake' : 'make'
|
30
29
|
|
31
30
|
Dir.chdir "ext" do
|
data/ext/rmtools.cpp
CHANGED
@@ -54,7 +54,7 @@ static VALUE rb_ary_string_transpose(VALUE ary)
|
|
54
54
|
for (j=0; j<elen; j++) rb_ary_store(result, j, rb_str_new("", 0));
|
55
55
|
}
|
56
56
|
else if (elen != RSTRING_LEN(tmp))
|
57
|
-
rb_raise(rb_eIndexError, "element size differs (%
|
57
|
+
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
|
58
58
|
RARRAY_LEN(tmp), elen);
|
59
59
|
for (j=0; j<elen; j++) rb_str_buf_cat(RARRAY_PTR(result)[j], &(RSTRING_PTR(tmp)[j]), 1);
|
60
60
|
}
|
@@ -82,7 +82,7 @@ static VALUE rb_ary_turn_ccw(VALUE ary)
|
|
82
82
|
for (i=0; i<alen; i++) {
|
83
83
|
if (i) tmp = RARRAY_PTR(ary)[i];
|
84
84
|
if (elen != RSTRING_LEN(tmp))
|
85
|
-
rb_raise(rb_eIndexError, "element size differs (%
|
85
|
+
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
|
86
86
|
RARRAY_LEN(tmp), elen);
|
87
87
|
for (j=0; j<elen; j++) rb_str_buf_cat(RARRAY_PTR(result)[j], &(RSTRING_PTR(tmp)[elen-1-j]), 1);
|
88
88
|
}
|
@@ -93,7 +93,7 @@ static VALUE rb_ary_turn_ccw(VALUE ary)
|
|
93
93
|
for (i=0; i<alen; i++) {
|
94
94
|
if (i) tmp = RARRAY_PTR(ary)[i];
|
95
95
|
if (elen != RARRAY_LEN(tmp))
|
96
|
-
rb_raise(rb_eIndexError, "element size differs (%
|
96
|
+
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
|
97
97
|
RARRAY_LEN(tmp), elen);
|
98
98
|
for (j=0; j<elen; j++) rb_ary_store(RARRAY_PTR(result)[j], i, RARRAY_PTR(tmp)[elen-1-j]);
|
99
99
|
}
|
@@ -123,7 +123,7 @@ static VALUE rb_ary_turn_cw(VALUE ary)
|
|
123
123
|
for (i=alen-1; i>-1; i--) {
|
124
124
|
tmp = RARRAY_PTR(ary)[i];
|
125
125
|
if (elen != RSTRING_LEN(tmp))
|
126
|
-
rb_raise(rb_eIndexError, "element size differs (%
|
126
|
+
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
|
127
127
|
RARRAY_LEN(tmp), elen);
|
128
128
|
for (j=0; j<elen; j++) rb_str_buf_cat(RARRAY_PTR(result)[j], &(RSTRING_PTR(tmp)[j]), 1);
|
129
129
|
}
|
@@ -134,7 +134,7 @@ static VALUE rb_ary_turn_cw(VALUE ary)
|
|
134
134
|
for (i=0; i<alen; i++) {
|
135
135
|
if (i) tmp = RARRAY_PTR(ary)[i];
|
136
136
|
if (elen != RARRAY_LEN(tmp))
|
137
|
-
rb_raise(rb_eIndexError, "element size differs (%
|
137
|
+
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
|
138
138
|
RARRAY_LEN(tmp), elen);
|
139
139
|
for (j=0; j<elen; j++) rb_ary_store(RARRAY_PTR(result)[j], elen-1-i, RARRAY_PTR(tmp)[j]);
|
140
140
|
}
|
@@ -150,7 +150,7 @@ static VALUE rb_ary_turn_cw(VALUE ary)
|
|
150
150
|
static VALUE rb_str_disjunction(VALUE self, VALUE str)
|
151
151
|
{
|
152
152
|
if (RSTRING_LEN(self) != RSTRING_LEN(str))
|
153
|
-
rb_raise(rb_eIndexError, "strings sizes differs (%
|
153
|
+
rb_raise(rb_eIndexError, "strings sizes differs (%ld and %ld)",
|
154
154
|
RSTRING_LEN(self), RSTRING_LEN(str));
|
155
155
|
VALUE new_str = rb_str_new("", 0);
|
156
156
|
int i;
|
@@ -171,7 +171,7 @@ static VALUE rb_str_disjunction(VALUE self, VALUE str)
|
|
171
171
|
static VALUE rb_str_conjunction(VALUE self, VALUE str)
|
172
172
|
{
|
173
173
|
if (RSTRING_LEN(self) != RSTRING_LEN(str))
|
174
|
-
rb_raise(rb_eIndexError, "strings sizes differs (%
|
174
|
+
rb_raise(rb_eIndexError, "strings sizes differs (%ld and %ld)",
|
175
175
|
RSTRING_LEN(self), RSTRING_LEN(str));
|
176
176
|
VALUE new_str = rb_str_new("", 0);
|
177
177
|
int i;
|
data/lib/rmtools.rb
CHANGED
@@ -3,8 +3,8 @@ require 'cgi'
|
|
3
3
|
|
4
4
|
class String
|
5
5
|
|
6
|
-
# with default delimiters -
|
7
|
-
def
|
6
|
+
# with default delimiters - the opposite of #urlencode
|
7
|
+
def to_params(unscp=true, params_delim='&', k_v_delim='=')
|
8
8
|
params = split(params_delim)
|
9
9
|
h = {}
|
10
10
|
params.each {|par|
|
@@ -18,7 +18,7 @@ class String
|
|
18
18
|
h
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
21
|
+
# the opposite of #to_json
|
22
22
|
# active support activesupport
|
23
23
|
def from_json
|
24
24
|
ActiveSupport::JSON.decode self
|
data/lib/rmtools/core/class.rb
CHANGED
@@ -39,6 +39,11 @@ class Class
|
|
39
39
|
(self.public_instance_methods - self.superclass.public_instance_methods).sort!.grep(filter)
|
40
40
|
end
|
41
41
|
|
42
|
+
# differs with #ancestors in that it doesn't show included modules
|
43
|
+
def superclasses
|
44
|
+
unfold(lambda {|c|!c}) {|c| [c.superclass, c]}
|
45
|
+
end
|
46
|
+
|
42
47
|
end
|
43
48
|
|
44
49
|
[Hash, Regexp, File, Dir].each {|klass| klass.__init__}
|
data/lib/rmtools/core/module.rb
CHANGED
@@ -13,12 +13,12 @@ class Module
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def children
|
16
|
-
constants.map! {|c| module_eval c}.find_all {|c| c.kinda Module rescue()}
|
16
|
+
constants.map! {|c| module_eval c.to_s}.find_all {|c| c.kinda Module rescue()}
|
17
17
|
end
|
18
18
|
|
19
19
|
def each_child
|
20
|
-
constants.map! {|c| module_eval c}.each {|c| yield c if c.kinda Module}
|
21
|
-
|
20
|
+
(cs = constants.map! {|c| module_eval c.to_s}).each {|c| yield c if c.kinda Module}
|
21
|
+
cs
|
22
22
|
end
|
23
23
|
|
24
24
|
def self_name
|
@@ -30,58 +30,5 @@ class Module
|
|
30
30
|
end
|
31
31
|
alias personal_methods my_methods
|
32
32
|
|
33
|
-
private
|
34
|
-
# example:
|
35
|
-
#
|
36
|
-
# def divide_ten_by x
|
37
|
-
# 10 / x
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# def maybe(*args)
|
41
|
-
# yield *args rescue(puts $!)
|
42
|
-
# end
|
43
|
-
# ...
|
44
|
-
#
|
45
|
-
# decorate :divide_ten_by, :maybe # =>
|
46
|
-
# def divide_ten_by x
|
47
|
-
# 10 / x rescue(puts $!)
|
48
|
-
# end
|
49
|
-
def decorate f1, f2
|
50
|
-
f1_clone = f1.to_s.dup
|
51
|
-
f1_clone.bump! '_' while private_method_defined? f1_clone.to_sym
|
52
|
-
class_eval(<<-EVAL, __FILE__, __LINE__+1
|
53
|
-
alias #{f1_clone} #{f1}
|
54
|
-
private :#{f1_clone}
|
55
|
-
def #{f1}(*args) #{f2}(*args, &method(:#{f1_clone})) end
|
56
|
-
EVAL
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
# some FP, example:
|
61
|
-
#
|
62
|
-
# def divide_ten_by x
|
63
|
-
# 10 / x
|
64
|
-
# end
|
65
|
-
#
|
66
|
-
# def maybe
|
67
|
-
# lambda {|*args| yield *args rescue(puts $!)}
|
68
|
-
# end
|
69
|
-
# ...
|
70
|
-
#
|
71
|
-
# decorated_fof :divide_ten_by, :maybe # =>
|
72
|
-
# def divide_ten_by
|
73
|
-
# lambda {|x| 10 / x rescue(puts $!)}
|
74
|
-
# end
|
75
|
-
def decorated_fof f1, f2
|
76
|
-
f1_clone = f1.to_s.dup
|
77
|
-
f1_clone.bump! '_' while private_method_defined? f1_clone
|
78
|
-
class_eval(<<-EVAL, __FILE__, __LINE__+1
|
79
|
-
alias #{f1_clone} #{f1}
|
80
|
-
private :#{f1_clone}
|
81
|
-
def #{f1}() #{f2}(&method(:#{f1_clone})) end
|
82
|
-
EVAL
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
33
|
end
|
87
34
|
|
@@ -1,59 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
# Problem with subs is solved, so now here will be only #ord
|
3
|
+
if RUBY_VERSION < "1.9"
|
4
|
+
class String
|
5
5
|
def ord; self[0] end
|
6
|
-
|
7
|
-
# TODO?
|
8
|
-
# [g]sub[!] in ruby 1.8 takes the second arg which can operate \1, \2 etc keys as if it were MatchData parts
|
9
|
-
# Though, in ruby 1.9 it ignores (without exception) the second arg and only pay attention to block. I can emulate ruby 1.8 second-arg-behaviour but
|
10
|
-
# block passed to old method must be of the same context as that method's caller
|
11
|
-
# in order to $~, $1 and such variables to work (and blocks with them are actualy used i.e. in Readline).
|
12
|
-
# So now I'm afraid it useless to redefine these methods for 1.9 but I'll try some to hack it in C-ext
|
13
|
-
=begin
|
14
|
-
else
|
15
|
-
alias :sub19 :sub
|
16
|
-
alias :sub19! :sub!
|
17
|
-
alias :gsub19 :gsub
|
18
|
-
alias :gsub19! :gsub!
|
19
|
-
|
20
|
-
def sub a,b=nil,&c
|
21
|
-
if b
|
22
|
-
if b=~/\\\d/
|
23
|
-
b = b.gsub19(/\\\d/) {|m| "\#$#{m[1]}"}
|
24
|
-
sub19(a) {eval "\"#{b}\""}
|
25
|
-
else sub19(a) {b} end
|
26
|
-
else gsub19(a, &c) end
|
27
|
-
end
|
28
|
-
|
29
|
-
def sub! a,b=nil,&c
|
30
|
-
if b
|
31
|
-
if b=~/\\\d/
|
32
|
-
b = b.gsub19(/\\\d/) {|m| "\#$#{m[1]}"}
|
33
|
-
sub19!(a) {eval "\"#{b}\""}
|
34
|
-
else sub19!(a) {b} end
|
35
|
-
else sub19!(a, &c) end
|
36
|
-
end
|
37
|
-
|
38
|
-
def gsub a,b=nil,&c
|
39
|
-
if b
|
40
|
-
if b=~/\\\d/
|
41
|
-
b = b.gsub19(/\\\d/) {|m| "\#$#{m[1]}"}
|
42
|
-
gsub19(a) {eval "\"#{b}\""}
|
43
|
-
else gsub19(a) {b} end
|
44
|
-
else gsub19(a, &c) end
|
45
|
-
end
|
46
|
-
|
47
|
-
def gsub! a,b=nil,&c
|
48
|
-
if b
|
49
|
-
if b=~/\\\d/
|
50
|
-
b = b.gsub19(/\\\d/) {|m| "\#$#{m[1]}"}
|
51
|
-
p a
|
52
|
-
gsub19!(a) {p "\"#{b}\""; p $~; p eval "\"#{b}\""; p eval "\"#{b}\""}
|
53
|
-
else gsub19!(a) {b} end
|
54
|
-
else gsub19!(a, &c) end
|
55
|
-
end
|
56
|
-
=end
|
57
6
|
end
|
58
|
-
|
59
7
|
end
|
data/lib/rmtools/db.rb
CHANGED
@@ -3,6 +3,11 @@ begin
|
|
3
3
|
require 'active_record'
|
4
4
|
ActiveRecord::Base
|
5
5
|
RMTools::require __FILE__, 'active_record'
|
6
|
+
# fix for that mystic bug
|
7
|
+
# /usr/lib/ruby/1.8/openssl/ssl-internal.rb:30: [BUG] Segmentation fault
|
8
|
+
# ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-linux]
|
9
|
+
require 'openssl/ssl'
|
6
10
|
rescue Exception
|
11
|
+
p $!
|
7
12
|
nil
|
8
13
|
end
|
@@ -12,14 +12,30 @@ class Binding
|
|
12
12
|
|
13
13
|
def inspect_instance_variables
|
14
14
|
vars = self.eval('instance_variables') # ['@a', '@b']
|
15
|
-
|
16
|
-
|
15
|
+
if !vars.empty?
|
16
|
+
values = self.eval "[#{vars * ','}]" # ["@a's value", "@b's value"]
|
17
|
+
Hash[vars.zip(values)]
|
18
|
+
else {}
|
19
|
+
end
|
17
20
|
end
|
18
21
|
|
19
|
-
def
|
20
|
-
self.eval(
|
22
|
+
def inspect_class_variables
|
23
|
+
vars = self.eval('self.class.class_variables') # ['@@a', '@@b']
|
24
|
+
if !vars.empty?
|
25
|
+
values = self.eval "[#{vars * ','}]" # ["@@a's value", "@@b's value"]
|
26
|
+
Hash[vars.zip(values)]
|
27
|
+
else {}
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
31
|
+
def inspect_special_variables
|
32
|
+
Hash[self.eval(%[{"self" => self, #{['!', '`', '\'', '&', '~', *(1..9)].map {|lit| %{"$#{lit}" => $#{lit}, }}.join}}]).reject {|k,v| v.nil?}]
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect_env
|
36
|
+
inspect_local_variables + inspect_instance_variables + inspect_class_variables + inspect_special_variables
|
37
|
+
end
|
38
|
+
|
23
39
|
def valid_types(pattern_ary)
|
24
40
|
self.eval("[#{self.eval('local_variables')*','}]").valid_types(pattern_ary)
|
25
41
|
end
|
@@ -34,12 +50,12 @@ class Binding
|
|
34
50
|
|
35
51
|
# it's supposed to be called during TDD in an IRB session
|
36
52
|
# $__MAIN__ must be `self' or root IRB session, i.e. `main' object
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
53
|
+
# def tested_function
|
54
|
+
# blah blah blah
|
55
|
+
# rescue => err
|
56
|
+
# binding.start_interaction
|
57
|
+
# raise err
|
58
|
+
# end
|
43
59
|
def start_interaction(sandbox=true)
|
44
60
|
$__env__ = inspect_env
|
45
61
|
puts "Caller trace:"
|
@@ -8,7 +8,15 @@ module RMTools
|
|
8
8
|
" >> #{Painter.green SCRIPT_LINES__[file][line.to_i - 1].chop}"
|
9
9
|
else
|
10
10
|
file = Readline::TEMPLOG if file == '(irb)' and defined? Readline::TEMPLOG
|
11
|
-
|
11
|
+
if File.file? file
|
12
|
+
line_read = read_lines(file, line.to_i)
|
13
|
+
if defined? SCRIPT_LINES__
|
14
|
+
SCRIPT_LINES__[file] = IO.readlines(file)
|
15
|
+
highlighted_line file, line
|
16
|
+
else
|
17
|
+
" #{Painter.cyan '>>'} #{Painter.green line_read.chop}"
|
18
|
+
end
|
19
|
+
end
|
12
20
|
end
|
13
21
|
end
|
14
22
|
|
@@ -36,7 +36,7 @@ module RMTools
|
|
36
36
|
file.path_format = '%'.in file.out if file.out
|
37
37
|
file.tf = format.time.to_a
|
38
38
|
file.cf0 = format.caller
|
39
|
-
file.cf = file.cf0.sub('%p'){'\1'}.sub('%f'){'\2'}.sub('%l'){'\3'}.sub('%m'){'\4'}
|
39
|
+
file.cf = file.cf0.sub('%p') {'\1'}.sub('%f') {'\2'}.sub('%l') {'\3'}.sub('%m') {'\4'}
|
40
40
|
file.fmt = format.format
|
41
41
|
file._time, file._caller = '%time'.in(file.fmt), '%caller'.in(file.fmt)
|
42
42
|
end
|
@@ -91,7 +91,9 @@ module RMTools
|
|
91
91
|
end
|
92
92
|
out = now.strftime cfg.out if cfg.path_format
|
93
93
|
end
|
94
|
-
|
94
|
+
if caler
|
95
|
+
str.sub! "%caller", caler.sub(String::CALLER_RE, cfg.cf)
|
96
|
+
end
|
95
97
|
log_str = @clr.clean str
|
96
98
|
RMTools.write out, log_str if log_
|
97
99
|
Kernel.print str if print_
|
@@ -76,5 +76,33 @@ module RMTools
|
|
76
76
|
set_trace_func nil
|
77
77
|
end
|
78
78
|
|
79
|
+
def self.trace_calls(out='log/calltrace.log')
|
80
|
+
logger = RMLogger.new :out => out, :format => '[%time]: %text'
|
81
|
+
offset, last_logline, quo, quos = 0, nil, 1, ''
|
82
|
+
set_trace_func lambda {|event, file, line, id, binding, classname|
|
83
|
+
if event == 'call' or event == 'c-call' or event == 'raise'
|
84
|
+
logline = "#{quos}\n#{' '*([offset, 0].max)}#{classname}##{id} < #{file} > #{event=='c-call' ? '[CC]' : event == 'raise' ? '[RAISE]' : ''}"
|
85
|
+
if last_logline != logline
|
86
|
+
logger.log(last_logline = logline, RMLogger::INLINE)
|
87
|
+
quo = 1
|
88
|
+
quos = ''
|
89
|
+
else
|
90
|
+
quo += 1
|
91
|
+
quos = " x#{q}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
if event == 'call' or event == 'c-call'
|
95
|
+
offset += 1
|
96
|
+
elsif event == 'return' or event == 'c-return'
|
97
|
+
offset -= 1
|
98
|
+
end
|
99
|
+
}
|
100
|
+
begin yield
|
101
|
+
rescue Exception
|
102
|
+
nil
|
103
|
+
ensure set_trace_func nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
79
107
|
end
|
80
108
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
RMTools::require 'debug/highlight'
|
3
|
+
RMTools::require 'debug/logging'
|
4
|
+
|
5
|
+
module RMTools
|
6
|
+
|
7
|
+
# Python-like traceback for exceptions; uses ANSI coloring.
|
8
|
+
# In case of any low-level ruby error it may hang up interpreter
|
9
|
+
# (although you must have done VERY creepy things for that). If you find
|
10
|
+
# interpreter in hanging up, require 'rmtools_notrace' instead of 'rmtools'
|
11
|
+
# or run "Exception.trace_format false" right after require
|
12
|
+
#
|
13
|
+
# 1:0> def divbyzero
|
14
|
+
# 2:1< 10/0 end
|
15
|
+
# => nil
|
16
|
+
# 3:0> divbyzero
|
17
|
+
# ZeroDivisionError: divided by 0
|
18
|
+
# from (irb):2:in `divbyzero' <- `/'
|
19
|
+
# >> 10/0 end
|
20
|
+
# from (irb):3
|
21
|
+
# >> divbyzero
|
22
|
+
def format_trace(a)
|
23
|
+
bt, calls, i = [], [], 0
|
24
|
+
# $log.info 'a.size', binding
|
25
|
+
m = a[0].parse:caller
|
26
|
+
while i < a.size
|
27
|
+
# $log.info 'i a[i]', binding
|
28
|
+
m2 = a[i+1] && a[i+1].parse(:caller)
|
29
|
+
# $log.info 'm m2', binding
|
30
|
+
# $log.info 'm.func [m.path,m.line]==[m2.path,m2.line]', binding if m and m2
|
31
|
+
# $log.info 'm.path m.line a[i]', binding if m
|
32
|
+
# $log.info RMTools.highlighted_line(m.path, m.line) if m
|
33
|
+
if m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line]
|
34
|
+
calls << " -> `#{m.func}'"
|
35
|
+
elsif m and m.line != 0 and line = RMTools.highlighted_line(m.path, m.line)
|
36
|
+
bt << "#{a[i]}#{calls.join}\n#{line}"
|
37
|
+
calls = []
|
38
|
+
else bt << a[i]
|
39
|
+
end
|
40
|
+
i += 1
|
41
|
+
m = m2
|
42
|
+
end
|
43
|
+
# $log << RMTools::Painter.r("FORMAT DONE! #{bt.size} lines formatted")
|
44
|
+
bt
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_trace_to_html(a)
|
48
|
+
a.map! do |lines|
|
49
|
+
caller_string, snippet = lines/"\n"
|
50
|
+
caller = caller_string.parse(:caller)
|
51
|
+
if caller
|
52
|
+
path = caller.path
|
53
|
+
lines = ["<a href='#{CGI.escape 'file://'+path}'>#{path}</a>:#{caller.line} in #{caller.func}"]
|
54
|
+
lines << RMTools::Painter.clean(snippet) if snippet
|
55
|
+
lines * "\n"
|
56
|
+
else
|
57
|
+
lines
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module_function :format_trace, :format_trace_to_html
|
63
|
+
end
|
64
|
+
|
65
|
+
class Class
|
66
|
+
|
67
|
+
private
|
68
|
+
def trace_format method
|
69
|
+
if Exception.in ancestors
|
70
|
+
class_attribute :__trace_format
|
71
|
+
self.__trace_format = method
|
72
|
+
else
|
73
|
+
raise NoMethodError, "undefined method `trace_format' for class #{self}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -1,83 +1,22 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
RMTools::require 'debug/
|
3
|
-
|
2
|
+
RMTools::require 'debug/trace_format'
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
# Python-like traceback for exceptions; uses ANSI coloring.
|
8
|
-
# In case of any low-level ruby error it may hang up interpreter
|
9
|
-
# (although you must have done creepy things for that). If you find
|
10
|
-
# interpreter in hanging up, require 'rmtools_notrace' instead of 'rmtools'
|
11
|
-
# or run "Exception.trace_format false" right after require
|
12
|
-
#
|
13
|
-
# 1:0> def divbyzero
|
14
|
-
# 2:1< 10/0 end
|
15
|
-
# => nil
|
16
|
-
# 3:0> divbyzero
|
17
|
-
# ZeroDivisionError: divided by 0
|
18
|
-
# from (irb):2:in `divbyzero' <- `/'
|
19
|
-
# >> 10/0 end
|
20
|
-
# from (irb):3
|
21
|
-
# >> divbyzero
|
22
|
-
def format_trace(a)
|
23
|
-
bt, calls, i = [], [], 0
|
24
|
-
# $log.info 'a.size', binding
|
25
|
-
m = a[0].parse:caller
|
26
|
-
while i < a.size
|
27
|
-
# $log.info 'i a[i]', binding
|
28
|
-
m2 = a[i+1] && a[i+1].parse(:caller)
|
29
|
-
# $log.info 'm m2', binding
|
30
|
-
# $log.info 'm.func [m.path,m.line]==[m2.path,m2.line]', binding if m and m2
|
31
|
-
# $log.info 'm.path m.line a[i]', binding if m
|
32
|
-
# $log.info RMTools.highlighted_line(m.path, m.line) if m
|
33
|
-
if m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line]
|
34
|
-
calls << " -> `#{m.func}'"
|
35
|
-
elsif m and m.line != 0 and line = RMTools.highlighted_line(m.path, m.line)
|
36
|
-
bt << "#{a[i]}#{calls.join}\n#{line}"
|
37
|
-
calls = []
|
38
|
-
else bt << a[i]
|
39
|
-
end
|
40
|
-
i += 1
|
41
|
-
m = m2
|
42
|
-
end
|
43
|
-
# $log << RMTools::Painter.r("FORMAT DONE! #{bt.size} lines formatted")
|
44
|
-
bt
|
45
|
-
end
|
46
|
-
|
47
|
-
module_function :format_trace
|
48
|
-
end
|
49
|
-
|
50
|
-
class Class
|
51
|
-
|
52
|
-
private
|
53
|
-
def trace_format method
|
54
|
-
if Exception.in ancestors
|
55
|
-
self.__trace_format = method
|
56
|
-
else
|
57
|
-
raise NoMethodError, "undefined method `trace_format' for class #{self}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
# 1.9 may hung up processing IO while generating traceback
|
5
|
+
# 1.9 may hung up processing IO while generating traceback
|
64
6
|
if RUBY_VERSION < '1.9'
|
65
7
|
class Exception
|
66
8
|
alias :set_bt :set_backtrace
|
67
9
|
class_attribute :__trace_format
|
68
10
|
|
69
|
-
# to use trace formatting ensure that you have SCRIPT_LINES__ constant set
|
70
|
-
# SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
71
|
-
#
|
72
11
|
# If you also set (e.g. in irbrc file)
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
12
|
+
# module Readline
|
13
|
+
# alias :orig_readline :readline
|
14
|
+
# def readline(*args)
|
15
|
+
# ln = orig_readline(*args)
|
16
|
+
# SCRIPT_LINES__['(irb)'] << "#{ln}\n"
|
17
|
+
# ln
|
18
|
+
# end
|
79
19
|
# end
|
80
|
-
# end
|
81
20
|
# it will be possible to get the lines entered in IRB
|
82
21
|
# else it reads only ordinal require'd files
|
83
22
|
def set_backtrace src
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
RMTools::require 'debug
|
2
|
+
RMTools::require 'debug/{observing,timer}'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Emulate python's @-operator
|
2
|
+
class Module
|
3
|
+
|
4
|
+
private
|
5
|
+
# example:
|
6
|
+
#
|
7
|
+
# def divide_ten_by x
|
8
|
+
# 10 / x
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def maybe(*args)
|
12
|
+
# yield *args rescue(puts $!)
|
13
|
+
# end
|
14
|
+
# ...
|
15
|
+
#
|
16
|
+
# decorate :divide_ten_by, :maybe # =>
|
17
|
+
# def divide_ten_by x
|
18
|
+
# 10 / x rescue(puts $!)
|
19
|
+
# end
|
20
|
+
def decorate f1, f2
|
21
|
+
f1_clone = f1.to_s.dup
|
22
|
+
f1_clone.bump! '_' while private_method_defined? f1_clone.to_sym
|
23
|
+
class_eval(<<-EVAL, __FILE__, __LINE__+1
|
24
|
+
alias #{f1_clone} #{f1}
|
25
|
+
private :#{f1_clone}
|
26
|
+
def #{f1}(*args) #{f2}(*args, &method(:#{f1_clone})) end
|
27
|
+
EVAL
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
# some FP, example:
|
32
|
+
#
|
33
|
+
# def divide_ten_by x
|
34
|
+
# 10 / x
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# def maybe
|
38
|
+
# lambda {|*args| yield *args rescue(puts $!)}
|
39
|
+
# end
|
40
|
+
# ...
|
41
|
+
#
|
42
|
+
# decorated_fof :divide_ten_by, :maybe # =>
|
43
|
+
# def divide_ten_by
|
44
|
+
# lambda {|x| 10 / x rescue(puts $!)}
|
45
|
+
# end
|
46
|
+
def decorated_fof f1, f2
|
47
|
+
f1_clone = f1.to_s.dup
|
48
|
+
f1_clone.bump! '_' while private_method_defined? f1_clone
|
49
|
+
class_eval(<<-EVAL, __FILE__, __LINE__+1
|
50
|
+
alias #{f1_clone} #{f1}
|
51
|
+
private :#{f1_clone}
|
52
|
+
def #{f1}() #{f2}(&method(:#{f1_clone})) end
|
53
|
+
EVAL
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/rmtools/install.rb
CHANGED
@@ -4,16 +4,11 @@ RMTools::require 'fs'
|
|
4
4
|
require 'digest/md5'
|
5
5
|
|
6
6
|
def ext_files_not_modified(ext_name='rmtools', version='\d')
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ext_files = gemspec.files.grep(/^ext\//)
|
13
|
-
ext_files.each {|f|
|
14
|
-
installed = File.join(full_path, f)
|
15
|
-
return unless File.file? installed and Digest::SHA256.file(f) == Digest::SHA256.file(installed)
|
16
|
-
}
|
7
|
+
gem = Gem.source_index.select {|a| a[0] =~ /^#{ext_name}-#{version}$/}[0]
|
8
|
+
return unless gem
|
9
|
+
gemspec = gem[1]
|
10
|
+
path = gemspec.full_gem_path
|
11
|
+
gemspec.files.grep(/^ext\//).find {|f| !(File.file?(installed=File.join(path, f)) and Digest::SHA256.file(f) == Digest::SHA256.file(installed))}
|
17
12
|
end
|
18
13
|
|
19
14
|
def compile_manifest(exc=['pkg'])
|
data/lib/rmtools/load.rb
CHANGED
data/lib/rmtools/require.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module RMTools
|
3
|
-
# ` RMTools::require __FILE__, "*" ' requires all ruby files from dir named as file
|
4
|
-
# ` RMTools::require "folder", "
|
5
|
-
# `RMTools::require "file" ' requires 'file.rb'
|
3
|
+
# ` RMTools::require __FILE__, "*" ' requires all ruby files from dir named as file under 'rmtools-gem/lib/rmtools'
|
4
|
+
# ` RMTools::require "folder", "mask" ' requires all files come within `mask' from dir `folder' under 'rmtools-gem/lib/rmtools'
|
5
|
+
# `RMTools::require "file" ' requires 'file.rb' under 'rmtools-gem/lib/rmtools'
|
6
6
|
def self.require(location, mask=nil)
|
7
7
|
if !mask
|
8
8
|
location, mask = File.dirname(__FILE__), location # /path/to/gems/rmtools
|
@@ -4,7 +4,7 @@ RMTools::require 'conversions/string'
|
|
4
4
|
class String
|
5
5
|
CALLER_RE = %r{^(.*?([^/\\]+?))#{ # ( path ( file ) )
|
6
6
|
}:(\d+)(?::in #{ # :( line )[ :in
|
7
|
-
}[`<](
|
7
|
+
}[`<](.+?)[>']#{ # `( closure )' ]
|
8
8
|
})?$}
|
9
9
|
URL_RE = %r{^((?:([^:]+)://)#{ # ( protocol
|
10
10
|
}([^/:]*(?::(\d+))?))?#{ # root[:port] )
|
data/lib/rmtools/xml/finders.rb
CHANGED
@@ -11,9 +11,11 @@ module LibXML::XML
|
|
11
11
|
node.is(Array) && node.size == 1 ? node[0] : node
|
12
12
|
}
|
13
13
|
FindByProc = lambda {|node, ns, ss|
|
14
|
+
str_to_eval = ss.matched[1..-2]
|
15
|
+
'_' >> str_to_eval if !str_to_eval['_']
|
14
16
|
node = node.is(Array) ?
|
15
|
-
node.sum {|n| n.__find(nil, ns, ss).select
|
16
|
-
node.__find(nil, ns, ss).select
|
17
|
+
node.sum {|n| n.__find(nil, ns, ss).select{|_| eval str_to_eval}.to_a} :
|
18
|
+
node.__find(nil, ns, ss).select{|_| eval str_to_eval}
|
17
19
|
node.is(Array) && node.size == 1 ? node[0] : node
|
18
20
|
}
|
19
21
|
|
data/lib/rmtools_notrace.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rmtools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 9
|
10
|
+
version: 1.1.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Shinku
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-03-17 00:00:00 +03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -66,10 +66,7 @@ dependencies:
|
|
66
66
|
version: 2.9.0
|
67
67
|
type: :development
|
68
68
|
version_requirements: *id003
|
69
|
-
description:
|
70
|
-
Methods for basic classes addon collection.\n\n\
|
71
|
-
== CHANGES\n\
|
72
|
-
:include: History.txt\n"
|
69
|
+
description: Applied framework primarily for debug and text/arrays/files operation.
|
73
70
|
email:
|
74
71
|
- tinbka@gmail.com
|
75
72
|
executables: []
|
@@ -80,7 +77,6 @@ extra_rdoc_files:
|
|
80
77
|
- ./Manifest.txt
|
81
78
|
- ./License.txt
|
82
79
|
- ./README.txt
|
83
|
-
- ./History.txt
|
84
80
|
files:
|
85
81
|
- ext/extconf.rb
|
86
82
|
- ext/rmtools.h
|
@@ -139,6 +135,7 @@ files:
|
|
139
135
|
- lib/rmtools/debug/traceback.rb
|
140
136
|
- lib/rmtools/debug/binding.rb
|
141
137
|
- lib/rmtools/debug/logging.rb
|
138
|
+
- lib/rmtools/debug/trace_format.rb
|
142
139
|
- lib/rmtools/debug/highlight.rb
|
143
140
|
- lib/rmtools/debug/timer.rb
|
144
141
|
- lib/rmtools/fs.rb
|
@@ -148,7 +145,7 @@ files:
|
|
148
145
|
- lib/rmtools/load.rb
|
149
146
|
- lib/rmtools/experimental.rb
|
150
147
|
- lib/rmtools/install.rb
|
151
|
-
- lib/rmtools/functional/
|
148
|
+
- lib/rmtools/functional/decorate.rb
|
152
149
|
- lib/rmtools/functional/fold.rb
|
153
150
|
- lib/rmtools/functional/unfold.rb
|
154
151
|
- lib/rmtools/text.rb
|
@@ -182,7 +179,6 @@ files:
|
|
182
179
|
- ./Manifest.txt
|
183
180
|
- ./License.txt
|
184
181
|
- ./README.txt
|
185
|
-
- ./History.txt
|
186
182
|
has_rdoc: true
|
187
183
|
homepage: http://github.com/tinbka
|
188
184
|
licenses: []
|
data/History.txt
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
=== Version 1.0.0
|
2
|
-
|
3
|
-
* Divided by classes and packed as gem
|
4
|
-
|
5
|
-
=== Version 1.1.0
|
6
|
-
|
7
|
-
* Fixed some bugs
|
8
|
-
* Divided by semantics
|
9
|
-
* Compatible with ruby 1.8.7 (2010-08-16 patchlevel 302)
|
10
|
-
|
11
|
-
=== Version 1.1.6
|
12
|
-
|
13
|
-
* Rewrited few functions
|
14
|
-
* Fixed bug with RDoc and RI
|
15
|
-
* Compatible with 1.9
|
16
|
-
* Binding#start_interaction and RMTools::Observer for debugging purposes
|
17
|
-
* To require any file from lib/rmtools now RMTools::require is used
|
18
|
-
* In order to not overload Rails apps initialization tracing is lightened and gem now may be also required as "rmtools_nodebug" and "rmtools_notrace"
|
@@ -1,94 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# String#to_proc
|
3
|
-
#
|
4
|
-
# See http://weblog.raganwald.com/2007/10/stringtoproc.html ( Subscribe in a reader)
|
5
|
-
#
|
6
|
-
# Ported from the String Lambdas in Oliver Steele's Functional Javascript
|
7
|
-
# http://osteele.com/sources/javascript/functional/
|
8
|
-
#
|
9
|
-
# This work is licensed under the MIT License:
|
10
|
-
#
|
11
|
-
# (c) 2007 Reginald Braithwaite
|
12
|
-
# Portions Copyright (c) 2006 Oliver Steele
|
13
|
-
|
14
|
-
|
15
|
-
class String
|
16
|
-
unless ''.respond_to?(:to_proc)
|
17
|
-
=begin original definition:
|
18
|
-
def to_proc &block
|
19
|
-
params = []
|
20
|
-
expr = self
|
21
|
-
sections = expr.split(/\s*->\s*/m)
|
22
|
-
if sections.length > 1 then
|
23
|
-
eval sections.reverse!.inject { |e, p| "(Proc.new { |#{p.split(/\s/).join(', ')}| #{e} })" }, block && block.binding
|
24
|
-
elsif expr.match(/\b_\b/)
|
25
|
-
eval "Proc.new { |_| #{expr} }", block && block.binding
|
26
|
-
else
|
27
|
-
leftSection = expr.match(/^\s*(?:[+*\/%&|\^\.=<>\[]|!=)/m)
|
28
|
-
rightSection = expr.match(/[+\-*\/%&|\^\.=<>!]\s*$/m)
|
29
|
-
if leftSection || rightSection then
|
30
|
-
if (leftSection) then
|
31
|
-
params.push('$left')
|
32
|
-
expr = '$left' + expr
|
33
|
-
end
|
34
|
-
if (rightSection) then
|
35
|
-
params.push('$right')
|
36
|
-
expr = expr + '$right'
|
37
|
-
end
|
38
|
-
else
|
39
|
-
self.gsub(
|
40
|
-
/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|self|arguments|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/, ''
|
41
|
-
).scan(
|
42
|
-
/([a-z_$][a-z_$\d]*)/i
|
43
|
-
) do |v|
|
44
|
-
params.push(v) unless params.include?(v)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
eval "Proc.new { |#{params.join(', ')}| #{expr} }", block && block.binding
|
48
|
-
end
|
49
|
-
end
|
50
|
-
=end
|
51
|
-
|
52
|
-
RMTools::String_to_proc_cache = {}
|
53
|
-
def to_proc &block
|
54
|
-
# improving performance
|
55
|
-
if proc = RMTools::String_to_proc_cache[[self, block]]
|
56
|
-
return proc
|
57
|
-
end
|
58
|
-
params = []
|
59
|
-
expr = self
|
60
|
-
sections = expr.split(/\s*->\s*/m)
|
61
|
-
proc =
|
62
|
-
if sections.length > 1
|
63
|
-
str = sections.reverse!.inject { |e, p| "(Proc.new { |#{p.split(/\s/).join(', ')}| #{e} })" }
|
64
|
-
(proc = eval str, block && block.binding).string = str
|
65
|
-
proc
|
66
|
-
elsif expr.match(/\b_\b/)
|
67
|
-
Proc.eval "|_| #{expr}", block && block.binding
|
68
|
-
else
|
69
|
-
leftSection = expr.match(/^\s*(?:[+*\/%&|\^\.=<>\[]|!=)/m)
|
70
|
-
rightSection = expr.match(/[+\-*\/%&|\^\.=<>!]\s*$/m)
|
71
|
-
if leftSection || rightSection
|
72
|
-
if leftSection
|
73
|
-
params.push('__left')
|
74
|
-
expr = '__left' + expr
|
75
|
-
end
|
76
|
-
if rightSection
|
77
|
-
params.push('__right')
|
78
|
-
expr = expr + '__right'
|
79
|
-
end
|
80
|
-
else
|
81
|
-
params = gsub(/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|self|arguments|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/, ''
|
82
|
-
).scan(
|
83
|
-
/([a-z_$][a-z_$\d]*)/i
|
84
|
-
).uniq
|
85
|
-
end
|
86
|
-
Proc.eval "|#{params.join(', ')}| #{expr}", block && block.binding
|
87
|
-
end
|
88
|
-
RMTools::String_to_proc_cache[[self, block]] ||= proc
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
|