serializable_proc 0.1.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/.document +5 -0
- data/.gitignore +21 -0
- data/HISTORY.txt +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +132 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/lib/serializable_proc/binding.rb +53 -0
- data/lib/serializable_proc/marshalable.rb +51 -0
- data/lib/serializable_proc/parsers/pt.rb +16 -0
- data/lib/serializable_proc/parsers/rp.rb +93 -0
- data/lib/serializable_proc/parsers.rb +8 -0
- data/lib/serializable_proc/sandboxer.rb +24 -0
- data/lib/serializable_proc.rb +169 -0
- data/spec/extracting_bound_variables_spec.rb +99 -0
- data/spec/initializing_errors_spec.rb +95 -0
- data/spec/marshalling_spec.rb +51 -0
- data/spec/multiple_arities_serializable_proc_spec.rb +159 -0
- data/spec/one_arity_serializable_proc_spec.rb +159 -0
- data/spec/optional_arity_serializable_proc_spec.rb +160 -0
- data/spec/proc_like_spec.rb +191 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/zero_arity_serializable_proc_spec.rb +159 -0
- metadata +127 -0
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'ruby2ruby'
|
4
|
+
require 'serializable_proc/marshalable'
|
5
|
+
require 'serializable_proc/parsers'
|
6
|
+
require 'serializable_proc/binding'
|
7
|
+
require 'serializable_proc/sandboxer'
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'parse_tree'
|
11
|
+
require 'parse_tree_extensions'
|
12
|
+
rescue LoadError
|
13
|
+
require 'ruby_parser'
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# SerializableProc differs from the vanilla Proc in 2 ways:
|
18
|
+
#
|
19
|
+
# #1. Isolated variables
|
20
|
+
#
|
21
|
+
# Upon initializing, all variables (local, instance, class & global) within its context
|
22
|
+
# are extracted from the proc's binding, and are isolated from changes outside the
|
23
|
+
# proc's scope, thus, achieving a snapshot effect.
|
24
|
+
#
|
25
|
+
# require 'rubygems'
|
26
|
+
# require 'serializable_proc'
|
27
|
+
#
|
28
|
+
# x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
29
|
+
#
|
30
|
+
# s_proc = SerializableProc.new { [x, @x, @@x, $x].join(', ') }
|
31
|
+
# v_proc = Proc.new { [x, @x, @@x, $x].join(', ') }
|
32
|
+
#
|
33
|
+
# x, @x, @@x, $x = 'ly', 'iy', 'cy', 'gy'
|
34
|
+
#
|
35
|
+
# s_proc.call # >> "lx, ix, cx, gx"
|
36
|
+
# v_proc.call # >> "ly, iy, cy, gy"
|
37
|
+
#
|
38
|
+
# #2. Marshallable
|
39
|
+
#
|
40
|
+
# No throwing of TypeError when marshalling a SerializableProc:
|
41
|
+
#
|
42
|
+
# Marshal.load(Marshal.dump(s_proc)).call # >> "lx, ix, cx, gx"
|
43
|
+
# Marshal.load(Marshal.dump(v_proc)).call # >> TypeError (cannot dump Proc)
|
44
|
+
#
|
45
|
+
class SerializableProc
|
46
|
+
|
47
|
+
include Marshalable
|
48
|
+
marshal_attrs :file, :line, :code, :arity, :binding
|
49
|
+
|
50
|
+
##
|
51
|
+
# Creates a new instance of SerializableProc by passing in a code block, in the process,
|
52
|
+
# all referenced variables (local, instance, class & global) within the block are
|
53
|
+
# extracted and isolated from the current context.
|
54
|
+
#
|
55
|
+
# SerializableProc.new {|...| block }
|
56
|
+
# x = lambda { ... }; SerializableProc.new(&x)
|
57
|
+
# y = proc { ... }; SerializableProc.new(&y)
|
58
|
+
# z = Proc.new { ... }; SerializableProc.new(&z)
|
59
|
+
#
|
60
|
+
# The following will only work if u have ParseTree (not available for 1.9.* & JRuby)
|
61
|
+
# installed:
|
62
|
+
#
|
63
|
+
# def action(&block) ; SerializableProc.new(&block) ; end
|
64
|
+
# action { ... }
|
65
|
+
#
|
66
|
+
def initialize(&block)
|
67
|
+
file, line = /^#<Proc:0x[0-9A-Fa-f]+@(.+):(\d+).*?>$/.match(block.inspect)[1..2]
|
68
|
+
@file, @line, @arity = File.expand_path(file), line.to_i, block.arity
|
69
|
+
@code, sexp = Parsers::PT.process(block) || Parsers::RP.process(self.class, @file, @line)
|
70
|
+
@binding = Binding.new(block.binding, sexp)
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Returns true if +other+ is exactly the same instance, or if +other+ has the same string
|
75
|
+
# content.
|
76
|
+
#
|
77
|
+
# x = SerializableProc.new { puts 'awesome' }
|
78
|
+
# y = SerializableProc.new { puts 'wonderful' }
|
79
|
+
# z = SerializableProc.new { puts 'awesome' }
|
80
|
+
#
|
81
|
+
# x == x # >> true
|
82
|
+
# x == y # >> false
|
83
|
+
# x == z # >> true
|
84
|
+
#
|
85
|
+
def ==(other)
|
86
|
+
other.object_id == object_id or
|
87
|
+
other.is_a?(self.class) && other.to_s == to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Returns a plain vanilla proc that works just like other instances of Proc, the
|
92
|
+
# only difference is that the binding of variables is the same as the serializable
|
93
|
+
# proc, which is isolated.
|
94
|
+
#
|
95
|
+
# x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
|
96
|
+
# s_proc = SerializableProc.new { [x, @x, @@x, $x].join(', ') }
|
97
|
+
# x, @x, @@x, $x = 'ly', 'iy', 'cy', 'gy'
|
98
|
+
# s_proc.to_proc.call # >> 'lx, ix, cx, gx'
|
99
|
+
#
|
100
|
+
# Just like any object that responds to #to_proc, you can do the following as well:
|
101
|
+
#
|
102
|
+
# def action(&block) ; yield ; end
|
103
|
+
# action(&s_proc) # >> 'lx, ix, cx, gx'
|
104
|
+
#
|
105
|
+
def to_proc
|
106
|
+
@proc ||= eval(@code[:runnable], @binding.eval!, @file, @line)
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Returns a string representation of itself, which is in fact the code enclosed within
|
111
|
+
# the initializing block.
|
112
|
+
#
|
113
|
+
# SerializableProc.new { [x, @x, @@x, $x].join(', ') }.to_s
|
114
|
+
# # >> lambda { [x, @x, @@x, $x].join(', ') }
|
115
|
+
#
|
116
|
+
# By specifying +debug+ as true, the true runnable code is returned, the only difference
|
117
|
+
# from the above is that the variables within has been renamed (in order to provide for
|
118
|
+
# variables isolation):
|
119
|
+
#
|
120
|
+
# SerializableProc.new { [x, @x, @@x, $x].join(', ') }.to_s(true)
|
121
|
+
# # >> lambda { [lvar_x, ivar_x, cvar_x, gvar_x].join(', ') }
|
122
|
+
#
|
123
|
+
# The following renaming rules apply:
|
124
|
+
# * local variable -> prefixed with 'lvar_',
|
125
|
+
# * instance variable -> replaced '@' with 'ivar_'
|
126
|
+
# * class variable -> replaced '@@' with 'cvar_'
|
127
|
+
# * global variable -> replaced '$ with 'gvar_'
|
128
|
+
#
|
129
|
+
def to_s(debug = false)
|
130
|
+
@code[debug ? :runnable : :extracted]
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Returns the number of arguments accepted when running #call. This is extracted directly
|
135
|
+
# from the initializing code block, & is only as accurate as Proc#arity.
|
136
|
+
#
|
137
|
+
# Note that at the time of this writing, running on 1.8.* yields different result from
|
138
|
+
# that of 1.9.*:
|
139
|
+
#
|
140
|
+
# lambda { }.arity # 1.8.* (-1) / 1.9.* (0) (?!)
|
141
|
+
# lambda {|x| }.arity # 1.8.* (1) / 1.9.* (1)
|
142
|
+
# lambda {|x,y| }.arity # 1.8.* (2) / 1.9.* (2)
|
143
|
+
# lambda {|*x| }.arity # 1.8.* (-1) / 1.9.* (-1)
|
144
|
+
# lambda {|x, *y| }.arity # 1.8.* (-2) / 1.9.* (-2)
|
145
|
+
# lambda {|(x,y)| }.arity # 1.8.* (1) / 1.9.* (1)
|
146
|
+
#
|
147
|
+
def arity
|
148
|
+
@arity
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Just like the vanilla proc, invokes it, setting params as specified. Since the code
|
153
|
+
# representation of a SerializableProc is a lambda, expect lambda-like behaviour when
|
154
|
+
# wrong number of params are passed in.
|
155
|
+
#
|
156
|
+
# SerializableProc.new{|i| (['hello'] * i).join(' ') }.call(2)
|
157
|
+
# # >> 'hello hello'
|
158
|
+
#
|
159
|
+
def call(*params)
|
160
|
+
to_proc.call(*params)
|
161
|
+
end
|
162
|
+
|
163
|
+
alias_method :[], :call
|
164
|
+
|
165
|
+
def binding #:nodoc:
|
166
|
+
raise NotImplementedError
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Extracting bound variables' do
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def m1 ; 'm1' ; end
|
7
|
+
def m2(x) ; 'm2(%s)' % x ; end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '>> extracting local variables' do
|
11
|
+
|
12
|
+
extend SerializableProc::Spec::Helpers
|
13
|
+
|
14
|
+
should "handle outer-scoped ones" do
|
15
|
+
x, y = 'awe', 'some'
|
16
|
+
should_have_expected_binding \
|
17
|
+
SerializableProc.new{ x + y }, {:lvar_x => x, :lvar_y => y}
|
18
|
+
end
|
19
|
+
|
20
|
+
should "handle inner-scoped ones" do
|
21
|
+
x, y = 'awe', 'some'
|
22
|
+
should_have_expected_binding \
|
23
|
+
SerializableProc.new{|x| z = 'wonder' ; %w{a b}.each{|y| puts z, x, y } },
|
24
|
+
{:lvar_x => x, :lvar_y => y, :lvar_z => nil}
|
25
|
+
end
|
26
|
+
|
27
|
+
# NOTE: Errors checking are found under ./initializing_errors_spec.rb
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '>> extracting instance variables' do
|
32
|
+
|
33
|
+
extend SerializableProc::Spec::Helpers
|
34
|
+
|
35
|
+
should 'handle outer-scoped ones' do
|
36
|
+
@x, @y = 'awe', 'some'
|
37
|
+
should_have_expected_binding \
|
38
|
+
SerializableProc.new{ @x + @y }, {:ivar_x => @x, :ivar_y => @y}
|
39
|
+
end
|
40
|
+
|
41
|
+
should "handle inner-scoped ones" do
|
42
|
+
@x, @y = 'awe', 'some'
|
43
|
+
should_have_expected_binding \
|
44
|
+
SerializableProc.new{ @z = 'wonder' ; %w{a b}.each{ puts @z, @x, @y } },
|
45
|
+
{:ivar_x => @x, :ivar_y => @y, :ivar_z => nil}
|
46
|
+
end
|
47
|
+
|
48
|
+
# NOTE: Errors checking are found under ./initializing_errors_spec.rb
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '>> extracting class variables' do
|
53
|
+
|
54
|
+
extend SerializableProc::Spec::Helpers
|
55
|
+
|
56
|
+
should 'handle outer-scoped ones' do
|
57
|
+
@@x, @@y = 'awe', 'some'
|
58
|
+
should_have_expected_binding \
|
59
|
+
SerializableProc.new{ @@x + @@y }, {:cvar_x => @@x, :cvar_y => @@y}
|
60
|
+
end
|
61
|
+
|
62
|
+
should "handle inner-scoped ones" do
|
63
|
+
@@x, @@y = 'awe', 'some'
|
64
|
+
should_have_expected_binding \
|
65
|
+
SerializableProc.new{ @@z = 'wonder' ; %w{a b}.each{ puts @@z, @@x, @@y } },
|
66
|
+
{:cvar_x => @@x, :cvar_y => @@y, :cvar_z => nil}
|
67
|
+
end
|
68
|
+
|
69
|
+
# NOTE: Errors checking are found under ./initializing_errors_spec.rb
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '>> extracting global variables' do
|
74
|
+
|
75
|
+
extend SerializableProc::Spec::Helpers
|
76
|
+
|
77
|
+
should 'handle outer-scoped ones' do
|
78
|
+
$x, $y = 'awe', 'some'
|
79
|
+
should_have_expected_binding SerializableProc.new{ $x + $y }, {:gvar_x => $x, :gvar_y => $y}
|
80
|
+
end
|
81
|
+
|
82
|
+
should "handle inner-scoped ones" do
|
83
|
+
$x, $y = 'awe', 'some'
|
84
|
+
should_have_expected_binding \
|
85
|
+
SerializableProc.new{ $z = 'wonder' ; %w{a b}.each{ puts $z, $x, $y } },
|
86
|
+
{:gvar_x => $x, :gvar_y => $y, :gvar_z => nil}
|
87
|
+
end
|
88
|
+
|
89
|
+
# NOTE: Errors checking are found under ./initializing_errors_spec.rb
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '>> extracting method returns' do
|
94
|
+
should "not handle" do
|
95
|
+
SerializableProc.new { m1 + m2(3) }.binding_dump.should.be.empty
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Initializing errors' do
|
4
|
+
|
5
|
+
unless $parse_tree_installed
|
6
|
+
describe '>> SerializableProc::CannotAnalyseCodeError' do
|
7
|
+
|
8
|
+
extend SerializableProc::Spec::Helpers
|
9
|
+
|
10
|
+
should "raise if line has more than 1 'SerializableProc.new'" do
|
11
|
+
lambda {
|
12
|
+
SerializableProc.new {} ; SerializableProc.new { |arg| %w{a b}.map{|x| puts x } }
|
13
|
+
}.should.be raising_cannot_analyse_error("'SerializableProc.new'")
|
14
|
+
end
|
15
|
+
|
16
|
+
should "raise if line has more than 1 'Proc.new'" do
|
17
|
+
lambda {
|
18
|
+
p1 = Proc.new {} ; p2 = Proc.new { |arg| %w{a b}.map{|x| puts x } }
|
19
|
+
SerializableProc.new(&p2)
|
20
|
+
}.should.be raising_cannot_analyse_error("'lambda'/'proc'/'Proc.new'")
|
21
|
+
end
|
22
|
+
|
23
|
+
should "raise if line has more than 1 'lambda'" do
|
24
|
+
lambda {
|
25
|
+
p1 = lambda {} ; p2 = lambda { |arg| %w{a b}.map{|x| puts x } }
|
26
|
+
SerializableProc.new(&p2)
|
27
|
+
}.should.be raising_cannot_analyse_error("'lambda'/'proc'/'Proc.new'")
|
28
|
+
end
|
29
|
+
|
30
|
+
should "raise if line has more than 1 'proc'" do
|
31
|
+
lambda {
|
32
|
+
p1 = proc {} ; p2 = proc { |arg| %w{a b}.map{|x| puts x } }
|
33
|
+
SerializableProc.new(&p2)
|
34
|
+
}.should.be raising_cannot_analyse_error("'lambda'/'proc'/'Proc.new'")
|
35
|
+
end
|
36
|
+
|
37
|
+
should "raise if line mixes 'lambda' & 'proc'" do
|
38
|
+
lambda {
|
39
|
+
p1 = lambda {} ; p2 = proc { |arg| %w{a b}.map{|x| puts x } }
|
40
|
+
SerializableProc.new(&p2)
|
41
|
+
}.should.be raising_cannot_analyse_error("'lambda'/'proc'/'Proc.new'")
|
42
|
+
end
|
43
|
+
|
44
|
+
should "raise if line mixes 'Proc.new' & 'proc'" do
|
45
|
+
lambda {
|
46
|
+
p1 = Proc.new {} ; p2 = proc { |arg| %w{a b}.map{|x| puts x } }
|
47
|
+
SerializableProc.new(&p2)
|
48
|
+
}.should.be raising_cannot_analyse_error("'lambda'/'proc'/'Proc.new'")
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise if line mixes 'Proc.new' & 'lambda'" do
|
52
|
+
lambda {
|
53
|
+
p1 = Proc.new {} ; p2 = lambda { |arg| %w{a b}.map{|x| puts x } }
|
54
|
+
SerializableProc.new(&p2)
|
55
|
+
}.should.be raising_cannot_analyse_error("'lambda'/'proc'/'Proc.new'")
|
56
|
+
end
|
57
|
+
|
58
|
+
should "raise if line does not have lambda, proc, Proc.new or SerializableProc.new" do
|
59
|
+
lambda {
|
60
|
+
def create_serializable_proc(&block) ; SerializableProc.new(&block) ; end
|
61
|
+
create_serializable_proc { %w{a b}.map{|x| puts x } }
|
62
|
+
}.should.raise(SerializableProc::CannotAnalyseCodeError).
|
63
|
+
message.should.equal('Cannot find specified initializer !!')
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '>> SerializableProc::CannotSerializeVariableError' do
|
70
|
+
|
71
|
+
extend SerializableProc::Spec::Helpers
|
72
|
+
|
73
|
+
should "raise if local variable cannot be marshalled" do
|
74
|
+
f = Tempfile.new('fake')
|
75
|
+
lambda { SerializableProc.new{ f } }.should.be raising_cannot_serialize_variable_error('f')
|
76
|
+
end
|
77
|
+
|
78
|
+
should "raise if class variable cannot be marshalled" do
|
79
|
+
@@f = Tempfile.new('fake')
|
80
|
+
lambda { SerializableProc.new{ @@f } }.should.be raising_cannot_serialize_variable_error('@@f')
|
81
|
+
end
|
82
|
+
|
83
|
+
should "raise if instance variable cannot be marshalled" do
|
84
|
+
@f = Tempfile.new('fake')
|
85
|
+
lambda { SerializableProc.new{ @f } }.should.be raising_cannot_serialize_variable_error('@f')
|
86
|
+
end
|
87
|
+
|
88
|
+
should "raise if global variable cannot be marshalled" do
|
89
|
+
$f = Tempfile.new('fake')
|
90
|
+
lambda { SerializableProc.new{ $f } }.should.be raising_cannot_serialize_variable_error('$f')
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Marshalling' do
|
4
|
+
|
5
|
+
describe '>> basic (wo contextual references)' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@proc = SerializableProc.new{ %w{a b}.map{|x| x } }
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'be able to marshal' do
|
12
|
+
Marshal.load(Marshal.dump(@proc))
|
13
|
+
true.should.be.true # the above should execute wo error
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'be able to resume proc behaviours' do
|
17
|
+
Marshal.load(Marshal.dump(@proc)).call.should.equal(%w{a b})
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '>> with contextual references' do
|
23
|
+
|
24
|
+
should 'handle local variables' do
|
25
|
+
x, y, expected = 'awe', 'some', 'awesome'
|
26
|
+
s_proc = SerializableProc.new{ x + y }
|
27
|
+
Marshal.load(Marshal.dump(s_proc)).call.should.equal(expected)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'handle instance variables' do
|
31
|
+
@x, @y, expected = 'awe', 'some', 'awesome'
|
32
|
+
s_proc = SerializableProc.new{ @x + @y }
|
33
|
+
Marshal.load(Marshal.dump(s_proc)).call.should.equal(expected)
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'handle class variables' do
|
37
|
+
@@x, @@y, expected = 'awe', 'some', 'awesome'
|
38
|
+
s_proc = SerializableProc.new{ @@x + @@y }
|
39
|
+
Marshal.load(Marshal.dump(s_proc)).call.should.equal(expected)
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'handle global variables' do
|
43
|
+
$x, $y, expected = 'awe', 'some', 'awesome'
|
44
|
+
s_proc = SerializableProc.new{ $x + $y }
|
45
|
+
Marshal.load(Marshal.dump(s_proc)).call.should.equal(expected)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe 'Multiple arities serializable proc' do
|
4
|
+
|
5
|
+
extend SerializableProc::Spec::Helpers
|
6
|
+
|
7
|
+
expected_file = File.expand_path(__FILE__)
|
8
|
+
expected_code = "lambda { |lvar_arg1, lvar_arg2| [\"a\", \"b\"].map { |lvar_x| puts(lvar_x) } }"
|
9
|
+
|
10
|
+
should_handle_proc_variable expected_file, expected_code, {
|
11
|
+
# ////////////////////////////////////////////////////////////////////////
|
12
|
+
# >> Always newlinling
|
13
|
+
# ////////////////////////////////////////////////////////////////////////
|
14
|
+
__LINE__ =>
|
15
|
+
lambda do |arg1, arg2|
|
16
|
+
%w{a b}.map do |x|
|
17
|
+
puts x
|
18
|
+
end
|
19
|
+
end,
|
20
|
+
__LINE__ =>
|
21
|
+
lambda { |arg1, arg2|
|
22
|
+
%w{a b}.map{|x|
|
23
|
+
puts x
|
24
|
+
}
|
25
|
+
},
|
26
|
+
__LINE__ =>
|
27
|
+
proc do |arg1, arg2|
|
28
|
+
%w{a b}.map do |x|
|
29
|
+
puts x
|
30
|
+
end
|
31
|
+
end,
|
32
|
+
__LINE__ =>
|
33
|
+
lambda { |arg1, arg2|
|
34
|
+
%w{a b}.map{|x|
|
35
|
+
puts x
|
36
|
+
}
|
37
|
+
},
|
38
|
+
__LINE__ =>
|
39
|
+
Proc.new do |arg1, arg2|
|
40
|
+
%w{a b}.map do |x|
|
41
|
+
puts x
|
42
|
+
end
|
43
|
+
end,
|
44
|
+
__LINE__ =>
|
45
|
+
Proc.new { |arg1, arg2|
|
46
|
+
%w{a b}.map{|x|
|
47
|
+
puts x
|
48
|
+
}
|
49
|
+
},
|
50
|
+
# ////////////////////////////////////////////////////////////////////////
|
51
|
+
# >> Partial newlining
|
52
|
+
# ////////////////////////////////////////////////////////////////////////
|
53
|
+
__LINE__ =>
|
54
|
+
lambda do |arg1, arg2|
|
55
|
+
%w{a b}.map do |x| puts x end
|
56
|
+
end,
|
57
|
+
__LINE__ =>
|
58
|
+
lambda { |arg1, arg2|
|
59
|
+
%w{a b}.map{|x| puts x }
|
60
|
+
},
|
61
|
+
__LINE__ =>
|
62
|
+
proc do |arg1, arg2|
|
63
|
+
%w{a b}.map do |x| puts x end
|
64
|
+
end,
|
65
|
+
__LINE__ =>
|
66
|
+
lambda { |arg1, arg2|
|
67
|
+
%w{a b}.map{|x| puts x }
|
68
|
+
},
|
69
|
+
__LINE__ =>
|
70
|
+
Proc.new do |arg1, arg2|
|
71
|
+
%w{a b}.map do |x| puts x end
|
72
|
+
end,
|
73
|
+
__LINE__ =>
|
74
|
+
Proc.new { |arg1, arg2|
|
75
|
+
%w{a b}.map{|x| puts x }
|
76
|
+
},
|
77
|
+
# ////////////////////////////////////////////////////////////////////////
|
78
|
+
# >> No newlining
|
79
|
+
# ////////////////////////////////////////////////////////////////////////
|
80
|
+
__LINE__ =>
|
81
|
+
lambda do |arg1, arg2| %w{a b}.map do |x| puts x end end,
|
82
|
+
__LINE__ =>
|
83
|
+
lambda { |arg1, arg2| %w{a b}.map{|x| puts x } },
|
84
|
+
__LINE__ =>
|
85
|
+
proc do |arg1, arg2| %w{a b}.map do |x| puts x end end,
|
86
|
+
__LINE__ =>
|
87
|
+
lambda { |arg1, arg2| %w{a b}.map{|x| puts x } },
|
88
|
+
__LINE__ =>
|
89
|
+
Proc.new do |arg1, arg2| %w{a b}.map do |x| puts x end end,
|
90
|
+
__LINE__ =>
|
91
|
+
Proc.new { |arg1, arg2| %w{a b}.map{|x| puts x } },
|
92
|
+
}
|
93
|
+
|
94
|
+
should "handle block using do ... end [##{__LINE__}]" do
|
95
|
+
(
|
96
|
+
SerializableProc.new do |arg1, arg2|
|
97
|
+
%w{a b}.map{|x| puts x }
|
98
|
+
end
|
99
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
100
|
+
end
|
101
|
+
|
102
|
+
should "handle block using do ... end [##{__LINE__}]" do
|
103
|
+
(SerializableProc.new do |arg1, arg2| %w{a b}.map{|x| puts x } end).
|
104
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
105
|
+
end
|
106
|
+
|
107
|
+
should "handle block using { ... } [##{__LINE__}]" do
|
108
|
+
(
|
109
|
+
SerializableProc.new { |arg1, arg2|
|
110
|
+
%w{a b}.map{|x| puts x }
|
111
|
+
}
|
112
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
113
|
+
end
|
114
|
+
|
115
|
+
should "handle block using { ... } [##{__LINE__}]" do
|
116
|
+
(SerializableProc.new { |arg1, arg2| %w{a b}.map{|x| puts x } }).
|
117
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
118
|
+
end
|
119
|
+
|
120
|
+
should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
|
121
|
+
(SerializableProc.new(&(lambda { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
|
122
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
|
126
|
+
(
|
127
|
+
SerializableProc.new(&(lambda do |arg1, arg2|
|
128
|
+
%w{a b}.map{|x| puts x }
|
129
|
+
end))
|
130
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
131
|
+
end
|
132
|
+
|
133
|
+
should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
|
134
|
+
(SerializableProc.new(&(proc { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
|
135
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
|
139
|
+
(
|
140
|
+
SerializableProc.new(&(proc do |arg1, arg2|
|
141
|
+
%w{a b}.map{|x| puts x }
|
142
|
+
end))
|
143
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
144
|
+
end
|
145
|
+
|
146
|
+
should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
|
147
|
+
(SerializableProc.new(&(Proc.new { |arg1, arg2| %w{a b}.map{|x| puts x } }))).
|
148
|
+
should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
|
149
|
+
end
|
150
|
+
|
151
|
+
should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
|
152
|
+
(
|
153
|
+
SerializableProc.new(&(Proc.new do |arg1, arg2|
|
154
|
+
%w{a b}.map{|x| puts x }
|
155
|
+
end))
|
156
|
+
).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|