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 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