liquid 1.9.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/Manifest.txt +0 -31
  2. data/Rakefile +1 -1
  3. data/lib/extras/liquid_view.rb +15 -2
  4. data/lib/liquid.rb +15 -15
  5. data/lib/liquid/block.rb +1 -2
  6. data/lib/liquid/context.rb +89 -99
  7. data/lib/liquid/drop.rb +6 -4
  8. data/lib/liquid/errors.rb +1 -0
  9. data/lib/liquid/standardfilters.rb +56 -11
  10. data/lib/liquid/strainer.rb +1 -1
  11. data/lib/liquid/tags/assign.rb +1 -1
  12. data/lib/liquid/tags/case.rb +2 -2
  13. data/lib/liquid/tags/cycle.rb +3 -4
  14. data/lib/liquid/tags/for.rb +53 -35
  15. data/lib/liquid/tags/if.rb +3 -3
  16. data/lib/liquid/template.rb +8 -7
  17. data/lib/liquid/variable.rb +10 -11
  18. metadata +5 -35
  19. data/example/server/example_servlet.rb +0 -37
  20. data/example/server/liquid_servlet.rb +0 -28
  21. data/example/server/server.rb +0 -12
  22. data/example/server/templates/index.liquid +0 -6
  23. data/example/server/templates/products.liquid +0 -45
  24. data/test/block_test.rb +0 -58
  25. data/test/condition_test.rb +0 -109
  26. data/test/context_test.rb +0 -418
  27. data/test/drop_test.rb +0 -141
  28. data/test/error_handling_test.rb +0 -78
  29. data/test/extra/breakpoint.rb +0 -547
  30. data/test/extra/caller.rb +0 -80
  31. data/test/file_system_test.rb +0 -30
  32. data/test/filter_test.rb +0 -98
  33. data/test/helper.rb +0 -20
  34. data/test/html_tag_test.rb +0 -31
  35. data/test/if_else_test.rb +0 -127
  36. data/test/include_tag_test.rb +0 -114
  37. data/test/module_ex_test.rb +0 -89
  38. data/test/output_test.rb +0 -121
  39. data/test/parsing_quirks_test.rb +0 -29
  40. data/test/regexp_test.rb +0 -40
  41. data/test/security_test.rb +0 -41
  42. data/test/standard_filter_test.rb +0 -126
  43. data/test/standard_tag_test.rb +0 -383
  44. data/test/statements_test.rb +0 -137
  45. data/test/strainer_test.rb +0 -16
  46. data/test/template_test.rb +0 -26
  47. data/test/unless_else_test.rb +0 -27
  48. data/test/variable_test.rb +0 -135
