otaku 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ rdoc
19
19
  pkg
20
20
 
21
21
  ## PROJECT::SPECIFIC
22
+ tmp/*
@@ -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
1
+ 0.2.2
@@ -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)
@@ -3,11 +3,17 @@ module Otaku
3
3
 
4
4
  def initialize(context, handler)
5
5
  @context = __context_as_code__(context)
6
- @proc = __proc_as_code__(handler)
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 [](data)
10
- eval(@context).instance_exec(data, &eval(@proc))
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
- def to_code
36
- code, remaining = code_fragments
37
-
38
- while frag = remaining[frag_regexp,1]
39
- begin
40
- sexp = RUBY_PARSER.parse(code += frag, File.expand_path(@file))
41
- return RUBY_2_RUBY.process(sexp) if sexp.inspect =~ sexp_regexp
42
- rescue SyntaxError, Racc::ParseError, NoMethodError
43
- remaining.sub!(frag,'')
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
- def code_fragments
49
- ignore, start_marker, arg =
50
- [:ignore, :start_marker, :arg].map{|key| code_match_args[key] }
51
- [
52
- "proc #{start_marker} |#{arg}| ",
53
- source_code.sub(ignore, '')
54
- ]
55
- end
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
- def sexp_regexp
58
- @sexp_regexp ||= (
59
- Regexp.new([
60
- Regexp.quote("s(:iter, s(:call, nil, :"),
61
- "(proc|lambda)",
62
- Regexp.quote(", s(:arglist)), s(:lasgn, :#{code_match_args[:arg]}), s("),
63
- ].join)
64
- )
65
- end
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
- def frag_regexp
68
- @frag_regexp ||= (
69
- end_marker = {'do' => 'end', '{' => '\}'}[code_match_args[:start_marker]]
70
- /^(.*?\W#{end_marker})/m
71
- )
72
- end
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
- def code_regexp
75
- @code_regexp ||=
76
- /^(.*?(Otaku\.start.*?|lambda|proc|Proc\.new)\s*(do|\{)\s*\|(\w+)\|\s*)/m
77
- end
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
- def code_match_args
80
- @code_match_args ||= (
81
- args = source_code.match(code_regexp)
82
- {
83
- :ignore => args[1],
84
- :start_marker => args[3],
85
- :arg => args[4]
86
- }
87
- )
88
- end
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
- def source_code
91
- @source_code ||= (
92
- @file, line_no = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+).*?>$/.match(@block.inspect)[1..2]
93
- @line_no = line_no.to_i
94
- File.readlines(@file)[@line_no.pred .. -1].join
95
- )
96
- end
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
 
@@ -20,9 +20,10 @@ module Otaku
20
20
  end
21
21
 
22
22
  def run_server_script
23
- script = File.join(File.dirname(__FILE__), '..', 'otaku.rb')
23
+ script = File.join(Otaku.root, 'otaku.rb')
24
24
  args = Encoder.encode(:config => Otaku.config, :handler => @handler)
25
- @process = IO.popen(%|#{Otaku.ruby} #{script} "#{args.gsub('"','\"')}"|,'r')
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[data]
49
+ Server.handler.process(data)
49
50
  rescue
50
51
  error = DataProcessError.new($!.inspect)
51
52
  log(error.inspect)
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{otaku}
8
- s.version = "0.2.1"
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-19}
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 = [
@@ -31,7 +31,7 @@ describe "Otaku Service Handler" do
31
31
 
32
32
  describe '>> initializing proc' do
33
33
 
34
- expected = "proc { |watever| [\"a\", \"b\"].map { |x| puts(x) } }"
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
- proc { |watever|
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
- proc { |watever|
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
- proc { |watever| %w{a b}.map{|x| puts x } }
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 "handle __FILE__ correctly [##{__LINE__}]" do
216
+ should "leave __FILE__ as __FILE__ [##{__LINE__}]" do
217
217
  Otaku.start { |watever| __FILE__ }.proc.should.
218
- equal("proc { |watever| \"%s\" }" % File.expand_path('spec/handler_spec.rb'))
218
+ equal("lambda { |watever| __FILE__ }" % File.expand_path('spec/handler_spec.rb'))
219
219
  end
220
220
 
221
- should "handle __LINE__ incorrectly [##{__LINE__}]" do
221
+ should "leave __LINE__ as __LINE__ [##{__LINE__}]" do
222
222
  Otaku.start { |watever| __LINE__ }.proc.should.
223
- equal("proc { |watever| 1 }")
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
@@ -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 'not reflect __LINE__ as captured when declaring proc' do
45
+ should 'reflect __LINE__ as captured when declaring proc' do
46
46
  Otaku.start{|data| __LINE__ }
47
- Otaku.process(:watever_data).should.not.equal(__LINE__.pred)
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: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 1
10
- version: 0.2.1
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-19 00:00:00 +08:00
18
+ date: 2010-07-21 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency