activesupport 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

@@ -0,0 +1,70 @@
1
+ *1.0.0* (24th February, 2005)
2
+
3
+ * Added TimeZone as the first of a number of value objects that among others Active Record can use rich value objects using composed_of #688 [Jamis Buck]
4
+
5
+ * Added Date::Conversions for getting dates in different convenient string representations and other objects
6
+
7
+ * Added Time::Conversions for getting times in different convenient string representations and other objects
8
+
9
+ * Added Time::Calculations to ask for things like Time.now.tomorrow, Time.now.yesterday, Time.now.months_ago(4) #580 [DP|Flurin]. Examples:
10
+
11
+ "Later today" => now.in(3.hours),
12
+ "Tomorrow morning" => now.tomorrow.change(:hour => 9),
13
+ "Tomorrow afternoon" => now.tomorrow.change(:hour => 14),
14
+ "In a couple of days" => now.tomorrow.tomorrow.change(:hour => 9),
15
+ "Next monday" => now.next_week.change(:hour => 9),
16
+ "In a month" => now.next_month.change(:hour => 9),
17
+ "In 6 months" => now.months_since(6).change(:hour => 9),
18
+ "In a year" => now.in(1.year).change(:hour => 9)
19
+
20
+ * Upgraded to breakpoint 92 which fixes:
21
+
22
+ * overload IRB.parse_opts(), fixes #443
23
+ => breakpoints in tests work even when running them via rake
24
+ * untaint handlers, might fix an issue discussed on the Rails ML
25
+ * added verbose mode to breakpoint_client
26
+ * less noise caused by breakpoint_client by default
27
+ * ignored TerminateLineInput exception in signal handler
28
+ => quiet exit on Ctrl-C
29
+
30
+ * Fixed Inflector for words like "news" and "series" that are the same in plural and singular #603 [echion], #615 [marcenuc]
31
+
32
+ * Added Hash#stringify_keys and Hash#stringify_keys!
33
+
34
+ * Added IndifferentAccess as a way to wrap a hash by a symbol-based store that also can be accessed by string keys
35
+
36
+ * Added Inflector.constantize to turn "Admin::User" into a reference for the constant Admin::User
37
+
38
+ * Added that Inflector.camelize and Inflector.underscore can deal with modules like turning "Admin::User" into "admin/user" and back
39
+
40
+ * Added Inflector.humanize to turn attribute names like employee_salary into "Employee salary". Used by automated error reporting in AR.
41
+
42
+ * Added availability of class inheritable attributes to the masses #477 [bitsweat]
43
+
44
+ class Foo
45
+ class_inheritable_reader :read_me
46
+ class_inheritable_writer :write_me
47
+ class_inheritable_accessor :read_and_write_me
48
+ class_inheritable_array :read_and_concat_me
49
+ class_inheritable_hash :read_and_update_me
50
+ end
51
+
52
+ # Bar gets a clone of (not a reference to) Foo's attributes.
53
+ class Bar < Foo
54
+ end
55
+
56
+ Bar.read_and_write_me == Foo.read_and_write_me
57
+ Bar.read_and_write_me = 'bar'
58
+ Bar.read_and_write_me != Foo.read_and_write_me
59
+
60
+ * Added Inflections as an extension on String, so Inflector.pluralize(Inflector.classify(name)) becomes name.classify.pluralize #476 [bitsweat]
61
+
62
+ * Added Byte operations to Numeric, so 5.5.megabytes + 200.kilobytes #461 [Marcel Molina]
63
+
64
+ * Fixed that Dependencies.reload can't load the same file twice #420 [Kent Sibilev]
65
+
66
+ * Added Fixnum#ago/until, Fixnum#since/from_now #450 [bitsweat]
67
+
68
+ * Added that Inflector now accepts Symbols and Classes by calling .to_s on the word supplied
69
+
70
+ * Added time unit extensions to Fixnum that'll return the period in seconds, like 2.days + 4.hours.
@@ -0,0 +1,31 @@
1
+ #--
2
+ # Copyright (c) 2005 David Heinemeier Hansson
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $:.unshift(File.dirname(__FILE__))
25
+
26
+ require 'active_support/core_ext'
27
+ require 'active_support/clean_logger'
28
+ require 'active_support/misc'
29
+ require 'active_support/dependencies'
30
+
31
+ require 'active_support/values/time_zone'
@@ -0,0 +1,84 @@
1
+ begin
2
+ require 'simplecc'
3
+ rescue LoadError
4
+ class Continuation # :nodoc: # for RDoc
5
+ end
6
+ def Continuation.create(*args, &block) # :nodoc:
7
+ cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
8
+ result ||= args
9
+ return *[cc, *result]
10
+ end
11
+ end
12
+
13
+ class Binding; end # for RDoc
14
+ # This method returns the binding of the method that called your
15
+ # method. It will raise an Exception when you're not inside a method.
16
+ #
17
+ # It's used like this:
18
+ # def inc_counter(amount = 1)
19
+ # Binding.of_caller do |binding|
20
+ # # Create a lambda that will increase the variable 'counter'
21
+ # # in the caller of this method when called.
22
+ # inc = eval("lambda { |arg| counter += arg }", binding)
23
+ # # We can refer to amount from inside this block safely.
24
+ # inc.call(amount)
25
+ # end
26
+ # # No other statements can go here. Put them inside the block.
27
+ # end
28
+ # counter = 0
29
+ # 2.times { inc_counter }
30
+ # counter # => 2
31
+ #
32
+ # Binding.of_caller must be the last statement in the method.
33
+ # This means that you will have to put everything you want to
34
+ # do after the call to Binding.of_caller into the block of it.
35
+ # This should be no problem however, because Ruby has closures.
36
+ # If you don't do this an Exception will be raised. Because of
37
+ # the way that Binding.of_caller is implemented it has to be
38
+ # done this way.
39
+ def Binding.of_caller(&block)
40
+ old_critical = Thread.critical
41
+ Thread.critical = true
42
+ count = 0
43
+ cc, result, error, extra_data = Continuation.create(nil, nil)
44
+ error.call if error
45
+
46
+ tracer = lambda do |*args|
47
+ type, context, extra_data = args[0], args[4], args
48
+ if type == "return"
49
+ count += 1
50
+ # First this method and then calling one will return --
51
+ # the trace event of the second event gets the context
52
+ # of the method which called the method that called this
53
+ # method.
54
+ if count == 2
55
+ # It would be nice if we could restore the trace_func
56
+ # that was set before we swapped in our own one, but
57
+ # this is impossible without overloading set_trace_func
58
+ # in current Ruby.
59
+ set_trace_func(nil)
60
+ cc.call(eval("binding", context), nil, extra_data)
61
+ end
62
+ elsif type == "line" then
63
+ nil
64
+ elsif type == "c-return" and extra_data[3] == :set_trace_func then
65
+ nil
66
+ else
67
+ set_trace_func(nil)
68
+ error_msg = "Binding.of_caller used in non-method context or " +
69
+ "trailing statements of method using it aren't in the block."
70
+ cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
71
+ end
72
+ end
73
+
74
+ unless result
75
+ set_trace_func(tracer)
76
+ return nil
77
+ else
78
+ Thread.critical = old_critical
79
+ case block.arity
80
+ when 1 then yield(result)
81
+ else yield(result, extra_data)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,523 @@
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 File.dirname(__FILE__) + '/binding_of_caller'
20
+ require 'drb'
21
+ require 'drb/acl'
22
+
23
+ module Breakpoint
24
+ id = %q$Id: breakpoint.rb 92 2005-02-04 22:35:53Z flgr $
25
+ Version = id.split(" ")[2].to_i
26
+
27
+ extend self
28
+
29
+ # This will pop up an interactive ruby session at a
30
+ # pre-defined break point in a Ruby application. In
31
+ # this session you can examine the environment of
32
+ # the break point.
33
+ #
34
+ # You can get a list of variables in the context using
35
+ # local_variables via +local_variables+. You can then
36
+ # examine their values by typing their names.
37
+ #
38
+ # You can have a look at the call stack via +caller+.
39
+ #
40
+ # The source code around the location where the breakpoint
41
+ # was executed can be examined via +source_lines+. Its
42
+ # argument specifies how much lines of context to display.
43
+ # The default amount of context is 5 lines. Note that
44
+ # the call to +source_lines+ can raise an exception when
45
+ # it isn't able to read in the source code.
46
+ #
47
+ # breakpoints can also return a value. They will execute
48
+ # a supplied block for getting a default return value.
49
+ # A custom value can be returned from the session by doing
50
+ # +throw(:debug_return, value)+.
51
+ #
52
+ # You can also give names to break points which will be
53
+ # used in the message that is displayed upon execution
54
+ # of them.
55
+ #
56
+ # Here's a sample of how breakpoints should be placed:
57
+ #
58
+ # class Person
59
+ # def initialize(name, age)
60
+ # @name, @age = name, age
61
+ # breakpoint("Person#initialize")
62
+ # end
63
+ #
64
+ # attr_reader :age
65
+ # def name
66
+ # breakpoint("Person#name") { @name }
67
+ # end
68
+ # end
69
+ #
70
+ # person = Person.new("Random Person", 23)
71
+ # puts "Name: #{person.name}"
72
+ #
73
+ # And here is a sample debug session:
74
+ #
75
+ # Executing break point "Person#initialize" at file.rb:4 in `initialize'
76
+ # irb(#<Person:0x292fbe8>):001:0> local_variables
77
+ # => ["name", "age", "_", "__"]
78
+ # irb(#<Person:0x292fbe8>):002:0> [name, age]
79
+ # => ["Random Person", 23]
80
+ # irb(#<Person:0x292fbe8>):003:0> [@name, @age]
81
+ # => ["Random Person", 23]
82
+ # irb(#<Person:0x292fbe8>):004:0> self
83
+ # => #<Person:0x292fbe8 @age=23, @name="Random Person">
84
+ # irb(#<Person:0x292fbe8>):005:0> @age += 1; self
85
+ # => #<Person:0x292fbe8 @age=24, @name="Random Person">
86
+ # irb(#<Person:0x292fbe8>):006:0> exit
87
+ # Executing break point "Person#name" at file.rb:9 in `name'
88
+ # irb(#<Person:0x292fbe8>):001:0> throw(:debug_return, "Overriden name")
89
+ # Name: Overriden name
90
+ #
91
+ # Breakpoint sessions will automatically have a few
92
+ # convenience methods available. See Breakpoint::CommandBundle
93
+ # for a list of them.
94
+ #
95
+ # Breakpoints can also be used remotely over sockets.
96
+ # This is implemented by running part of the IRB session
97
+ # in the application and part of it in a special client.
98
+ # You have to call Breakpoint.activate_drb to enable
99
+ # support for remote breakpoints and then run
100
+ # breakpoint_client.rb which is distributed with this
101
+ # library. See the documentation of Breakpoint.activate_drb
102
+ # for details.
103
+ def breakpoint(id = nil, context = nil, &block)
104
+ callstack = caller
105
+ callstack.slice!(0, 3) if callstack.first["breakpoint"]
106
+ file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
107
+
108
+ message = "Executing break point " + (id ? "#{id.inspect} " : "") +
109
+ "at #{file}:#{line}" + (method ? " in `#{method}'" : "")
110
+
111
+ if context then
112
+ return handle_breakpoint(context, message, file, line, &block)
113
+ end
114
+
115
+ Binding.of_caller do |binding_context|
116
+ handle_breakpoint(binding_context, message, file, line, &block)
117
+ end
118
+ end
119
+
120
+ module CommandBundle #:nodoc:
121
+ # Proxy to a Breakpoint client. Lets you directly execute code
122
+ # in the context of the client.
123
+ class Client #:nodoc:
124
+ def initialize(eval_handler) # :nodoc:
125
+ eval_handler.untaint
126
+ @eval_handler = eval_handler
127
+ end
128
+
129
+ instance_methods.each do |method|
130
+ next if method[/^__.+__$/]
131
+ undef_method method
132
+ end
133
+
134
+ # Executes the specified code at the client.
135
+ def eval(code)
136
+ @eval_handler.call(code)
137
+ end
138
+
139
+ # Will execute the specified statement at the client.
140
+ def method_missing(method, *args, &block)
141
+ if args.empty? and not block
142
+ result = eval "#{method}"
143
+ else
144
+ # This is a bit ugly. The alternative would be using an
145
+ # eval context instead of an eval handler for executing
146
+ # the code at the client. The problem with that approach
147
+ # is that we would have to handle special expressions
148
+ # like "self", "nil" or constants ourself which is hard.
149
+ remote = eval %{
150
+ result = lambda { |block, *args| #{method}(*args, &block) }
151
+ def result.call_with_block(*args, &block)
152
+ call(block, *args)
153
+ end
154
+ result
155
+ }
156
+ remote.call_with_block(*args, &block)
157
+ end
158
+
159
+ return result
160
+ end
161
+ end
162
+
163
+ # Returns the source code surrounding the location where the
164
+ # breakpoint was issued.
165
+ def source_lines(context = 5, return_line_numbers = false)
166
+ lines = File.readlines(@__bp_file).map { |line| line.chomp }
167
+
168
+ break_line = @__bp_line
169
+ start_line = [break_line - context, 1].max
170
+ end_line = break_line + context
171
+
172
+ result = lines[(start_line - 1) .. (end_line - 1)]
173
+
174
+ if return_line_numbers then
175
+ return [start_line, break_line, result]
176
+ else
177
+ return result
178
+ end
179
+ end
180
+
181
+ # Lets an object that will forward method calls to the breakpoint
182
+ # client. This is useful for outputting longer things at the client
183
+ # and so on. You can for example do these things:
184
+ #
185
+ # client.puts "Hello" # outputs "Hello" at client console
186
+ # # outputs "Hello" into the file temp.txt at the client
187
+ # client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
188
+ def client()
189
+ if Breakpoint.use_drb? then
190
+ sleep(0.5) until Breakpoint.drb_service.eval_handler
191
+ Client.new(Breakpoint.drb_service.eval_handler)
192
+ else
193
+ Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
194
+ end
195
+ end
196
+ end
197
+
198
+ def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc:
199
+ catch(:debug_return) do |value|
200
+ eval(%{
201
+ @__bp_file = #{file.inspect}
202
+ @__bp_line = #{line}
203
+ extend Breakpoint::CommandBundle
204
+ extend DRbUndumped if self
205
+ }, context) rescue nil
206
+
207
+ if not use_drb? then
208
+ puts message
209
+ IRB.start(nil, IRB::WorkSpace.new(context))
210
+ else
211
+ @drb_service.add_breakpoint(context, message)
212
+ end
213
+
214
+ block.call if block
215
+ end
216
+ end
217
+
218
+ # These exceptions will be raised on failed asserts
219
+ # if Breakpoint.asserts_cause_exceptions is set to
220
+ # true.
221
+ class FailedAssertError < RuntimeError #:nodoc:
222
+ end
223
+
224
+ # This asserts that the block evaluates to true.
225
+ # If it doesn't evaluate to true a breakpoint will
226
+ # automatically be created at that execution point.
227
+ #
228
+ # You can disable assert checking in production
229
+ # code by setting Breakpoint.optimize_asserts to
230
+ # true. (It will still be enabled when Ruby is run
231
+ # via the -d argument.)
232
+ #
233
+ # Example:
234
+ # person_name = "Foobar"
235
+ # assert { not person_name.nil? }
236
+ #
237
+ # Note: If you want to use this method from an
238
+ # unit test, you will have to call it by its full
239
+ # name, Breakpoint.assert.
240
+ def assert(context = nil, &condition)
241
+ return if Breakpoint.optimize_asserts and not $DEBUG
242
+ return if yield
243
+
244
+ callstack = caller
245
+ callstack.slice!(0, 3) if callstack.first["assert"]
246
+ file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
247
+
248
+ message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}."
249
+
250
+ if Breakpoint.asserts_cause_exceptions and not $DEBUG then
251
+ raise(Breakpoint::FailedAssertError, message)
252
+ end
253
+
254
+ message += " Executing implicit breakpoint."
255
+
256
+ if context then
257
+ return handle_breakpoint(context, message, file, line)
258
+ end
259
+
260
+ Binding.of_caller do |context|
261
+ handle_breakpoint(context, message, file, line)
262
+ end
263
+ end
264
+
265
+ # Whether asserts should be ignored if not in debug mode.
266
+ # Debug mode can be enabled by running ruby with the -d
267
+ # switch or by setting $DEBUG to true.
268
+ attr_accessor :optimize_asserts
269
+ self.optimize_asserts = false
270
+
271
+ # Whether an Exception should be raised on failed asserts
272
+ # in non-$DEBUG code or not. By default this is disabled.
273
+ attr_accessor :asserts_cause_exceptions
274
+ self.asserts_cause_exceptions = false
275
+ @use_drb = false
276
+
277
+ attr_reader :drb_service # :nodoc:
278
+
279
+ class DRbService # :nodoc:
280
+ include DRbUndumped
281
+
282
+ def initialize
283
+ @handler = @eval_handler = @collision_handler = nil
284
+
285
+ IRB.instance_eval { @CONF[:RC] = true }
286
+ IRB.run_config
287
+ end
288
+
289
+ def collision
290
+ sleep(0.5) until @collision_handler
291
+
292
+ @collision_handler.untaint
293
+
294
+ @collision_handler.call
295
+ end
296
+
297
+ def ping() end
298
+
299
+ def add_breakpoint(context, message)
300
+ workspace = IRB::WorkSpace.new(context)
301
+ workspace.extend(DRbUndumped)
302
+
303
+ sleep(0.5) until @handler
304
+
305
+ @handler.untaint
306
+ @handler.call(workspace, message)
307
+ end
308
+
309
+ attr_accessor :handler, :eval_handler, :collision_handler
310
+ end
311
+
312
+ # Will run Breakpoint in DRb mode. This will spawn a server
313
+ # that can be attached to via the breakpoint-client command
314
+ # whenever a breakpoint is executed. This is useful when you
315
+ # are debugging CGI applications or other applications where
316
+ # you can't access debug sessions via the standard input and
317
+ # output of your application.
318
+ #
319
+ # You can specify an URI where the DRb server will run at.
320
+ # This way you can specify the port the server runs on. The
321
+ # default URI is druby://localhost:42531.
322
+ #
323
+ # Please note that breakpoints will be skipped silently in
324
+ # case the DRb server can not spawned. (This can happen if
325
+ # the port is already used by another instance of your
326
+ # application on CGI or another application.)
327
+ #
328
+ # Also note that by default this will only allow access
329
+ # from localhost. You can however specify a list of
330
+ # allowed hosts or nil (to allow access from everywhere).
331
+ # But that will still not protect you from somebody
332
+ # reading the data as it goes through the net.
333
+ #
334
+ # A good approach for getting security and remote access
335
+ # is setting up an SSH tunnel between the DRb service
336
+ # and the client. This is usually done like this:
337
+ #
338
+ # $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com
339
+ # (This will connect port 20000 at the client side to port
340
+ # 20000 at the server side, and port 10000 at the server
341
+ # side to port 10000 at the client side.)
342
+ #
343
+ # After that do this on the server side: (the code being debugged)
344
+ # Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost")
345
+ #
346
+ # And at the client side:
347
+ # ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
348
+ #
349
+ # Running through such a SSH proxy will also let you use
350
+ # breakpoint.rb in case you are behind a firewall.
351
+ #
352
+ # Detailed information about running DRb through firewalls is
353
+ # available at http://www.rubygarden.org/ruby?DrbTutorial
354
+ def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
355
+ ignore_collisions = false)
356
+
357
+ return false if @use_drb
358
+
359
+ uri ||= 'druby://localhost:42531'
360
+
361
+ if allowed_hosts then
362
+ acl = ["deny", "all"]
363
+
364
+ Array(allowed_hosts).each do |host|
365
+ acl += ["allow", host]
366
+ end
367
+
368
+ DRb.install_acl(ACL.new(acl))
369
+ end
370
+
371
+ @use_drb = true
372
+ @drb_service = DRbService.new
373
+ did_collision = false
374
+ begin
375
+ @service = DRb.start_service(uri, @drb_service)
376
+ rescue Errno::EADDRINUSE
377
+ if ignore_collisions then
378
+ nil
379
+ else
380
+ # The port is already occupied by another
381
+ # Breakpoint service. We will try to tell
382
+ # the old service that we want its port.
383
+ # It will then forward that request to the
384
+ # user and retry.
385
+ unless did_collision then
386
+ DRbObject.new(nil, uri).collision
387
+ did_collision = true
388
+ end
389
+ sleep(10)
390
+ retry
391
+ end
392
+ end
393
+
394
+ return true
395
+ end
396
+
397
+ # Deactivates a running Breakpoint service.
398
+ def deactivate_drb
399
+ @service.stop_service unless @service.nil?
400
+ @service = nil
401
+ @use_drb = false
402
+ @drb_service = nil
403
+ end
404
+
405
+ # Returns true when Breakpoints are used over DRb.
406
+ # Breakpoint.activate_drb causes this to be true.
407
+ def use_drb?
408
+ @use_drb == true
409
+ end
410
+ end
411
+
412
+ module IRB #:nodoc:
413
+ class << self; remove_method :start; end
414
+ def self.start(ap_path = nil, main_context = nil, workspace = nil)
415
+ $0 = File::basename(ap_path, ".rb") if ap_path
416
+
417
+ # suppress some warnings about redefined constants
418
+ old_verbose, $VERBOSE = $VERBOSE, nil
419
+ IRB.setup(ap_path)
420
+ $VERBOSE = old_verbose
421
+
422
+ if @CONF[:SCRIPT] then
423
+ irb = Irb.new(main_context, @CONF[:SCRIPT])
424
+ else
425
+ irb = Irb.new(main_context)
426
+ end
427
+
428
+ if workspace then
429
+ irb.context.workspace = workspace
430
+ end
431
+
432
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
433
+ @CONF[:MAIN_CONTEXT] = irb.context
434
+
435
+ old_sigint = trap("SIGINT") do
436
+ begin
437
+ irb.signal_handle
438
+ rescue RubyLex::TerminateLineInput
439
+ # ignored
440
+ end
441
+ end
442
+
443
+ catch(:IRB_EXIT) do
444
+ irb.eval_input
445
+ end
446
+ ensure
447
+ trap("SIGINT", old_sigint)
448
+ end
449
+
450
+ class << self
451
+ alias :old_CurrentContext :CurrentContext
452
+ remove_method :CurrentContext
453
+ end
454
+ def IRB.CurrentContext
455
+ if old_CurrentContext.nil? and Breakpoint.use_drb? then
456
+ result = Object.new
457
+ def result.last_value; end
458
+ return result
459
+ else
460
+ old_CurrentContext
461
+ end
462
+ end
463
+ def IRB.parse_opts() end
464
+
465
+ class Context #:nodoc:
466
+ alias :old_evaluate :evaluate
467
+ def evaluate(line, line_no)
468
+ if line.chomp == "exit" then
469
+ exit
470
+ else
471
+ old_evaluate(line, line_no)
472
+ end
473
+ end
474
+ end
475
+
476
+ class WorkSpace #:nodoc:
477
+ alias :old_evaluate :evaluate
478
+
479
+ def evaluate(*args)
480
+ if Breakpoint.use_drb? then
481
+ result = old_evaluate(*args)
482
+ if args[0] != :no_proxy and
483
+ not [true, false, nil].include?(result)
484
+ then
485
+ result.extend(DRbUndumped) rescue nil
486
+ end
487
+ return result
488
+ else
489
+ old_evaluate(*args)
490
+ end
491
+ end
492
+ end
493
+
494
+ module InputCompletor #:nodoc:
495
+ def self.eval(code, context, *more)
496
+ # Big hack, this assumes that InputCompletor
497
+ # will only call eval() when it wants code
498
+ # to be executed in the IRB context.
499
+ IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more)
500
+ end
501
+ end
502
+ end
503
+
504
+ module DRb # :nodoc:
505
+ class DRbObject #:nodoc:
506
+ undef :inspect if method_defined?(:inspect)
507
+ undef :clone if method_defined?(:clone)
508
+ end
509
+ end
510
+
511
+ # See Breakpoint.breakpoint
512
+ def breakpoint(id = nil, &block)
513
+ Binding.of_caller do |context|
514
+ Breakpoint.breakpoint(id, context, &block)
515
+ end
516
+ end
517
+
518
+ # See Breakpoint.assert
519
+ def assert(&block)
520
+ Binding.of_caller do |context|
521
+ Breakpoint.assert(context, &block)
522
+ end
523
+ end