@@ -1,141 +0,0 @@
1
-
2
- #!/usr/bin/env ruby
3
- require File.dirname(__FILE__) + '/helper'
4
-
5
- class ContextDrop < Liquid::Drop
6
- def scopes
7
- @context.scopes.size
8
- end
9
-
10
- def scopes_as_array
11
- (1..@context.scopes.size).to_a
12
- end
13
-
14
- def loop_pos
15
- @context['forloop.index']
16
- end
17
-
18
- def break
19
- Breakpoint.breakpoint
20
- end
21
-
22
- def before_method(method)
23
- return @context[method]
24
- end
25
- end
26
-
27
-
28
- class ProductDrop < Liquid::Drop
29
-
30
- class TextDrop < Liquid::Drop
31
- def array
32
- ['text1', 'text2']
33
- end
34
-
35
- def text
36
- 'text1'
37
- end
38
- end
39
-
40
- class CatchallDrop < Liquid::Drop
41
- def before_method(method)
42
- return 'method: ' << method
43
- end
44
- end
45
-
46
- def texts
47
- TextDrop.new
48
- end
49
-
50
- def catchall
51
- CatchallDrop.new
52
- end
53
-
54
- def context
55
- ContextDrop.new
56
- end
57
-
58
- protected
59
- def callmenot
60
- "protected"
61
- end
62
- end
63
-
64
-
65
- class DropsTest < Test::Unit::TestCase
66
- include Liquid
67
-
68
- def test_product_drop
69
-
70
- assert_nothing_raised do
71
- tpl = Liquid::Template.parse( ' ' )
72
- tpl.render('product' => ProductDrop.new)
73
- end
74
- end
75
-
76
- def test_text_drop
77
- output = Liquid::Template.parse( ' {{ product.texts.text }} ' ).render('product' => ProductDrop.new)
78
- assert_equal ' text1 ', output
79
-
80
- end
81
-
82
- def test_text_drop
83
- output = Liquid::Template.parse( ' {{ product.catchall.unknown }} ' ).render('product' => ProductDrop.new)
84
- assert_equal ' method: unknown ', output
85
-
86
- end
87
-
88
- def test_text_array_drop
89
- output = Liquid::Template.parse( '{% for text in product.texts.array %} {{text}} {% endfor %}' ).render('product' => ProductDrop.new)
90
- assert_equal ' text1 text2 ', output
91
- end
92
-
93
- def test_context_drop
94
- output = Liquid::Template.parse( ' {{ context.bar }} ' ).render('context' => ContextDrop.new, 'bar' => "carrot")
95
- assert_equal ' carrot ', output
96
- end
97
-
98
- def test_nested_context_drop
99
- output = Liquid::Template.parse( ' {{ product.context.foo }} ' ).render('product' => ProductDrop.new, 'foo' => "monkey")
100
- assert_equal ' monkey ', output
101
- end
102
-
103
- def test_protected
104
- output = Liquid::Template.parse( ' {{ product.callmenot }} ' ).render('product' => ProductDrop.new)
105
- assert_equal ' ', output
106
- end
107
-
108
- def test_scope
109
- assert_equal '1', Liquid::Template.parse( '{{ context.scopes }}' ).render('context' => ContextDrop.new)
110
- assert_equal '2', Liquid::Template.parse( '{%for i in dummy%}{{ context.scopes }}{%endfor%}' ).render('context' => ContextDrop.new, 'dummy' => [1])
111
- assert_equal '3', Liquid::Template.parse( '{%for i in dummy%}{%for i in dummy%}{{ context.scopes }}{%endfor%}{%endfor%}' ).render('context' => ContextDrop.new, 'dummy' => [1])
112
- end
113
-
114
- def test_scope_though_proc
115
- assert_equal '1', Liquid::Template.parse( '{{ s }}' ).render('context' => ContextDrop.new, 's' => Proc.new{|c| c['context.scopes'] })
116
- assert_equal '2', Liquid::Template.parse( '{%for i in dummy%}{{ s }}{%endfor%}' ).render('context' => ContextDrop.new, 's' => Proc.new{|c| c['context.scopes'] }, 'dummy' => [1])
117
- assert_equal '3', Liquid::Template.parse( '{%for i in dummy%}{%for i in dummy%}{{ s }}{%endfor%}{%endfor%}' ).render('context' => ContextDrop.new, 's' => Proc.new{|c| c['context.scopes'] }, 'dummy' => [1])
118
- end
119
-
120
- def test_scope_with_assigns
121
- assert_equal 'variable', Liquid::Template.parse( '{% assign a = "variable"%}{{a}}' ).render('context' => ContextDrop.new)
122
- assert_equal 'variable', Liquid::Template.parse( '{% assign a = "variable"%}{%for i in dummy%}{{a}}{%endfor%}' ).render('context' => ContextDrop.new, 'dummy' => [1])
123
- assert_equal 'test', Liquid::Template.parse( '{% assign header_gif = "test"%}{{header_gif}}' ).render('context' => ContextDrop.new)
124
- assert_equal 'test', Liquid::Template.parse( "{% assign header_gif = 'test'%}{{header_gif}}" ).render('context' => ContextDrop.new)
125
- end
126
-
127
- def test_scope_from_tags
128
- assert_equal '1', Liquid::Template.parse( '{% for i in context.scopes_as_array %}{{i}}{% endfor %}' ).render('context' => ContextDrop.new, 'dummy' => [1])
129
- assert_equal '12', Liquid::Template.parse( '{%for a in dummy%}{% for i in context.scopes_as_array %}{{i}}{% endfor %}{% endfor %}' ).render('context' => ContextDrop.new, 'dummy' => [1])
130
- assert_equal '123', Liquid::Template.parse( '{%for a in dummy%}{%for a in dummy%}{% for i in context.scopes_as_array %}{{i}}{% endfor %}{% endfor %}{% endfor %}' ).render('context' => ContextDrop.new, 'dummy' => [1])
131
- end
132
-
133
- def test_access_context_from_drop
134
- assert_equal '123', Liquid::Template.parse( '{%for a in dummy%}{{ context.loop_pos }}{% endfor %}' ).render('context' => ContextDrop.new, 'dummy' => [1,2,3])
135
- end
136
-
137
-
138
-
139
- end
140
-
141
-
@@ -1,78 +0,0 @@
1
-
2
- #!/usr/bin/env ruby
3
- require File.dirname(__FILE__) + '/helper'
4
-
5
- class ErrorDrop < Liquid::Drop
6
- def standard_error
7
- raise Liquid::StandardError, 'standard error'
8
- end
9
-
10
- def argument_error
11
- raise Liquid::ArgumentError, 'argument error'
12
- end
13
-
14
- def syntax_error
15
- raise Liquid::SyntaxError, 'syntax error'
16
- end
17
-
18
- end
19
-
20
-
21
- class ErrorHandlingTest < Test::Unit::TestCase
22
- include Liquid
23
-
24
- def test_standard_error
25
- assert_nothing_raised do
26
- template = Liquid::Template.parse( ' {{ errors.standard_error }} ' )
27
- assert_equal ' Liquid error: standard error ', template.render('errors' => ErrorDrop.new)
28
-
29
- assert_equal 1, template.errors.size
30
- assert_equal StandardError, template.errors.first.class
31
- end
32
- end
33
-
34
- def test_syntax
35
-
36
- assert_nothing_raised do
37
-
38
- template = Liquid::Template.parse( ' {{ errors.syntax_error }} ' )
39
- assert_equal ' Liquid syntax error: syntax error ', template.render('errors' => ErrorDrop.new)
40
-
41
- assert_equal 1, template.errors.size
42
- assert_equal SyntaxError, template.errors.first.class
43
-
44
- end
45
-
46
- end
47
-
48
- def test_argument
49
-
50
- assert_nothing_raised do
51
-
52
- template = Liquid::Template.parse( ' {{ errors.argument_error }} ' )
53
- assert_equal ' Liquid error: argument error ', template.render('errors' => ErrorDrop.new)
54
-
55
- assert_equal 1, template.errors.size
56
- assert_equal ArgumentError, template.errors.first.class
57
-
58
- end
59
-
60
- end
61
-
62
- def test_unrecognized_operator
63
-
64
- assert_nothing_raised do
65
-
66
- template = Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ')
67
- assert_equal ' Liquid error: Unknown operator =! ', template.render
68
-
69
- assert_equal 1, template.errors.size
70
- assert_equal Liquid::ArgumentError, template.errors.first.class
71
-
72
- end
73
-
74
- end
75
-
76
- end
77
-
78
-
@@ -1,547 +0,0 @@
1
- # The Breakpoint library provides the convenience of
2
- # being able to inspect and modify state, diagnose
3
- # bugs all via IRB by simply setting breakpoints in
4
- # your applications by the call of a method.
5
- #
6
- # This library was written and is supported by me,
7
- # Florian Gross. I can be reached at flgr@ccan.de
8
- # and enjoy getting feedback about my libraries.
9
- #
10
- # The whole library (including breakpoint_client.rb
11
- # and binding_of_caller.rb) is licensed under the
12
- # same license that Ruby uses. (Which is currently
13
- # either the GNU General Public License or a custom
14
- # one that allows for commercial usage.) If you for
15
- # some good reason need to use this under another
16
- # license please contact me.
17
-
18
- require 'irb'
19
- require 'caller'
20
- require 'drb'
21
- require 'drb/acl'
22
- require 'thread'
23
-
24
- module Breakpoint
25
- id = %q$Id: breakpoint.rb 52 2005-02-26 19:43:19Z flgr $
26
- current_version = id.split(" ")[2]
27
- unless defined?(Version)
28
- # The Version of ruby-breakpoint you are using as String of the
29
- # 1.2.3 form where the digits stand for release, major and minor
30
- # version respectively.
31
- Version = "0.5.0"
32
- end
33
-
34
- extend self
35
-
36
- # This will pop up an interactive ruby session at a
37
- # pre-defined break point in a Ruby application. In
38
- # this session you can examine the environment of
39
- # the break point.
40
- #
41
- # You can get a list of variables in the context using
42
- # local_variables via +local_variables+. You can then
43
- # examine their values by typing their names.
44
- #
45
- # You can have a look at the call stack via +caller+.
46
- #
47
- # The source code around the location where the breakpoint
48
- # was executed can be examined via +source_lines+. Its
49
- # argument specifies how much lines of context to display.
50
- # The default amount of context is 5 lines. Note that
51
- # the call to +source_lines+ can raise an exception when
52
- # it isn't able to read in the source code.
53
- #
54
- # breakpoints can also return a value. They will execute
55
- # a supplied block for getting a default return value.
56
- # A custom value can be returned from the session by doing
57
- # +throw(:debug_return, value)+.
58
- #
59
- # You can also give names to break points which will be
60
- # used in the message that is displayed upon execution
61
- # of them.
62
- #
63
- # Here's a sample of how breakpoints should be placed:
64
- #
65
- # class Person
66
- # def initialize(name, age)
67
- # @name, @age = name, age
68
- # breakpoint("Person#initialize")
69
- # end
70
- #
71
- # attr_reader :age
72
- # def name
73
- # breakpoint("Person#name") { @name }
74
- # end
75
- # end
76
- #
77
- # person = Person.new("Random Person", 23)
78
- # puts "Name: #{person.name}"
79
- #
80
- # And here is a sample debug session:
81
- #
82
- # Executing break point "Person#initialize" at file.rb:4 in `initialize'
83
- # irb(#<Person:0x292fbe8>):001:0> local_variables
84
- # => ["name", "age", "_", "__"]
85
- # irb(#<Person:0x292fbe8>):002:0> [name, age]
86
- # => ["Random Person", 23]
87
- # irb(#<Person:0x292fbe8>):003:0> [@name, @age]
88
- # => ["Random Person", 23]
89
- # irb(#<Person:0x292fbe8>):004:0> self
90
- # => #<Person:0x292fbe8 @age=23, @name="Random Person">
91
- # irb(#<Person:0x292fbe8>):005:0> @age += 1; self
92
- # => #<Person:0x292fbe8 @age=24, @name="Random Person">
93
- # irb(#<Person:0x292fbe8>):006:0> exit
94
- # Executing break point "Person#name" at file.rb:9 in `name'
95
- # irb(#<Person:0x292fbe8>):001:0> throw(:debug_return, "Overriden name")
96
- # Name: Overriden name
97
- #
98
- # Breakpoint sessions will automatically have a few
99
- # convenience methods available. See Breakpoint::CommandBundle
100
- # for a list of them.
101
- #
102
- # Breakpoints can also be used remotely over sockets.
103
- # This is implemented by running part of the IRB session
104
- # in the application and part of it in a special client.
105
- # You have to call Breakpoint.activate_drb to enable
106
- # support for remote breakpoints and then run
107
- # breakpoint_client.rb which is distributed with this
108
- # library. See the documentation of Breakpoint.activate_drb
109
- # for details.
110
- def breakpoint(id = nil, context = nil, &block)
111
- callstack = caller
112
- callstack.slice!(0, 3) if callstack.first["breakpoint"]
113
- file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
114
-
115
- message = "Executing break point " + (id ? "#{id.inspect} " : "") +
116
- "at #{file}:#{line}" + (method ? " in `#{method}'" : "")
117
-
118
- if context then
119
- return handle_breakpoint(context, message, file, line, &block)
120
- end
121
-
122
- Binding.of_caller do |binding_context|
123
- handle_breakpoint(binding_context, message, file, line, &block)
124
- end
125
- end
126
-
127
- # These commands are automatically available in all breakpoint shells.
128
- module CommandBundle
129
- # Proxy to a Breakpoint client. Lets you directly execute code
130
- # in the context of the client.
131
- class Client
132
- def initialize(eval_handler) # :nodoc:
133
- eval_handler.untaint
134
- @eval_handler = eval_handler
135
- end
136
-
137
- instance_methods.each do |method|
138
- next if method[/^__.+__$/]
139
- undef_method method
140
- end
141
-
142
- # Executes the specified code at the client.
143
- def eval(code)
144
- @eval_handler.call(code)
145
- end
146
-
147
- # Will execute the specified statement at the client.
148
- def method_missing(method, *args, &block)
149
- if args.empty? and not block
150
- result = eval "#{method}"
151
- else
152
- # This is a bit ugly. The alternative would be using an
153
- # eval context instead of an eval handler for executing
154
- # the code at the client. The problem with that approach
155
- # is that we would have to handle special expressions
156
- # like "self", "nil" or constants ourself which is hard.
157
- remote = eval %{
158
- result = lambda { |block, *args| #{method}(*args, &block) }
159
- def result.call_with_block(*args, &block)
160
- call(block, *args)
161
- end
162
- result
163
- }
164
- remote.call_with_block(*args, &block)
165
- end
166
-
167
- return result
168
- end
169
- end
170
-
171
- # Returns the source code surrounding the location where the
172
- # breakpoint was issued.
173
- def source_lines(context = 5, return_line_numbers = false)
174
- lines = File.readlines(@__bp_file).map { |line| line.chomp }
175
-
176
- break_line = @__bp_line
177
- start_line = [break_line - context, 1].max
178
- end_line = break_line + context
179
-
180
- result = lines[(start_line - 1) .. (end_line - 1)]
181
-
182
- if return_line_numbers then
183
- return [start_line, break_line, result]
184
- else
185
- return result
186
- end
187
- end
188
-
189
- # Lets an object that will forward method calls to the breakpoint
190
- # client. This is useful for outputting longer things at the client
191
- # and so on. You can for example do these things:
192
- #
193
- # client.puts "Hello" # outputs "Hello" at client console
194
- # # outputs "Hello" into the file temp.txt at the client
195
- # client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
196
- def client()
197
- if Breakpoint.use_drb? then
198
- sleep(0.5) until Breakpoint.drb_service.eval_handler
199
- Client.new(Breakpoint.drb_service.eval_handler)
200
- else
201
- Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
202
- end
203
- end
204
- end
205
-
206
- def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc:
207
- catch(:debug_return) do |value|
208
- eval(%{
209
- @__bp_file = #{file.inspect}
210
- @__bp_line = #{line}
211
- extend Breakpoint::CommandBundle
212
- extend DRbUndumped if self
213
- }, context) rescue nil
214
-
215
- if not use_drb? then
216
- puts message
217
- IRB.start(nil, IRB::WorkSpace.new(context))
218
- else
219
- @drb_service.add_breakpoint(context, message)
220
- end
221
-
222
- block.call if block
223
- end
224
- end
225
-
226
- # These exceptions will be raised on failed asserts
227
- # if Breakpoint.asserts_cause_exceptions is set to
228
- # true.
229
- class FailedAssertError < RuntimeError
230
- end
231
-
232
- # This asserts that the block evaluates to true.
233
- # If it doesn't evaluate to true a breakpoint will
234
- # automatically be created at that execution point.
235
- #
236
- # You can disable assert checking in production
237
- # code by setting Breakpoint.optimize_asserts to
238
- # true. (It will still be enabled when Ruby is run
239
- # via the -d argument.)
240
- #
241
- # Example:
242
- # person_name = "Foobar"
243
- # assert { not person_name.nil? }
244
- #
245
- # Note: If you want to use this method from an
246
- # unit test, you will have to call it by its full
247
- # name, Breakpoint.assert.
248
- def assert(context = nil, &condition)
249
- return if Breakpoint.optimize_asserts and not $DEBUG
250
- return if yield
251
-
252
- callstack = caller
253
- callstack.slice!(0, 3) if callstack.first["assert"]
254
- file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
255
-
256
- message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}."
257
-
258
- if Breakpoint.asserts_cause_exceptions and not $DEBUG then
259
- raise(Breakpoint::FailedAssertError, message)
260
- end
261
-
262
- message += " Executing implicit breakpoint."
263
-
264
- if context then
265
- return handle_breakpoint(context, message, file, line)
266
- end
267
-
268
- Binding.of_caller do |context|
269
- handle_breakpoint(context, message, file, line)
270
- end
271
- end
272
-
273
- # Whether asserts should be ignored if not in debug mode.
274
- # Debug mode can be enabled by running ruby with the -d
275
- # switch or by setting $DEBUG to true.
276
- attr_accessor :optimize_asserts
277
- self.optimize_asserts = false
278
-
279
- # Whether an Exception should be raised on failed asserts
280
- # in non-$DEBUG code or not. By default this is disabled.
281
- attr_accessor :asserts_cause_exceptions
282
- self.asserts_cause_exceptions = false
283
- @use_drb = false
284
-
285
- attr_reader :drb_service # :nodoc:
286
-
287
- class DRbService # :nodoc:
288
- include DRbUndumped
289
-
290
- def initialize
291
- @handler = @eval_handler = @collision_handler = nil
292
-
293
- IRB.instance_eval { @CONF[:RC] = true }
294
- IRB.run_config
295
- end
296
-
297
- def collision
298
- sleep(0.5) until @collision_handler
299
-
300
- @collision_handler.untaint
301
-
302
- @collision_handler.call
303
- end
304
-
305
- def ping() end
306
-
307
- def add_breakpoint(context, message)
308
- workspace = IRB::WorkSpace.new(context)
309
- workspace.extend(DRbUndumped)
310
-
311
- sleep(0.5) until @handler
312
-
313
- @handler.untaint
314
- @handler.call(workspace, message)
315
- rescue Errno::ECONNREFUSED, DRb::DRbConnError
316
- raise if Breakpoint.use_drb?
317
- end
318
-
319
- attr_accessor :handler, :eval_handler, :collision_handler
320
- end
321
-
322
- # Will run Breakpoint in DRb mode. This will spawn a server
323
- # that can be attached to via the breakpoint-client command
324
- # whenever a breakpoint is executed. This is useful when you
325
- # are debugging CGI applications or other applications where
326
- # you can't access debug sessions via the standard input and
327
- # output of your application.
328
- #
329
- # You can specify an URI where the DRb server will run at.
330
- # This way you can specify the port the server runs on. The
331
- # default URI is druby://localhost:42531.
332
- #
333
- # Please note that breakpoints will be skipped silently in
334
- # case the DRb server can not spawned. (This can happen if
335
- # the port is already used by another instance of your
336
- # application on CGI or another application.)
337
- #
338
- # Also note that by default this will only allow access
339
- # from localhost. You can however specify a list of
340
- # allowed hosts or nil (to allow access from everywhere).
341
- # But that will still not protect you from somebody
342
- # reading the data as it goes through the net.
343
- #
344
- # A good approach for getting security and remote access
345
- # is setting up an SSH tunnel between the DRb service
346
- # and the client. This is usually done like this:
347
- #
348
- # $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com
349
- # (This will connect port 20000 at the client side to port
350
- # 20000 at the server side, and port 10000 at the server
351
- # side to port 10000 at the client side.)
352
- #
353
- # After that do this on the server side: (the code being debugged)
354
- # Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost")
355
- #
356
- # And at the client side:
357
- # ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
358
- #
359
- # Running through such a SSH proxy will also let you use
360
- # breakpoint.rb in case you are behind a firewall.
361
- #
362
- # Detailed information about running DRb through firewalls is
363
- # available at http://www.rubygarden.org/ruby?DrbTutorial
364
- #
365
- # == Security considerations
366
- # Usually you will be fine when using the default druby:// URI and the default
367
- # access control list. However, if you are sitting on a machine where there are
368
- # local users that you likely can not trust (this is the case for example on
369
- # most web hosts which have multiple users sitting on the same physical machine)
370
- # you will be better off by doing client/server communication through a unix
371
- # socket. This can be accomplished by calling with a drbunix:/ style URI, e.g.
372
- # <code>Breakpoint.activate_drb('drbunix:/tmp/breakpoint_server')</code>. This
373
- # will only work on Unix based platforms.
374
- def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
375
- ignore_collisions = false)
376
-
377
- return false if @use_drb
378
-
379
- uri ||= 'druby://localhost:42531'
380
-
381
- if allowed_hosts then
382
- acl = ["deny", "all"]
383
-
384
- Array(allowed_hosts).each do |host|
385
- acl += ["allow", host]
386
- end
387
-
388
- DRb.install_acl(ACL.new(acl))
389
- end
390
-
391
- @use_drb = true
392
- @drb_service = DRbService.new
393
- did_collision = false
394
- begin
395
- @service = DRb.start_service(uri, @drb_service)
396
- rescue Errno::EADDRINUSE
397
- if ignore_collisions then
398
- nil
399
- else
400
- # The port is already occupied by another
401
- # Breakpoint service. We will try to tell
402
- # the old service that we want its port.
403
- # It will then forward that request to the
404
- # user and retry.
405
- unless did_collision then
406
- DRbObject.new(nil, uri).collision
407
- did_collision = true
408
- end
409
- sleep(10)
410
- retry
411
- end
412
- end
413
-
414
- return true
415
- end
416
-
417
- # Deactivates a running Breakpoint service.
418
- def deactivate_drb
419
- Thread.exclusive do
420
- @service.stop_service unless @service.nil?
421
- @service = nil
422
- @use_drb = false
423
- @drb_service = nil
424
- end
425
- end
426
-
427
- # Returns true when Breakpoints are used over DRb.
428
- # Breakpoint.activate_drb causes this to be true.
429
- def use_drb?
430
- @use_drb == true
431
- end
432
- end
433
-
434
- module IRB # :nodoc:
435
- class << self; remove_method :start; end
436
- def self.start(ap_path = nil, main_context = nil, workspace = nil)
437
- $0 = File::basename(ap_path, ".rb") if ap_path
438
-
439
- # suppress some warnings about redefined constants
440
- old_verbose, $VERBOSE = $VERBOSE, nil
441
- IRB.setup(ap_path)
442
- $VERBOSE = old_verbose
443
-
444
- if @CONF[:SCRIPT] then
445
- irb = Irb.new(main_context, @CONF[:SCRIPT])
446
- else
447
- irb = Irb.new(main_context)
448
- end
449
-
450
- if workspace then
451
- irb.context.workspace = workspace
452
- end
453
-
454
- @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
455
- @CONF[:MAIN_CONTEXT] = irb.context
456
-
457
- old_sigint = trap("SIGINT") do
458
- begin
459
- irb.signal_handle
460
- rescue RubyLex::TerminateLineInput
461
- # ignored
462
- end
463
- end
464
-
465
- catch(:IRB_EXIT) do
466
- irb.eval_input
467
- end
468
- ensure
469
- trap("SIGINT", old_sigint)
470
- end
471
-
472
- class << self
473
- alias :old_CurrentContext :CurrentContext
474
- remove_method :CurrentContext
475
- remove_method :parse_opts
476
- end
477
-
478
- def IRB.CurrentContext
479
- if old_CurrentContext.nil? and Breakpoint.use_drb? then
480
- result = Object.new
481
- def result.last_value; end
482
- return result
483
- else
484
- old_CurrentContext
485
- end
486
- end
487
- def IRB.parse_opts() end
488
-
489
- class Context # :nodoc:
490
- alias :old_evaluate :evaluate
491
- def evaluate(line, line_no)
492
- if line.chomp == "exit" then
493
- exit
494
- else
495
- old_evaluate(line, line_no)
496
- end
497
- end
498
- end
499
-
500
- class WorkSpace # :nodoc:
501
- alias :old_evaluate :evaluate
502
-
503
- def evaluate(*args)
504
- if Breakpoint.use_drb? then
505
- result = old_evaluate(*args)
506
- if args[0] != :no_proxy and
507
- not [true, false, nil].include?(result)
508
- then
509
- result.extend(DRbUndumped) rescue nil
510
- end
511
- return result
512
- else
513
- old_evaluate(*args)
514
- end
515
- end
516
- end
517
-
518
- module InputCompletor # :nodoc:
519
- def self.eval(code, context, *more)
520
- # Big hack, this assumes that InputCompletor
521
- # will only call eval() when it wants code
522
- # to be executed in the IRB context.
523
- IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more)
524
- end
525
- end
526
- end
527
-
528
- module DRb # :nodoc:
529
- class DRbObject # :nodoc:
530
- undef :inspect if method_defined?(:inspect)
531
- undef :clone if method_defined?(:clone)
532
- end
533
- end
534
-
535
- # See Breakpoint.breakpoint
536
- def breakpoint(id = nil, &block)
537
- Binding.of_caller do |context|
538
- Breakpoint.breakpoint(id, context, &block)
539
- end
540
- end
541
-
542
- # See Breakpoint.assert
543
- def assert(&block)
544
- Binding.of_caller do |context|
545
- Breakpoint.assert(context, &block)
546
- end
547
- end