rmtools 1.1.6 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|