serializable_proc 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 0.3.0 (Aug 18, 2010)
2
+
3
+ * added support for defining of custom matchers that enhances static parser to handle
4
+ more initializing cases, other than the current SerializableProc.new, Proc.new, proc
5
+ & lambda [#ngty]
6
+ * ensured subclasses of SerializableProc behaves exactly like SerializableProc [#ngty]
7
+ * partially implemented workaround to ensure the more conservative usages work, quite a
8
+ number of specs still failing though [#ngty]
9
+
1
10
  === 0.2.0 (Aug 18, 2010)
2
11
 
3
12
  * added SerializableProc#to_sexp to facilitate retrieving of sexp representation of the
data/README.rdoc CHANGED
@@ -42,7 +42,7 @@ The following declares all variables as not isolatable:
42
42
 
43
43
  s_proc = SerializableProc.new do
44
44
  @@_not_isolated_vars = :global, :class, :instance, :local
45
- # (blah blah)
45
+ ...
46
46
  end
47
47
 
48
48
  When invoking, Kernel.binding should be passed in to avoid unpleasant surprises:
@@ -77,15 +77,18 @@ to its static analysis nature (see 'Gotchas' section).
77
77
 
78
78
  SerializableProc relies on ParseTree or RubyParser to do code extraction. While running
79
79
  in ParseTree mode, thanks to the goodness of dynamic code analysis, SerializableProc
80
- performs faster by a magnitude of abt 7.5 times for the same ruby, as illustrated with
81
- the following benchmark results (obtained from running the specs suite):
80
+ performs faster by a magnitude of abt 6 times for the same ruby, as illustrated with
81
+ the following benchmark results:
82
82
 
83
- MRI & implementation user system total real
84
- 1.8.7p299 (ParseTree) 0.000000 0.000000 1.310000 1.312676
85
- 1.8.7p299 (RubyParser) 0.000000 0.010000 9.560000 9.706455
86
- 1.9.1p376 (RubyParser) 0.010000 0.010000 8.240000 8.288799
83
+ MRI & implementation user system total real
84
+ 1.8.7p299 (ParseTree) 0.000000 0.000000 3.510000 3.660623
85
+ 1.8.7p299 (RubyParser) 0.000000 0.000000 20.780000 21.328566
86
+ 1.9.1p376 (RubyParser) 0.010000 0.000000 16.990000 17.370586
87
87
 
88
- (the above is run on my x86_64-linux):
88
+ Note:
89
+ * the above are obtained from running the specs suite of 393 specifications with 1330
90
+ requirements
91
+ * hardware & OS specs: x86_64 Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz
89
92
 
90
93
  == Gotchas
91
94
 
@@ -98,14 +101,14 @@ perfect (yet), pls take note of the following:
98
101
  The following initializations throw SerializableProc::CannotAnalyseCodeError:
99
102
 
100
103
  # Multiple SerializableProc.new per line
101
- SerializableProc.new { x } ; SerializableProc.new { y }
104
+ SerializableProc.new { ... } ; SerializableProc.new { ... }
102
105
 
103
106
  # Multiple lambda per line (the same applies to proc & Proc.new)
104
- x_proc = lambda { x } ; y_proc = lambda { y }
107
+ x_proc = lambda { ... } ; y_proc = lambda { ... }
105
108
  SerializableProc.new(&x_proc)
106
109
 
107
110
  # Mixed lambda, proc & Proc.new per line
108
- x_proc = proc { x } ; y_proc = lambda { y }
111
+ x_proc = proc { ... } ; y_proc = lambda { ... }
109
112
  SerializableProc.new(&x_proc)
110
113
 
111
114
  === 2. Limited ways to initialize code blocks
@@ -113,29 +116,79 @@ The following initializations throw SerializableProc::CannotAnalyseCodeError:
113
116
  Code block must be initialized with lambda, proc, Proc.new & SerializableProc.new,
114
117
  the following will throw SerializableProc::CannotAnalyseCodeError:
115
118
 
116
- def create_serializable_proc(&block)
119
+ def create_magic_proc(&block)
117
120
  SerializableProc.new(&block)
118
121
  end
119
122
 
120
- create_serializable_proc { x }
123
+ create_magic_proc { ... }
121
124
 
122
125
  But the following will work as expected:
123
126
 
124
- x_proc = lambda { x }
125
- create_serializable_proc(&x_proc)
127
+ x_proc = lambda { ... }
128
+ create_magic_proc(&x_proc)
129
+
130
+ There are several strategies to workaround this limitation:
131
+
132
+ ==== 2.1. Subclassing SerializableProc
133
+
134
+ Any subclass of SerializableProc shows traits of a SerializableProc:
135
+
136
+ class MagicProc < SerializableProc ; end
137
+ m_proc = MagicProc.new { ... } # m_proc walks & quacks like a SerializableProc
138
+
139
+ ==== 2.2. Adding custom matcher(s)
140
+
141
+ To support more match cases, we can declare new matchers:
142
+
143
+ def work(&block)
144
+ s_proc = SerializableProc.new(&block)
145
+ ...
146
+ end
147
+
148
+ SerializableProc::Parsers::Static.matchers << 'create_magic_proc'
149
+ work { ... }
150
+
151
+ Or if the method above takes arguments:
152
+
153
+ def create_magic_proc(*args, &block)
154
+ s_proc = SerializableProc.new(&block)
155
+ ...
156
+ end
157
+
158
+ SerializableProc::Parsers::Static.matchers << 'create_magic_proc\W+.*?\W+'
159
+ create_magic_proc(1, :a => 2, :b => 3) { ... }
160
+
161
+ === 3. One liner for ...
162
+
163
+ This is embarassing, but being flexible can aggrevates performance even more.
164
+ Currently, the declarative (eg. lambda, proc, SerializableProc.new, Proc.new,
165
+ subclasses of SerializableProc, & any user-defined matcher(s)), & the start of
166
+ the code-block (the 'do' & '{' chars) must be on the same line. Meaning the
167
+ following won't work:
168
+
169
+ SerializableProc.new \
170
+ do
171
+ ...
172
+ end
173
+
174
+ create_magic_proc(
175
+ 1, :a => 2
176
+ ) { ... }
126
177
 
127
178
  == Supported Rubies
128
179
 
129
180
  SerializableProc has been tested to work on the following rubies:
130
181
 
131
182
  1. MRI 1.8.6, 1.8.7 & 1.9.1
183
+ 2. JRuby (partial, the more conservative usages work, quite abit of the specs are failing
184
+ due to JRuby's bug in dumping a proc's line number when we do Proc#inspect)
132
185
 
133
186
  == TODO (just brain-dumping)
134
187
 
135
188
  1. The RubyParser-based implementation probably need alot more optimization to catch up
136
189
  on ParseTree-based one
137
- 2. Implementing alternative means of extracting the code block without requiring help
138
- of ParseTree or RubyParser
190
+ 2. Implementing alternative means (if possible) of extracting the code block without
191
+ requiring help of ParseTree or RubyParser
139
192
  3. Implement workaround to tackle line-numbering bug in JRuby, which causes the
140
193
  RubyParser-based implementation to fail, for more info abt JRuby's line-numbering
141
194
  bug, see http://stackoverflow.com/questions/3454838/jruby-line-numbering-problem &
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -1,6 +1,6 @@
1
1
  class SerializableProc
2
2
  module Parsers
3
- class PT < Base
3
+ class Dynamic < Base
4
4
  class << self
5
5
  def process(block)
6
6
  if Object.const_defined?(:ParseTree)
@@ -3,7 +3,7 @@ class SerializableProc
3
3
  class CannotAnalyseCodeError < Exception ; end
4
4
 
5
5
  module Parsers
6
- class RP < Base
6
+ class Static < Base
7
7
  class << self
8
8
 
9
9
  def process(klass, file, line)
@@ -12,6 +12,10 @@ class SerializableProc
12
12
  extract_code_and_sexp
13
13
  end
14
14
 
15
+ def matchers
16
+ @matchers ||= []
17
+ end
18
+
15
19
  private
16
20
 
17
21
  def extract_code_and_sexp
@@ -19,7 +23,7 @@ class SerializableProc
19
23
  while frag = remaining[/^([^\)]*\))/,1]
20
24
  begin
21
25
  sexp = normalized_eval(sexp_str += frag)
22
- return sexp_derivatives(sexp){|code| unescape_magic_vars(code) }
26
+ return sexp_derivatives(sexp)
23
27
  rescue SyntaxError
24
28
  remaining.sub!(frag,'')
25
29
  end
@@ -49,11 +53,25 @@ class SerializableProc
49
53
  end
50
54
 
51
55
  def raw_sexp_and_marker
56
+ line = @line
57
+ begin
58
+ raw_sexp_and_marker_by_lineno(@line = line)
59
+ rescue CannotAnalyseCodeError
60
+ if RUBY_PLATFORM =~ /java/i
61
+ line += 1
62
+ retry
63
+ else
64
+ raise $!
65
+ end
66
+ end
67
+ end
68
+
69
+ def raw_sexp_and_marker_by_lineno(lineno)
52
70
  # TODO: Ugly chunk, need some lovely cleanup !!
53
- %W{#{@klass}\.new lambda|proc|Proc\.new}.each do |declarative|
71
+ (%W{#{@klass}\.new lambda|proc|Proc\.new} + matchers).each do |declarative|
54
72
  regexp = /^((.*?)(#{declarative})(\s*(?:do|\{)\s*(?:\|(?:[^\|]*)\|\s*)?)(.*)?)$/m
55
73
  raw = raw_code
56
- lines1, lines2 = [(0 .. (@line - 2)), (@line.pred .. -1)].map{|r| raw[r] }
74
+ lines1, lines2 = [(0 .. (lineno - 2)), (lineno.pred .. -1)].map{|r| raw[r] }
57
75
  prepend, type, block_start, append = lines2[0].match(regexp)[2..5] rescue next
58
76
 
59
77
  if lines2[0] =~ /^(.*?\W)?(#{declarative})(\W.*?\W(#{declarative}))+(\W.*)?$/
@@ -61,27 +79,15 @@ class SerializableProc
61
79
  declarative.split('|').join("'/'")
62
80
  raise CannotAnalyseCodeError.new(msg)
63
81
  elsif lines2[0] =~ /^(.*?\W)?(#{declarative})(\W.*)?$/
64
- marker = "__serializable_proc_marker_#{@line}__"
82
+ marker = "__serializable_proc_marker_#{lineno}__"
65
83
  line = "#{prepend}proc#{block_start} #{marker}; #{append}"
66
- lines = lines1.join + escape_magic_vars(line + lines2[1..-1].join)
67
- return [RUBY_PARSER.parse(lines).inspect, marker]
84
+ lines = lines1.join + line + lines2[1..-1].join
85
+ return [RUBY_PARSER.parse(lines, @file).inspect, marker]
68
86
  end
69
87
  end
70
88
  raise CannotAnalyseCodeError.new('Cannot find specified initializer !!')
71
89
  end
72
90
 
73
- def escape_magic_vars(s)
74
- %w{__FILE__ __LINE__}.inject(s) do |s, var|
75
- s.gsub(var, "__serializable_proc_#{var.downcase}__")
76
- end
77
- end
78
-
79
- def unescape_magic_vars(s)
80
- %w{__FILE__ __LINE__}.inject(s) do |s, var|
81
- s.gsub("__serializable_proc_#{var.downcase}__", var)
82
- end
83
- end
84
-
85
91
  def raw_code
86
92
  File.readlines(@file)
87
93
  end
@@ -26,5 +26,5 @@ class SerializableProc
26
26
  end
27
27
  end
28
28
 
29
- require 'serializable_proc/parsers/pt'
30
- require 'serializable_proc/parsers/rp'
29
+ require 'serializable_proc/parsers/dynamic'
30
+ require 'serializable_proc/parsers/static'
@@ -95,7 +95,7 @@ class SerializableProc
95
95
  def initialize(&block)
96
96
  file, line = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+).*?>$/.match(block.inspect)[1..2]
97
97
  @file, @line, @arity = File.expand_path(file), line.to_i, block.arity
98
- @code, @sexp = Parsers::PT.process(block) || Parsers::RP.process(self.class, @file, @line)
98
+ @code, @sexp = Parsers::Dynamic.process(block) || Parsers::Static.process(self.class, file, @line)
99
99
  @binding = Binding.new(block.binding, @sexp[:extracted])
100
100
  end
101
101
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{serializable_proc}
8
- s.version = "0.2.0"
8
+ s.version = "0.3.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"]
@@ -33,8 +33,8 @@ Gem::Specification.new do |s|
33
33
  "lib/serializable_proc/isolatable.rb",
34
34
  "lib/serializable_proc/marshalable.rb",
35
35
  "lib/serializable_proc/parsers.rb",
36
- "lib/serializable_proc/parsers/pt.rb",
37
- "lib/serializable_proc/parsers/rp.rb",
36
+ "lib/serializable_proc/parsers/dynamic.rb",
37
+ "lib/serializable_proc/parsers/static.rb",
38
38
  "serializable_proc.gemspec",
39
39
  "spec/bounded_vars/class_vars_spec.rb",
40
40
  "spec/bounded_vars/class_vars_within_block_scope_spec.rb",
@@ -46,11 +46,21 @@ Gem::Specification.new do |s|
46
46
  "spec/bounded_vars/local_vars_spec.rb",
47
47
  "spec/bounded_vars/local_vars_within_block_scope_spec.rb",
48
48
  "spec/code_block/errors_spec.rb",
49
+ "spec/code_block/magic_vars_spec.rb",
49
50
  "spec/code_block/multiple_arities_spec.rb",
50
51
  "spec/code_block/optional_arity_spec.rb",
51
52
  "spec/code_block/renaming_vars_spec.rb",
52
53
  "spec/code_block/single_arity_spec.rb",
53
54
  "spec/code_block/zero_arity_spec.rb",
55
+ "spec/extending/new_matcher_w_multiple_arities_spec.rb",
56
+ "spec/extending/new_matcher_w_optional_arity_spec.rb",
57
+ "spec/extending/new_matcher_w_single_arity_spec.rb",
58
+ "spec/extending/new_matcher_w_zero_arity_spec.rb",
59
+ "spec/extending/spec_helper.rb",
60
+ "spec/extending/subclassing_w_multiple_arities_spec.rb",
61
+ "spec/extending/subclassing_w_optional_arity_spec.rb",
62
+ "spec/extending/subclassing_w_single_arity_spec.rb",
63
+ "spec/extending/subclassing_w_zero_arity_spec.rb",
54
64
  "spec/proc_like/extras_spec.rb",
55
65
  "spec/proc_like/invoking_with_args_spec.rb",
56
66
  "spec/proc_like/invoking_with_class_vars_spec.rb",
@@ -62,27 +72,13 @@ Gem::Specification.new do |s|
62
72
  "spec/spec_helper.rb"
63
73
  ]
64
74
  s.homepage = %q{http://github.com/ngty/serializable_proc}
65
- s.post_install_message = %q{
66
- /////////////////////////////////////////////////////////////////////////////////
67
-
68
- ** SerializableProc **
69
-
70
- You are installing SerializableProc on a ruby platform & version that supports
71
- ParseTree. With ParseTree, u can enjoy better performance of SerializableProc,
72
- as well as other dynamic code analysis goodness, as compared to the default
73
- implementation using RubyParser's less flexible static code analysis.
74
-
75
- Anyway, u have been informed, SerializableProc will fallback on its default
76
- implementation using RubyParser.
77
-
78
- /////////////////////////////////////////////////////////////////////////////////
79
- }
80
75
  s.rdoc_options = ["--charset=UTF-8"]
81
76
  s.require_paths = ["lib"]
82
- s.rubygems_version = %q{1.3.7}
77
+ s.rubygems_version = %q{1.3.6}
83
78
  s.summary = %q{Proc that can be serialized (as the name suggests)}
84
79
  s.test_files = [
85
- "spec/proc_like/extras_spec.rb",
80
+ "spec/spec_helper.rb",
81
+ "spec/proc_like/extras_spec.rb",
86
82
  "spec/proc_like/invoking_with_local_vars_spec.rb",
87
83
  "spec/proc_like/invoking_with_instance_vars_spec.rb",
88
84
  "spec/proc_like/invoking_with_class_vars_spec.rb",
@@ -90,12 +86,22 @@ Gem::Specification.new do |s|
90
86
  "spec/proc_like/others_spec.rb",
91
87
  "spec/proc_like/invoking_with_global_vars_spec.rb",
92
88
  "spec/proc_like/marshalling_spec.rb",
89
+ "spec/code_block/magic_vars_spec.rb",
93
90
  "spec/code_block/multiple_arities_spec.rb",
94
91
  "spec/code_block/zero_arity_spec.rb",
95
92
  "spec/code_block/errors_spec.rb",
96
93
  "spec/code_block/renaming_vars_spec.rb",
97
94
  "spec/code_block/single_arity_spec.rb",
98
95
  "spec/code_block/optional_arity_spec.rb",
96
+ "spec/extending/subclassing_w_optional_arity_spec.rb",
97
+ "spec/extending/subclassing_w_single_arity_spec.rb",
98
+ "spec/extending/new_matcher_w_multiple_arities_spec.rb",
99
+ "spec/extending/subclassing_w_zero_arity_spec.rb",
100
+ "spec/extending/new_matcher_w_single_arity_spec.rb",
101
+ "spec/extending/subclassing_w_multiple_arities_spec.rb",
102
+ "spec/extending/new_matcher_w_optional_arity_spec.rb",
103
+ "spec/extending/new_matcher_w_zero_arity_spec.rb",
104
+ "spec/extending/spec_helper.rb",
99
105
  "spec/bounded_vars/global_vars_within_block_scope_spec.rb",
100
106
  "spec/bounded_vars/instance_vars_within_block_scope_spec.rb",
101
107
  "spec/bounded_vars/errors_spec.rb",
@@ -104,15 +110,14 @@ Gem::Specification.new do |s|
104
110
  "spec/bounded_vars/local_vars_spec.rb",
105
111
  "spec/bounded_vars/global_vars_spec.rb",
106
112
  "spec/bounded_vars/instance_vars_spec.rb",
107
- "spec/bounded_vars/class_vars_within_block_scope_spec.rb",
108
- "spec/spec_helper.rb"
113
+ "spec/bounded_vars/class_vars_within_block_scope_spec.rb"
109
114
  ]
110
115
 
111
116
  if s.respond_to? :specification_version then
112
117
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
113
118
  s.specification_version = 3
114
119
 
115
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
120
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
116
121
  s.add_runtime_dependency(%q<ruby2ruby>, [">= 1.2.4"])
117
122
  s.add_development_dependency(%q<bacon>, [">= 0"])
118
123
  else
@@ -0,0 +1,17 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe 'Handling magic vars' do
4
+
5
+ extend SerializableProc::Spec::Helpers
6
+
7
+ should 'convert __FILE__' do
8
+ SerializableProc.new { __FILE__ }.should.be \
9
+ having_runnable_code_as('proc { "%s" }' % __FILE__)
10
+ end
11
+
12
+ should 'convert __LINE__' do
13
+ SerializableProc.new { __LINE__ }.should.be \
14
+ having_runnable_code_as('proc { %s }' % __LINE__.pred)
15
+ end
16
+
17
+ end
@@ -0,0 +1,152 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'New matcher w multiple arities' do
4
+
5
+ expected_file = File.expand_path(__FILE__)
6
+ expected_code = "lambda { |lvar_arg1, lvar_arg2| [\"a\", \"b\"].map { |lvar_x| puts(lvar_x) } }"
7
+
8
+ describe '>> wo args' do
9
+
10
+ extend SerializableProc::Spec::Helpers
11
+ behaves_like 'has support for parsing Otaky.work (wo args)'
12
+
13
+ should "handle block using do ... end [##{__LINE__}]" do
14
+ (
15
+ Otaky.work do |arg1, arg2|
16
+ %w{a b}.map{|x| puts x }
17
+ end
18
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
19
+ end
20
+
21
+ should "handle block using do ... end [##{__LINE__}]" do
22
+ (Otaky.work do |arg1, arg2| %w{a b}.map{|x| puts x } end).
23
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
24
+ end
25
+
26
+ should "handle block using { ... } [##{__LINE__}]" do
27
+ (
28
+ Otaky.work { |arg1, arg2|
29
+ %w{a b}.map{|x| puts x }
30
+ }
31
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
32
+ end
33
+
34
+ should "handle block using { ... } [##{__LINE__}]" do
35
+ (Otaky.work { |arg1, arg2| %w{a b}.map{|x| puts x } }).
36
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
37
+ end
38
+
39
+ should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
40
+ (Otaky.work(&(lambda { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
41
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
42
+ end
43
+
44
+ should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
45
+ (
46
+ Otaky.work(&(lambda do |arg1, arg2|
47
+ %w{a b}.map{|x| puts x }
48
+ end))
49
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
50
+ end
51
+
52
+ should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
53
+ (Otaky.work(&(proc { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
54
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
55
+ end
56
+
57
+ should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
58
+ (
59
+ Otaky.work(&(proc do |arg1, arg2|
60
+ %w{a b}.map{|x| puts x }
61
+ end))
62
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
63
+ end
64
+
65
+ should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
66
+ (Otaky.work(&(Proc.new { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
67
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
68
+ end
69
+
70
+ should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
71
+ (
72
+ Otaky.work(&(Proc.new do |arg1, arg2|
73
+ %w{a b}.map{|x| puts x }
74
+ end))
75
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
76
+ end
77
+
78
+ end
79
+
80
+ describe '>> w args' do
81
+
82
+ extend SerializableProc::Spec::Helpers
83
+ behaves_like 'has support for parsing Otaky.work (w args)'
84
+
85
+ should "handle block using do ... end [##{__LINE__}]" do
86
+ (
87
+ Otaky.work(1, :a => 2, :b => 3) do |arg1, arg2|
88
+ %w{a b}.map{|x| puts x }
89
+ end
90
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
91
+ end
92
+
93
+ should "handle block using do ... end [##{__LINE__}]" do
94
+ (Otaky.work(1, :a => 2, :b => 3) do |arg1, arg2| %w{a b}.map{|x| puts x } end).
95
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
96
+ end
97
+
98
+ should "handle block using { ... } [##{__LINE__}]" do
99
+ (
100
+ Otaky.work(1, :a => 2, :b => 3) { |arg1, arg2|
101
+ %w{a b}.map{|x| puts x }
102
+ }
103
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
104
+ end
105
+
106
+ should "handle block using { ... } [##{__LINE__}]" do
107
+ (Otaky.work(1, :a => 2, :b => 3) { |arg1, arg2| %w{a b}.map{|x| puts x } }).
108
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
109
+ end
110
+
111
+ should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
112
+ (Otaky.work(1, {:a => 2, :b => 3} , &(lambda { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
113
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
114
+ end
115
+
116
+ should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
117
+ (
118
+ Otaky.work(1, {:a => 2, :b => 3}, &(lambda do |arg1, arg2|
119
+ %w{a b}.map{|x| puts x }
120
+ end))
121
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
122
+ end
123
+
124
+ should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
125
+ (Otaky.work(1, {:a => 2, :b => 3}, &(proc { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
126
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
127
+ end
128
+
129
+ should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
130
+ (
131
+ Otaky.work(1, {:a => 2, :b => 3}, &(proc do |arg1, arg2|
132
+ %w{a b}.map{|x| puts x }
133
+ end))
134
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
135
+ end
136
+
137
+ should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
138
+ (Otaky.work(1, {:a => 2, :b => 3}, &(Proc.new { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
139
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
140
+ end
141
+
142
+ should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
143
+ (
144
+ Otaky.work(1, {:a => 2, :b => 3}, &(Proc.new do |arg1, arg2|
145
+ %w{a b}.map{|x| puts x }
146
+ end))
147
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
148
+ end
149
+
150
+ end
151
+
152
+ end