otaku 0.2.1 → 0.2.2
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/.gitignore +1 -0
- data/HISTORY.txt +19 -0
- data/VERSION +1 -1
- data/lib/otaku.rb +4 -1
- data/lib/otaku/handler.rb +84 -61
- data/lib/otaku/server.rb +4 -3
- data/otaku.gemspec +2 -2
- data/spec/handler_spec.rb +26 -8
- data/spec/integration_spec.rb +12 -2
- metadata +4 -4
data/.gitignore
CHANGED
data/HISTORY.txt
CHANGED
@@ -1,5 +1,24 @@
|
|
1
|
+
=== 0.2.2 2010-07-21
|
2
|
+
|
3
|
+
= Features
|
4
|
+
* $LOAD_PATH include the directory where the file calling Otaku.start is located, thus
|
5
|
+
user no longer need to verbosely define the full path of the file to require [#ngty]
|
6
|
+
|
7
|
+
= Maintenance
|
8
|
+
* magic variable __FILE__ is now derived the same way as __LINE__ (see below) [#ngty]
|
9
|
+
|
10
|
+
= Bug Fixes
|
11
|
+
* magic variable __LINE__ now works as expected (the line where the proc is defined in file,
|
12
|
+
instead of the string eval line) [#ngty]
|
13
|
+
* fixed unexpected failure in specs as a result of using installed otaku, instead of the
|
14
|
+
one under current project directory (by passing -I when running the sub-process server
|
15
|
+
script) [#ngty]
|
16
|
+
|
1
17
|
=== 0.2.1 2010-07-19
|
2
18
|
|
19
|
+
= Maintenance
|
20
|
+
* logging support is moved directly under Otaku module [#ngty]
|
21
|
+
|
3
22
|
= Bug Fixes
|
4
23
|
* closing of logger is done ONLY if the logger has been initialized [#ngty]
|
5
24
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
data/lib/otaku.rb
CHANGED
@@ -5,7 +5,6 @@ require 'base64'
|
|
5
5
|
require 'ruby2ruby'
|
6
6
|
require 'ruby_parser'
|
7
7
|
|
8
|
-
# $LOAD_PATH.unshift(File.dirname(__FILE__))
|
9
8
|
require 'otaku/encoder'
|
10
9
|
require 'otaku/handler'
|
11
10
|
require 'otaku/server'
|
@@ -39,6 +38,10 @@ module Otaku
|
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
41
|
+
def root
|
42
|
+
File.expand_path(File.dirname(__FILE__))
|
43
|
+
end
|
44
|
+
|
42
45
|
def start(context = {}, &handler)
|
43
46
|
raise HandlerNotDefinedError unless block_given?
|
44
47
|
Server.handler = Handler.new(context, handler)
|
data/lib/otaku/handler.rb
CHANGED
@@ -3,11 +3,17 @@ module Otaku
|
|
3
3
|
|
4
4
|
def initialize(context, handler)
|
5
5
|
@context = __context_as_code__(context)
|
6
|
-
|
6
|
+
magic_proc = MagicProc.new(handler)
|
7
|
+
@proc, @file, @line = [:code, :file, :line].map{|meth| magic_proc.send(meth) }
|
7
8
|
end
|
8
9
|
|
9
|
-
def
|
10
|
-
eval(@context
|
10
|
+
def process(data)
|
11
|
+
(instance = eval(@context, nil, '(generated class)', 1)).
|
12
|
+
instance_exec(data, &(block = eval(@proc, nil, @file, @line)))
|
13
|
+
end
|
14
|
+
|
15
|
+
def root
|
16
|
+
File.dirname(@file)
|
11
17
|
end
|
12
18
|
|
13
19
|
private
|
@@ -19,81 +25,98 @@ module Otaku
|
|
19
25
|
end.sort.join('; ')
|
20
26
|
end
|
21
27
|
|
22
|
-
def __proc_as_code__(block)
|
23
|
-
MagicProc.new(block).to_code
|
24
|
-
end
|
25
|
-
|
26
28
|
class MagicProc
|
27
29
|
|
28
30
|
RUBY_PARSER = RubyParser.new
|
29
31
|
RUBY_2_RUBY = Ruby2Ruby.new
|
30
32
|
|
33
|
+
attr_reader :file, :line, :code
|
34
|
+
|
31
35
|
def initialize(block)
|
32
36
|
@block = block
|
37
|
+
extract_file_and_line_and_code
|
33
38
|
end
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
private
|
41
|
+
|
42
|
+
def extract_file_and_line_and_code
|
43
|
+
code, remaining = code_fragments
|
44
|
+
|
45
|
+
while frag = remaining[frag_regexp,1]
|
46
|
+
begin
|
47
|
+
sexp = RUBY_PARSER.parse(replace_magic_vars(code += frag))
|
48
|
+
if sexp.inspect =~ sexp_regexp
|
49
|
+
@code = revert_magic_vars(RUBY_2_RUBY.process(sexp)).sub('proc {','lambda {')
|
50
|
+
break
|
51
|
+
end
|
52
|
+
rescue SyntaxError, Racc::ParseError, NoMethodError
|
53
|
+
remaining.sub!(frag,'')
|
54
|
+
end
|
44
55
|
end
|
45
56
|
end
|
46
|
-
end
|
47
57
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
def code_fragments
|
59
|
+
ignore, start_marker, arg =
|
60
|
+
[:ignore, :start_marker, :arg].map{|key| code_match_args[key] }
|
61
|
+
[
|
62
|
+
"proc #{start_marker} |#{arg}| ",
|
63
|
+
source_code.sub(ignore, '')
|
64
|
+
]
|
65
|
+
end
|
56
66
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
def sexp_regexp
|
68
|
+
@sexp_regexp ||= (
|
69
|
+
Regexp.new([
|
70
|
+
Regexp.quote("s(:iter, s(:call, nil, :"),
|
71
|
+
"(proc|lambda)",
|
72
|
+
Regexp.quote(", s(:arglist)), s(:lasgn, :#{code_match_args[:arg]}), s("),
|
73
|
+
].join)
|
74
|
+
)
|
75
|
+
end
|
66
76
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
77
|
+
def frag_regexp
|
78
|
+
@frag_regexp ||= (
|
79
|
+
end_marker = {'do' => 'end', '{' => '\}'}[code_match_args[:start_marker]]
|
80
|
+
/^(.*?\W#{end_marker})/m
|
81
|
+
)
|
82
|
+
end
|
73
83
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
84
|
+
def code_regexp
|
85
|
+
@code_regexp ||=
|
86
|
+
/^(.*?(Otaku\.start.*?|lambda|proc|Proc\.new)\s*(do|\{)\s*\|(\w+)\|\s*)/m
|
87
|
+
end
|
78
88
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
+
def code_match_args
|
90
|
+
@code_match_args ||= (
|
91
|
+
args = source_code.match(code_regexp)
|
92
|
+
{
|
93
|
+
:ignore => args[1],
|
94
|
+
:start_marker => args[3],
|
95
|
+
:arg => args[4]
|
96
|
+
}
|
97
|
+
)
|
98
|
+
end
|
89
99
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
100
|
+
def source_code
|
101
|
+
@source_code ||= (
|
102
|
+
file, line = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+).*?>$/.match(@block.inspect)[1..2]
|
103
|
+
@file = File.expand_path(file)
|
104
|
+
@line = line.to_i
|
105
|
+
File.readlines(@file)[@line.pred .. -1].join
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
def replace_magic_vars(code)
|
110
|
+
%w{__FILE__ __LINE__}.inject(code) do |code, var|
|
111
|
+
code.gsub(var, "%|((#{var}))|")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def revert_magic_vars(code)
|
116
|
+
%w{__FILE__ __LINE__}.inject(code) do |code, var|
|
117
|
+
code.gsub(%|"((#{var}))"|, var)
|
118
|
+
end
|
119
|
+
end
|
97
120
|
|
98
121
|
end
|
99
122
|
|
data/lib/otaku/server.rb
CHANGED
@@ -20,9 +20,10 @@ module Otaku
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def run_server_script
|
23
|
-
script = File.join(
|
23
|
+
script = File.join(Otaku.root, 'otaku.rb')
|
24
24
|
args = Encoder.encode(:config => Otaku.config, :handler => @handler)
|
25
|
-
|
25
|
+
load_paths = [@handler.root, Otaku.root].join(' -I')
|
26
|
+
@process = IO.popen(%|#{Otaku.ruby} -I#{load_paths} #{script} "#{args.gsub('"','\"')}"|,'r')
|
26
27
|
sleep Otaku.init_wait_time
|
27
28
|
end
|
28
29
|
|
@@ -45,7 +46,7 @@ module Otaku
|
|
45
46
|
|
46
47
|
def process_data(data)
|
47
48
|
begin
|
48
|
-
Server.handler
|
49
|
+
Server.handler.process(data)
|
49
50
|
rescue
|
50
51
|
error = DataProcessError.new($!.inspect)
|
51
52
|
log(error.inspect)
|
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.2.
|
8
|
+
s.version = "0.2.2"
|
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-07-
|
12
|
+
s.date = %q{2010-07-21}
|
13
13
|
s.description = %q{}
|
14
14
|
s.email = %q{ngty77@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/spec/handler_spec.rb
CHANGED
@@ -31,7 +31,7 @@ describe "Otaku Service Handler" do
|
|
31
31
|
|
32
32
|
describe '>> initializing proc' do
|
33
33
|
|
34
|
-
expected = "
|
34
|
+
expected = "lambda { |watever| [\"a\", \"b\"].map { |x| puts(x) } }"
|
35
35
|
|
36
36
|
{
|
37
37
|
# ////////////////////////////////////////////////////////////////////////
|
@@ -59,7 +59,7 @@ describe "Otaku Service Handler" do
|
|
59
59
|
end
|
60
60
|
),
|
61
61
|
__LINE__ => (
|
62
|
-
|
62
|
+
lambda { |watever|
|
63
63
|
%w{a b}.map{|x|
|
64
64
|
puts x
|
65
65
|
}
|
@@ -98,7 +98,7 @@ describe "Otaku Service Handler" do
|
|
98
98
|
end
|
99
99
|
),
|
100
100
|
__LINE__ => (
|
101
|
-
|
101
|
+
lambda { |watever|
|
102
102
|
%w{a b}.map{|x| puts x }
|
103
103
|
}
|
104
104
|
),
|
@@ -125,7 +125,7 @@ describe "Otaku Service Handler" do
|
|
125
125
|
proc do |watever| %w{a b}.map do |x| puts x end end
|
126
126
|
),
|
127
127
|
__LINE__ => (
|
128
|
-
|
128
|
+
lambda { |watever| %w{a b}.map{|x| puts x } }
|
129
129
|
),
|
130
130
|
__LINE__ => (
|
131
131
|
Proc.new do |watever| %w{a b}.map do |x| puts x end end
|
@@ -213,14 +213,32 @@ describe "Otaku Service Handler" do
|
|
213
213
|
Otaku.start { |watever| %w{a b}.map { |x| puts x } }.proc.should.equal(expected)
|
214
214
|
end
|
215
215
|
|
216
|
-
should "
|
216
|
+
should "leave __FILE__ as __FILE__ [##{__LINE__}]" do
|
217
217
|
Otaku.start { |watever| __FILE__ }.proc.should.
|
218
|
-
equal("
|
218
|
+
equal("lambda { |watever| __FILE__ }" % File.expand_path('spec/handler_spec.rb'))
|
219
219
|
end
|
220
220
|
|
221
|
-
should "
|
221
|
+
should "leave __LINE__ as __LINE__ [##{__LINE__}]" do
|
222
222
|
Otaku.start { |watever| __LINE__ }.proc.should.
|
223
|
-
equal("
|
223
|
+
equal("lambda { |watever| __LINE__ }")
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
describe '>> fetching root' do
|
229
|
+
should 'return directory of current file' do
|
230
|
+
Otaku.start { |watever| __LINE__ }.root.should.equal(File.expand_path(File.dirname(__FILE__)))
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe '>> processing specified data' do
|
235
|
+
|
236
|
+
should 'reflect __FILE__ captured when the proc was 1st defined' do
|
237
|
+
Otaku.start{ |watever| __FILE__ }.process(:fake_data).should.equal(File.expand_path(__FILE__))
|
238
|
+
end
|
239
|
+
|
240
|
+
should 'reflect __LINE__ captured when the proc was 1st defined' do
|
241
|
+
Otaku.start{ |watever| __LINE__ }.process(:fake_data).should.equal(__LINE__)
|
224
242
|
end
|
225
243
|
|
226
244
|
end
|
data/spec/integration_spec.rb
CHANGED
@@ -42,9 +42,19 @@ describe "Otaku Service" do
|
|
42
42
|
Otaku.process(:watever_data).should.equal(File.expand_path(__FILE__))
|
43
43
|
end
|
44
44
|
|
45
|
-
should '
|
45
|
+
should 'reflect __LINE__ as captured when declaring proc' do
|
46
46
|
Otaku.start{|data| __LINE__ }
|
47
|
-
Otaku.process(:watever_data).should.
|
47
|
+
Otaku.process(:watever_data).should.equal(__LINE__.pred)
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'have $LOAD_PATH include Otaku.root' do
|
51
|
+
Otaku.start{|data| $LOAD_PATH }
|
52
|
+
Otaku.process(:watever_data).should.include(Otaku.root)
|
53
|
+
end
|
54
|
+
|
55
|
+
should 'have $LOAD_PATH include Otaku::Server#handler.root' do
|
56
|
+
Otaku.start{|data| $LOAD_PATH }
|
57
|
+
Otaku.process(:watever_data).should.include(Otaku::Server.handler.root)
|
48
58
|
end
|
49
59
|
|
50
60
|
end
|
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: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
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-07-
|
18
|
+
date: 2010-07-21 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|