otaku 0.3.0 → 0.4.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.
- data/HISTORY.txt +6 -0
- data/README.rdoc +16 -23
- data/Rakefile +2 -3
- data/VERSION +1 -1
- data/lib/otaku.rb +4 -5
- data/lib/otaku/handler.rb +11 -13
- data/otaku.gemspec +5 -13
- data/spec/integration_spec.rb +13 -18
- metadata +9 -30
- data/lib/otaku/handler/context.rb +0 -43
- data/lib/otaku/handler/magic_proc.rb +0 -116
- data/lib/otaku/handler/processor.rb +0 -78
- data/spec/handler_spec.rb +0 -1128
data/HISTORY.txt
CHANGED
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@ Dead simple server/client service built using eventmachine.
|
|
5
5
|
== Introduction
|
6
6
|
|
7
7
|
Otaku's original intent is to support testing of cross-process stubbing in
|
8
|
-
|
8
|
+
CrossStub (http://github.com/ngty/cross-stub). It's usefulness in other
|
9
9
|
aspects of my hacking life prompts me to extract it out, & package it as a
|
10
10
|
generic solution. Its primary intent is to be dead simple to use & easy to
|
11
11
|
customize, of course, both criteria subjected to very my own tastes.
|
@@ -14,7 +14,7 @@ customize, of course, both criteria subjected to very my own tastes.
|
|
14
14
|
|
15
15
|
It's hosted on rubygems.org:
|
16
16
|
|
17
|
-
$
|
17
|
+
$ gem install otaku
|
18
18
|
|
19
19
|
== Using It
|
20
20
|
|
@@ -33,32 +33,29 @@ It's hosted on rubygems.org:
|
|
33
33
|
Otaku.process('hello')
|
34
34
|
# >> '~ hello ~'
|
35
35
|
|
36
|
-
===
|
36
|
+
=== Wait a minute, how abt contextual references ??
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
Previously, when there is references to local variables outside the proc, we need
|
39
|
+
to start Otaku in a very awkward manner:
|
40
40
|
|
41
|
-
mark
|
42
|
-
Otaku.start do |data|
|
41
|
+
Otaku.start(:mark => '*') do |data|
|
43
42
|
'%s %s %s' % [mark, data, mark]
|
44
43
|
end
|
45
44
|
|
46
|
-
Otaku.process('hello')
|
45
|
+
Otaku.process('hello')
|
46
|
+
# >> '* hello *'
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
This is no longer needed from release-0.4.0 onwards, thanks to the help with
|
49
|
+
SerializableProc (http://github.com/ngty/serializable_proc), contextual references
|
50
|
+
to global, class, instance & local variables are automatically taken care of:
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
53
|
+
Otaku.start do |data|
|
54
|
+
[x, @x, @@x, $x].join(data)
|
54
55
|
end
|
55
56
|
|
56
|
-
Otaku.process('
|
57
|
-
|
58
|
-
Anything that can be marshalled can be passed as a context. The exception is
|
59
|
-
proc, which cannot be marshalled, yet it can still be passed in. However, in
|
60
|
-
the process, all contextual references within the proc are lost, so u may
|
61
|
-
want to exercise care when playing with proc.
|
57
|
+
Otaku.process(' & ')
|
58
|
+
# >> 'lx & ix & cx & gx'
|
62
59
|
|
63
60
|
== Configuraing It
|
64
61
|
|
@@ -90,10 +87,6 @@ Configuring can be done via:
|
|
90
87
|
|
91
88
|
Otaku.init_wait_time = 10
|
92
89
|
|
93
|
-
== TODO
|
94
|
-
|
95
|
-
1. Currently, only integration testing is done ...
|
96
|
-
|
97
90
|
== Note on Patches/Pull Requests
|
98
91
|
|
99
92
|
* Fork the project.
|
data/Rakefile
CHANGED
@@ -4,6 +4,7 @@ require 'rake'
|
|
4
4
|
begin
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
7
8
|
gem.name = "otaku"
|
8
9
|
gem.summary = %Q{Dead simple service framework built on eventmachine}
|
9
10
|
gem.description = %Q{}
|
@@ -12,9 +13,7 @@ begin
|
|
12
13
|
gem.authors = ["NgTzeYang"]
|
13
14
|
gem.add_development_dependency "bacon", ">= 0"
|
14
15
|
gem.add_dependency "eventmachine", ">= 0.12.10"
|
15
|
-
gem.add_dependency "
|
16
|
-
gem.add_dependency "ruby_parser", ">= 2.0.4"
|
17
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
gem.add_dependency "serializable_proc", ">= 0.4.0"
|
18
17
|
end
|
19
18
|
Jeweler::GemcutterTasks.new
|
20
19
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/otaku.rb
CHANGED
@@ -3,8 +3,7 @@ require 'forwardable'
|
|
3
3
|
require 'eventmachine'
|
4
4
|
require 'logger'
|
5
5
|
require 'base64'
|
6
|
-
require '
|
7
|
-
require 'ruby_parser'
|
6
|
+
require 'serializable_proc'
|
8
7
|
|
9
8
|
require 'otaku/encoder'
|
10
9
|
require 'otaku/handler'
|
@@ -21,7 +20,7 @@ module Otaku
|
|
21
20
|
:address => '127.0.0.1',
|
22
21
|
:port => 10999,
|
23
22
|
:log_file => '/tmp/otaku.log',
|
24
|
-
:init_wait_time => 2 * (RUBY_PLATFORM =~ /java/i ?
|
23
|
+
:init_wait_time => 2 * (RUBY_PLATFORM =~ /java/i ? 5 : 1)
|
25
24
|
}
|
26
25
|
|
27
26
|
class << self
|
@@ -43,9 +42,9 @@ module Otaku
|
|
43
42
|
File.expand_path(File.dirname(__FILE__))
|
44
43
|
end
|
45
44
|
|
46
|
-
def start(
|
45
|
+
def start(&handler)
|
47
46
|
raise HandlerNotDefinedError unless block_given?
|
48
|
-
Server.handler = Handler.new(
|
47
|
+
Server.handler = Handler.new(handler)
|
49
48
|
Server.start
|
50
49
|
end
|
51
50
|
|
data/lib/otaku/handler.rb
CHANGED
@@ -1,32 +1,30 @@
|
|
1
|
-
require 'otaku/handler/magic_proc'
|
2
|
-
require 'otaku/handler/context'
|
3
|
-
require 'otaku/handler/processor'
|
4
|
-
|
5
1
|
module Otaku
|
6
2
|
class Handler
|
7
3
|
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(context, handler)
|
11
|
-
@context = Context.new(context)
|
12
|
-
@processor = Processor.new(handler)
|
4
|
+
def initialize(handler)
|
5
|
+
@proc = SerializableProc.new(&handler)
|
13
6
|
end
|
14
7
|
|
15
8
|
def process(data)
|
16
|
-
@
|
9
|
+
@proc.call(data)
|
17
10
|
end
|
18
11
|
|
19
12
|
def root
|
20
|
-
|
13
|
+
@proc.file
|
21
14
|
end
|
22
15
|
|
23
16
|
def marshal_dump
|
24
|
-
|
17
|
+
@proc
|
25
18
|
end
|
26
19
|
|
27
20
|
def marshal_load(data)
|
28
|
-
@
|
21
|
+
@proc = data
|
29
22
|
end
|
30
23
|
|
31
24
|
end
|
25
|
+
|
26
|
+
class ::SerializableProc
|
27
|
+
attr_reader :file
|
28
|
+
end
|
29
|
+
|
32
30
|
end
|
data/otaku.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{otaku}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["NgTzeYang"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-09-15}
|
13
13
|
s.description = %q{}
|
14
14
|
s.email = %q{ngty77@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,12 +28,8 @@ Gem::Specification.new do |s|
|
|
28
28
|
"lib/otaku/client.rb",
|
29
29
|
"lib/otaku/encoder.rb",
|
30
30
|
"lib/otaku/handler.rb",
|
31
|
-
"lib/otaku/handler/context.rb",
|
32
|
-
"lib/otaku/handler/magic_proc.rb",
|
33
|
-
"lib/otaku/handler/processor.rb",
|
34
31
|
"lib/otaku/server.rb",
|
35
32
|
"otaku.gemspec",
|
36
|
-
"spec/handler_spec.rb",
|
37
33
|
"spec/integration_spec.rb",
|
38
34
|
"spec/spec_helper.rb"
|
39
35
|
]
|
@@ -44,7 +40,6 @@ Gem::Specification.new do |s|
|
|
44
40
|
s.summary = %q{Dead simple service framework built on eventmachine}
|
45
41
|
s.test_files = [
|
46
42
|
"spec/integration_spec.rb",
|
47
|
-
"spec/handler_spec.rb",
|
48
43
|
"spec/spec_helper.rb",
|
49
44
|
"examples/unittest/client.rb",
|
50
45
|
"examples/unittest/tests/b_test.rb",
|
@@ -60,19 +55,16 @@ Gem::Specification.new do |s|
|
|
60
55
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
61
56
|
s.add_development_dependency(%q<bacon>, [">= 0"])
|
62
57
|
s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
|
63
|
-
s.add_runtime_dependency(%q<
|
64
|
-
s.add_runtime_dependency(%q<ruby_parser>, [">= 2.0.4"])
|
58
|
+
s.add_runtime_dependency(%q<serializable_proc>, [">= 0.4.0"])
|
65
59
|
else
|
66
60
|
s.add_dependency(%q<bacon>, [">= 0"])
|
67
61
|
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
68
|
-
s.add_dependency(%q<
|
69
|
-
s.add_dependency(%q<ruby_parser>, [">= 2.0.4"])
|
62
|
+
s.add_dependency(%q<serializable_proc>, [">= 0.4.0"])
|
70
63
|
end
|
71
64
|
else
|
72
65
|
s.add_dependency(%q<bacon>, [">= 0"])
|
73
66
|
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
74
|
-
s.add_dependency(%q<
|
75
|
-
s.add_dependency(%q<ruby_parser>, [">= 2.0.4"])
|
67
|
+
s.add_dependency(%q<serializable_proc>, [">= 0.4.0"])
|
76
68
|
end
|
77
69
|
end
|
78
70
|
|
data/spec/integration_spec.rb
CHANGED
@@ -25,40 +25,35 @@ describe "Otaku Service" do
|
|
25
25
|
Otaku.process('hello').should.equal '~ hello ~'
|
26
26
|
end
|
27
27
|
|
28
|
-
should '
|
28
|
+
should 'succeed w proc that has contextual reference' do
|
29
29
|
mark = '*'
|
30
|
-
Otaku.start{|data| '%s %s %s' % [mark, data, mark] }
|
31
|
-
lambda { Otaku.process('hello') }.should.raise(Otaku::DataProcessError).
|
32
|
-
message.should.match(/#<NameError: undefined local variable or method `mark' for /)
|
33
|
-
end
|
34
|
-
|
35
|
-
should 'succeed w proc that has non-proc contextual reference & has context specified' do
|
36
|
-
Otaku.start(:mark => '*') {|data| '%s %s %s' % [mark, data, mark] }
|
37
|
-
Otaku.process('hello').should.equal('* hello *')
|
38
|
-
end
|
39
|
-
|
40
|
-
should 'succeed w proc that has proc contextual reference & has context specified' do
|
41
|
-
Otaku.start(:mark => lambda { '*' }) {|data| '%s %s %s' % [mark.call, data, mark.call] }
|
30
|
+
Otaku.start {|data| '%s %s %s' % [mark, data, mark] }
|
42
31
|
Otaku.process('hello').should.equal('* hello *')
|
43
32
|
end
|
44
33
|
|
45
34
|
should 'reflect __FILE__ as captured when declaring proc' do
|
46
|
-
Otaku.start{|data| __FILE__ }
|
47
|
-
Otaku.process(:watever_data).should.equal(
|
35
|
+
Otaku.start {|data| __FILE__ }
|
36
|
+
Otaku.process(:watever_data).should.equal(__FILE__)
|
48
37
|
end
|
49
38
|
|
50
39
|
should 'reflect __LINE__ as captured when declaring proc' do
|
51
40
|
Otaku.start{|data| __LINE__ }
|
52
|
-
Otaku.process(:watever_data).should.equal(__LINE__
|
41
|
+
Otaku.process(:watever_data).should.equal(__LINE__ - 1)
|
53
42
|
end
|
54
43
|
|
55
44
|
should 'have $LOAD_PATH include Otaku.root' do
|
56
|
-
Otaku.start
|
45
|
+
Otaku.start do |data|
|
46
|
+
@@_not_isolated_vars = :global
|
47
|
+
$LOAD_PATH
|
48
|
+
end
|
57
49
|
Otaku.process(:watever_data).should.include(Otaku.root)
|
58
50
|
end
|
59
51
|
|
60
52
|
should 'have $LOAD_PATH include Otaku::Server#handler.root' do
|
61
|
-
Otaku.start
|
53
|
+
Otaku.start do |data|
|
54
|
+
@@_not_isolated_vars = :global
|
55
|
+
$LOAD_PATH
|
56
|
+
end
|
62
57
|
Otaku.process(:watever_data).should.include(Otaku::Server.handler.root)
|
63
58
|
end
|
64
59
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: otaku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- NgTzeYang
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-15 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -49,37 +49,21 @@ dependencies:
|
|
49
49
|
type: :runtime
|
50
50
|
version_requirements: *id002
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
|
-
name:
|
52
|
+
name: serializable_proc
|
53
53
|
prerelease: false
|
54
54
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
55
|
none: false
|
56
56
|
requirements:
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
hash:
|
59
|
+
hash: 15
|
60
60
|
segments:
|
61
|
-
- 1
|
62
|
-
- 2
|
63
|
-
- 4
|
64
|
-
version: 1.2.4
|
65
|
-
type: :runtime
|
66
|
-
version_requirements: *id003
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
name: ruby_parser
|
69
|
-
prerelease: false
|
70
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
-
none: false
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
hash: 7
|
76
|
-
segments:
|
77
|
-
- 2
|
78
61
|
- 0
|
79
62
|
- 4
|
80
|
-
|
63
|
+
- 0
|
64
|
+
version: 0.4.0
|
81
65
|
type: :runtime
|
82
|
-
version_requirements: *
|
66
|
+
version_requirements: *id003
|
83
67
|
description: ""
|
84
68
|
email: ngty77@gmail.com
|
85
69
|
executables: []
|
@@ -101,12 +85,8 @@ files:
|
|
101
85
|
- lib/otaku/client.rb
|
102
86
|
- lib/otaku/encoder.rb
|
103
87
|
- lib/otaku/handler.rb
|
104
|
-
- lib/otaku/handler/context.rb
|
105
|
-
- lib/otaku/handler/magic_proc.rb
|
106
|
-
- lib/otaku/handler/processor.rb
|
107
88
|
- lib/otaku/server.rb
|
108
89
|
- otaku.gemspec
|
109
|
-
- spec/handler_spec.rb
|
110
90
|
- spec/integration_spec.rb
|
111
91
|
- spec/spec_helper.rb
|
112
92
|
- examples/unittest/client.rb
|
@@ -150,7 +130,6 @@ specification_version: 3
|
|
150
130
|
summary: Dead simple service framework built on eventmachine
|
151
131
|
test_files:
|
152
132
|
- spec/integration_spec.rb
|
153
|
-
- spec/handler_spec.rb
|
154
133
|
- spec/spec_helper.rb
|
155
134
|
- examples/unittest/client.rb
|
156
135
|
- examples/unittest/tests/b_test.rb
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Otaku
|
2
|
-
class Handler
|
3
|
-
class Context #:nodoc:
|
4
|
-
|
5
|
-
attr_reader :code
|
6
|
-
|
7
|
-
def initialize(methods_hash)
|
8
|
-
@code = 'Class.new{ %s }.new' %
|
9
|
-
methods_hash.map do |method, val|
|
10
|
-
'def %s; %s; end' % [method, method_body(val)]
|
11
|
-
end.sort.join('; ')
|
12
|
-
end
|
13
|
-
|
14
|
-
def eval!
|
15
|
-
eval(@code, nil, '(generated class)', 1)
|
16
|
-
end
|
17
|
-
|
18
|
-
def marshal_dump
|
19
|
-
[@code]
|
20
|
-
end
|
21
|
-
|
22
|
-
def marshal_load(data)
|
23
|
-
@code, _ = data
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def method_body(val)
|
29
|
-
if val.is_a?(Proc)
|
30
|
-
"Encoder.decode(%|#{Encoder.encode(magic_proc(val)).gsub('|','\|')}|).eval!"
|
31
|
-
else
|
32
|
-
"Encoder.decode(%|#{Encoder.encode(val).gsub('|','\|')}|)"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def magic_proc(block)
|
37
|
-
MagicProc.new(block)
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
@@ -1,116 +0,0 @@
|
|
1
|
-
module Otaku
|
2
|
-
class Handler
|
3
|
-
class MagicProc #:nodoc:
|
4
|
-
|
5
|
-
RUBY_PARSER = RubyParser.new
|
6
|
-
RUBY_2_RUBY = Ruby2Ruby.new
|
7
|
-
|
8
|
-
attr_reader :file, :line, :code
|
9
|
-
|
10
|
-
def initialize(block)
|
11
|
-
@cache = {:block => block}
|
12
|
-
extract_file_and_line_and_code
|
13
|
-
@cache = nil
|
14
|
-
end
|
15
|
-
|
16
|
-
def eval!
|
17
|
-
eval(@code, nil, @file, @line)
|
18
|
-
end
|
19
|
-
|
20
|
-
def marshal_dump
|
21
|
-
[@code, @file, @line]
|
22
|
-
end
|
23
|
-
|
24
|
-
def marshal_load(data)
|
25
|
-
@code, @file, @line = data
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def extract_file_and_line_and_code
|
31
|
-
code, remaining = code_fragments
|
32
|
-
|
33
|
-
while frag = remaining[frag_regexp,1]
|
34
|
-
begin
|
35
|
-
sexp = RUBY_PARSER.parse(replace_magic_vars(code += frag))
|
36
|
-
if sexp.inspect =~ sexp_regexp
|
37
|
-
@code = revert_magic_vars(RUBY_2_RUBY.process(sexp)).sub('proc {','lambda {')
|
38
|
-
break
|
39
|
-
end
|
40
|
-
rescue SyntaxError, Racc::ParseError, NoMethodError
|
41
|
-
remaining.sub!(frag,'')
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def code_fragments
|
47
|
-
ignore, start_marker, arg =
|
48
|
-
[:ignore, :start_marker, :arg].map{|key| code_match_args[key] }
|
49
|
-
[
|
50
|
-
arg ? "proc #{start_marker} |#{arg}|" : "proc #{start_marker}",
|
51
|
-
source_code.sub(ignore, '')
|
52
|
-
]
|
53
|
-
end
|
54
|
-
|
55
|
-
def sexp_regexp
|
56
|
-
@cache[:sexp_regexp] ||= (
|
57
|
-
Regexp.new([
|
58
|
-
Regexp.quote("s(:iter, s(:call, nil, :"),
|
59
|
-
"(proc|lambda)",
|
60
|
-
Regexp.quote(", s(:arglist)), "),
|
61
|
-
'(%s|%s|%s)' % [
|
62
|
-
Regexp.quote('s(:masgn, s(:array, s('),
|
63
|
-
Regexp.quote('s(:lasgn, :'),
|
64
|
-
Regexp.quote('nil, s(')
|
65
|
-
]
|
66
|
-
].join)
|
67
|
-
)
|
68
|
-
end
|
69
|
-
|
70
|
-
def frag_regexp
|
71
|
-
@cache[:frag_regexp] ||= (
|
72
|
-
end_marker = {'do' => 'end', '{' => '\}'}[code_match_args[:start_marker]]
|
73
|
-
/^(.*?\W#{end_marker})/m
|
74
|
-
)
|
75
|
-
end
|
76
|
-
|
77
|
-
def code_regexp
|
78
|
-
@cache[:code_regexp] ||=
|
79
|
-
/^(.*?(lambda|proc|Proc\.new)?\s*(do|\{)\s*(\|(.*?)\|\s*)?)/m
|
80
|
-
end
|
81
|
-
|
82
|
-
def code_match_args
|
83
|
-
@cache[:code_match_args] ||= (
|
84
|
-
args = source_code.match(code_regexp)
|
85
|
-
{
|
86
|
-
:ignore => args[1],
|
87
|
-
:start_marker => args[3],
|
88
|
-
:arg => args[5]
|
89
|
-
}
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
def source_code
|
94
|
-
@cache[:source_code] ||= (
|
95
|
-
file, line = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+).*?>$/.match(@cache[:block].inspect)[1..2]
|
96
|
-
@file = File.expand_path(file)
|
97
|
-
@line = line.to_i
|
98
|
-
File.readlines(@file)[@line.pred .. -1].join
|
99
|
-
)
|
100
|
-
end
|
101
|
-
|
102
|
-
def replace_magic_vars(code)
|
103
|
-
%w{__FILE__ __LINE__}.inject(code) do |code, var|
|
104
|
-
code.gsub(var, "%|((#{var}))|")
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def revert_magic_vars(code)
|
109
|
-
%w{__FILE__ __LINE__}.inject(code) do |code, var|
|
110
|
-
code.gsub(%|"((#{var}))"|, var)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|