Permalink
Browse files

Fixed some breakpoint issues and made breakpoint_client depend on act…

…iverecord/support instead of duplicating the files in railties #441 [Florian Gross]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@424 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent fb13b7a commit c46e390920950f273bdfc1c664f5e672f59e3a21 @dhh dhh committed Jan 15, 2005
@@ -21,6 +21,9 @@
require 'drb/acl'
module Breakpoint
+ id = %q$Id$
+ Version = id.split(" ")[2].to_i
+
extend self
# This will pop up an interactive ruby session at a
@@ -133,15 +136,24 @@ def eval(code)
end
# Will execute the specified statement at the client.
- def method_missing(method, *args)
- if args.empty?
- result = eval("#{method}")
+ def method_missing(method, *args, &block)
+ if args.empty? and not block
+ result = eval "#{method}"
else
result = eval("#{method}(*Marshal.load(#{Marshal.dump(args).inspect}))")
- end
-
- unless [true, false, nil].include?(result)
- result.extend(DRbUndumped) if result
+ # This is a bit ugly. The alternative would be using an
+ # eval context instead of an eval handler for executing
+ # the code at the client. The problem with that approach
+ # is that we would have to handle special expressions
+ # like "self", "nil" or constants ourself which is hard.
+ remote = eval %{
+ result = lambda { |block, *args| #{method}(*args, &block) }
+ def result.call_with_block(*args, &block)
+ call(block, *args)
+ end
+ result
+ }
+ remote.call_with_block(*args, &block)
end
return result
@@ -175,6 +187,7 @@ def source_lines(context = 5, return_line_numbers = false)
# client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
def client()
if Breakpoint.use_drb? then
+ sleep(0.5) until Breakpoint.drb_service.eval_handler
Client.new(Breakpoint.drb_service.eval_handler)
else
Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
@@ -279,7 +292,7 @@ def collision
@collision_handler.call
end
- def ping; end
+ def ping() end
def add_breakpoint(context, message)
workspace = IRB::WorkSpace.new(context)
@@ -290,31 +303,7 @@ def add_breakpoint(context, message)
@handler.call(workspace, message)
end
- def register_handler(&block)
- @handler = block
- end
-
- def unregister_handler
- @handler = nil
- end
-
- attr_reader :eval_handler
-
- def register_eval_handler(&block)
- @eval_handler = block
- end
-
- def unregister_eval_handler
- @eval_handler = lambda { }
- end
-
- def register_collision_handler(&block)
- @collision_handler = block
- end
-
- def unregister_collision_handler
- @collision_handler = lambda { }
- end
+ attr_accessor :handler, :eval_handler, :collision_handler
end
# Will run Breakpoint in DRb mode. This will spawn a server
@@ -507,8 +496,8 @@ def self.eval(code, context, *more)
module DRb # :nodoc:
class DRbObject#:nodoc:
- undef :inspect
- undef :clone
+ undef :inspect if method_defined?(:inspect)
+ undef :clone if method_defined?(:clone)
end
end
@@ -1,3 +1,4 @@
#!/usr/local/bin/ruby
$LOAD_PATH << File.dirname(__FILE__) + '/../vendor/railties/lib'
+$LOAD_PATH << File.dirname(__FILE__) + '/../vendor/activerecord/lib/support'
require 'breakpoint_client'
@@ -1,81 +0,0 @@
-begin
- require 'simplecc'
-rescue LoadError
- def Continuation.create(*args, &block)
- cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
- result ||= args
- return *[cc, *result]
- end
-end
-
-# This method returns the binding of the method that called your
-# method. It will raise an Exception when you're not inside a method.
-#
-# It's used like this:
-# def inc_counter(amount = 1)
-# Binding.of_caller do |binding|
-# # Create a lambda that will increase the variable 'counter'
-# # in the caller of this method when called.
-# inc = eval("lambda { |arg| counter += arg }", binding)
-# # We can refer to amount from inside this block safely.
-# inc.call(amount)
-# end
-# # No other statements can go here. Put them inside the block.
-# end
-# counter = 0
-# 2.times { inc_counter }
-# counter # => 2
-#
-# Binding.of_caller must be the last statement in the method.
-# This means that you will have to put everything you want to
-# do after the call to Binding.of_caller into the block of it.
-# This should be no problem however, because Ruby has closures.
-# If you don't do this an Exception will be raised. Because of
-# the way that Binding.of_caller is implemented it has to be
-# done this way.
-def Binding.of_caller(&block)
- old_critical = Thread.critical
- Thread.critical = true
- count = 0
- cc, result, error, extra_data = Continuation.create(nil, nil)
- error.call if error
-
- tracer = lambda do |*args|
- type, context, extra_data = args[0], args[4], args
- if type == "return"
- count += 1
- # First this method and then calling one will return --
- # the trace event of the second event gets the context
- # of the method which called the method that called this
- # method.
- if count == 2
- # It would be nice if we could restore the trace_func
- # that was set before we swapped in our own one, but
- # this is impossible without overloading set_trace_func
- # in current Ruby.
- set_trace_func(nil)
- cc.call(eval("binding", context), nil, extra_data)
- end
- elsif type == "line" then
- nil
- elsif type == "c-return" and extra_data[3] == :set_trace_func then
- nil
- else
- set_trace_func(nil)
- error_msg = "Binding.of_caller used in non-method context or " +
- "trailing statements of method using it aren't in the block."
- cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
- end
- end
-
- unless result
- set_trace_func(tracer)
- return nil
- else
- Thread.critical = old_critical
- case block.arity
- when 1 then yield(result)
- else yield(result, extra_data)
- end
- end
-end
Oops, something went wrong.

0 comments on commit c46e390

Please sign in to comment.