mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
added basic skeleton for hooks system (yet to add many hook callsites)
This commit is contained in:
commit
c02772af19
9 changed files with 167 additions and 31 deletions
|
@ -4,19 +4,19 @@
|
||||||
|
|
||||||
require 'pp'
|
require 'pp'
|
||||||
require 'pry/helpers/base_helpers'
|
require 'pry/helpers/base_helpers'
|
||||||
|
require 'pry/hooks'
|
||||||
|
|
||||||
class Pry
|
class Pry
|
||||||
# The default hooks - display messages when beginning and ending Pry sessions.
|
# The default hooks - display messages when beginning and ending Pry sessions.
|
||||||
DEFAULT_HOOKS = {
|
DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session) do |out, target, _pry_|
|
||||||
:before_session => proc do |out, target, _pry_|
|
|
||||||
# ensure we're actually in a method
|
# ensure we're actually in a method
|
||||||
file = target.eval('__FILE__')
|
file = target.eval('__FILE__')
|
||||||
|
|
||||||
# /unknown/ for rbx
|
# /unknown/ for rbx
|
||||||
if file == Pry.eval_path || (file !~ /(\(.*\))|<.*>/ && file !~ /__unknown__/ && file != "" && file != "-e")
|
if file !~ /(\(.*\))|<.*>/ && file !~ /__unknown__/ && file != "" && file != "-e"
|
||||||
_pry_.process_line("whereami 5", "", target)
|
_pry_.process_line("whereami 5", "", target)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
|
||||||
|
|
||||||
# The default print
|
# The default print
|
||||||
DEFAULT_PRINT = proc do |output, value|
|
DEFAULT_PRINT = proc do |output, value|
|
||||||
|
|
52
lib/pry/hooks.rb
Normal file
52
lib/pry/hooks.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
class Pry
|
||||||
|
class Hooks
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@hooks = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new callable to be executed for the `name` hook.
|
||||||
|
# @param [Symbol] name The name of the hook.
|
||||||
|
# @param [#call] callable The callable.
|
||||||
|
# @yield The block to use as the callable (if `callable` parameter not provided)
|
||||||
|
def add_hook(name, callable=nil, &block)
|
||||||
|
@hooks[name] ||= []
|
||||||
|
|
||||||
|
if block
|
||||||
|
@hooks[name] << block
|
||||||
|
elsif callable
|
||||||
|
@hooks[name] << callable
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Must provide a block or callable."
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
# Execute the list of callables for the `name` hook.
|
||||||
|
# @param [Symbol] name The name of the hook to execute.
|
||||||
|
# @param [Array] args The arguments to pass to each callable.
|
||||||
|
def exec_hook(name, *args, &block)
|
||||||
|
Array(@hooks[name]).each { |v| v.call(*args, &block) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return the number of callables registered for the `name` hook.
|
||||||
|
# @param [Symbol] name The name of the hook.
|
||||||
|
def hook_count(name)
|
||||||
|
@hooks[name] ||= []
|
||||||
|
@hooks[name].size
|
||||||
|
end
|
||||||
|
|
||||||
|
# Clear the list of callables for the `name` hook.
|
||||||
|
# @param [Symbol] The name of the hook to delete.
|
||||||
|
def delete_hook(name)
|
||||||
|
@hooks[name] = []
|
||||||
|
end
|
||||||
|
|
||||||
|
# Clear all hooks.
|
||||||
|
def reset
|
||||||
|
@hooks = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
class Pry
|
class Pry
|
||||||
class Method
|
class Method
|
||||||
include RbxMethod if Helpers::BaseHelpers.rbx?
|
include RbxMethod if Helpers::BaseHelpers.rbx?
|
||||||
|
@ -178,7 +179,7 @@ class Pry
|
||||||
if Helpers::BaseHelpers.rbx? && core?
|
if Helpers::BaseHelpers.rbx? && core?
|
||||||
code = core_code
|
code = core_code
|
||||||
elsif pry_method?
|
elsif pry_method?
|
||||||
code = Pry.new(:input => StringIO.new(Pry.line_buffer[source_line..-1].join), :prompt => proc {""}, :hooks => {}).r
|
code = Pry.new(:input => StringIO.new(Pry.line_buffer[source_line..-1].join), :prompt => proc {""}, :hooks => Pry::Hooks.new).r
|
||||||
else
|
else
|
||||||
code = @method.source
|
code = @method.source
|
||||||
end
|
end
|
||||||
|
|
|
@ -165,7 +165,7 @@ class Pry
|
||||||
|
|
||||||
output = options[:show_output] ? options[:output] : StringIO.new
|
output = options[:show_output] ? options[:output] : StringIO.new
|
||||||
|
|
||||||
Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands], :prompt => proc {""}, :hooks => {}).rep(options[:context])
|
Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands], :prompt => proc {""}, :hooks => Pry::Hooks.new).rep(options[:context])
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_editor_for_platform
|
def self.default_editor_for_platform
|
||||||
|
|
|
@ -149,7 +149,7 @@ class Pry
|
||||||
# Initialize the repl session.
|
# Initialize the repl session.
|
||||||
# @param [Binding] target The target binding for the session.
|
# @param [Binding] target The target binding for the session.
|
||||||
def repl_prologue(target)
|
def repl_prologue(target)
|
||||||
exec_hook :before_session, output, target, self
|
hooks.exec_hook :before_session, output, target, self
|
||||||
initialize_special_locals(target)
|
initialize_special_locals(target)
|
||||||
|
|
||||||
@input_array << nil # add empty input so _in_ and _out_ match
|
@input_array << nil # add empty input so _in_ and _out_ match
|
||||||
|
@ -161,7 +161,7 @@ class Pry
|
||||||
# Clean-up after the repl session.
|
# Clean-up after the repl session.
|
||||||
# @param [Binding] target The target binding for the session.
|
# @param [Binding] target The target binding for the session.
|
||||||
def repl_epilogue(target)
|
def repl_epilogue(target)
|
||||||
exec_hook :after_session, output, target, self
|
hooks.exec_hook :after_session, output, target, self
|
||||||
|
|
||||||
Pry.active_sessions -= 1
|
Pry.active_sessions -= 1
|
||||||
binding_stack.pop
|
binding_stack.pop
|
||||||
|
@ -235,9 +235,10 @@ class Pry
|
||||||
result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
|
result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
|
||||||
result
|
result
|
||||||
rescue RescuableException => e
|
rescue RescuableException => e
|
||||||
set_last_exception(e, target)
|
result = set_last_exception(e, target)
|
||||||
ensure
|
ensure
|
||||||
update_input_history(code)
|
update_input_history(code)
|
||||||
|
hooks.exec_hook :after_eval, result, self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Perform a read.
|
# Perform a read.
|
||||||
|
@ -270,6 +271,7 @@ class Pry
|
||||||
|
|
||||||
@suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
|
@suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
|
||||||
|
|
||||||
|
hooks.exec_hook :after_read, eval_string, self
|
||||||
eval_string
|
eval_string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class << Pry
|
||||||
Pry.config.history.should_load = false
|
Pry.config.history.should_load = false
|
||||||
Pry.config.history.should_save = false
|
Pry.config.history.should_save = false
|
||||||
Pry.config.auto_indent = false
|
Pry.config.auto_indent = false
|
||||||
Pry.config.hooks = { }
|
Pry.config.hooks = Pry::Hooks.new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ describe "Pry::DefaultCommands::Input" do
|
||||||
b = binding
|
b = binding
|
||||||
b.eval('x = "\"hello\""')
|
b.eval('x = "\"hello\""')
|
||||||
redirect_pry_io(InputTester.new("play x", "exit-all"), str_output = StringIO.new) do
|
redirect_pry_io(InputTester.new("play x", "exit-all"), str_output = StringIO.new) do
|
||||||
Pry.start b, :hooks => {}
|
Pry.start b, :hooks => Pry::Hooks.new
|
||||||
end
|
end
|
||||||
str_output.string.should =~ /hello/
|
str_output.string.should =~ /hello/
|
||||||
end
|
end
|
||||||
|
@ -163,7 +163,7 @@ describe "Pry::DefaultCommands::Input" do
|
||||||
b = binding
|
b = binding
|
||||||
b.eval('x = "\"hello\"\n\"goodbye\"\n\"love\""')
|
b.eval('x = "\"hello\"\n\"goodbye\"\n\"love\""')
|
||||||
redirect_pry_io(InputTester.new("play x --lines 1", "exit-all"), str_output = StringIO.new) do
|
redirect_pry_io(InputTester.new("play x --lines 1", "exit-all"), str_output = StringIO.new) do
|
||||||
Pry.start b, :hooks => {}
|
Pry.start b, :hooks => Pry::Hooks.new
|
||||||
end
|
end
|
||||||
str_output.string.should =~ /hello/
|
str_output.string.should =~ /hello/
|
||||||
str_output.string.should.not =~ /love/
|
str_output.string.should.not =~ /love/
|
||||||
|
|
85
test/test_hooks.rb
Normal file
85
test/test_hooks.rb
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
require 'helper'
|
||||||
|
|
||||||
|
describe Pry::Hooks do
|
||||||
|
before do
|
||||||
|
@hooks = Pry::Hooks.new
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "adding a new hook" do
|
||||||
|
it 'should not execute hook while adding it' do
|
||||||
|
@hooks.add_hook(:test_hook) { @test_var = true }
|
||||||
|
@test_var.should == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a count of 0 for an empty hook' do
|
||||||
|
@hooks.hook_count(:test_hook).should == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create a new hook with a block' do
|
||||||
|
@hooks.add_hook(:test_hook) { }
|
||||||
|
@hooks.hook_count(:test_hook).should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create a new hook with a callable' do
|
||||||
|
@hooks.add_hook(:test_hook, proc { })
|
||||||
|
@hooks.hook_count(:test_hook).should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should use just block if given both block and callable' do
|
||||||
|
@hooks.add_hook(:test_hook, proc { }) { }
|
||||||
|
@hooks.hook_count(:test_hook).should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should raise if not given a block or any other object' do
|
||||||
|
lambda { @hooks.add_hook(:test_hook) }.should.raise ArgumentError
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create a hook with multiple callables' do
|
||||||
|
@hooks.add_hook(:test_hook) {}
|
||||||
|
@hooks.add_hook(:test_hook) {}
|
||||||
|
@hooks.hook_count(:test_hook).should == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "executing a hook" do
|
||||||
|
before do
|
||||||
|
@test_var = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should execute block hook' do
|
||||||
|
@hooks.add_hook(:test_hook) { @test_var = true }
|
||||||
|
@hooks.exec_hook(:test_hook)
|
||||||
|
@test_var.should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should execute proc hook' do
|
||||||
|
@hooks.add_hook(:test_hook, proc { @test_var = true })
|
||||||
|
@hooks.exec_hook(:test_hook)
|
||||||
|
@test_var.should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should execute a general callable hook' do
|
||||||
|
callable = Object.new.tap do |obj|
|
||||||
|
obj.instance_variable_set(:@test_var, nil)
|
||||||
|
class << obj
|
||||||
|
attr_accessor :test_var
|
||||||
|
def call() @test_var = true; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@hooks.add_hook(:test_hook, callable)
|
||||||
|
@hooks.exec_hook(:test_hook)
|
||||||
|
callable.test_var.should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should execute multiple callables for a hook if more than one is defined' do
|
||||||
|
x = nil
|
||||||
|
y = nil
|
||||||
|
@hooks.add_hook(:test_hook) { x = true }
|
||||||
|
@hooks.add_hook(:test_hook) { y = true }
|
||||||
|
@hooks.exec_hook(:test_hook)
|
||||||
|
x.should == true
|
||||||
|
y.should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1281,10 +1281,9 @@ describe Pry do
|
||||||
|
|
||||||
it 'should set the hooks default, and the default should be overridable' do
|
it 'should set the hooks default, and the default should be overridable' do
|
||||||
Pry.input = InputTester.new("exit-all")
|
Pry.input = InputTester.new("exit-all")
|
||||||
Pry.hooks = {
|
Pry.hooks = Pry::Hooks.new.
|
||||||
:before_session => proc { |out,_,_| out.puts "HELLO" },
|
add_hook(:before_session) { |out,_,_| out.puts "HELLO" }.
|
||||||
:after_session => proc { |out,_,_| out.puts "BYE" }
|
add_hook(:after_session) { |out,_,_| out.puts "BYE" }
|
||||||
}
|
|
||||||
|
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
Pry.new(:output => str_output).repl
|
Pry.new(:output => str_output).repl
|
||||||
|
@ -1295,10 +1294,9 @@ describe Pry do
|
||||||
|
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
Pry.new(:output => str_output,
|
Pry.new(:output => str_output,
|
||||||
:hooks => {
|
:hooks => Pry::Hooks.new.
|
||||||
:before_session => proc { |out,_,_| out.puts "MORNING" },
|
add_hook( :before_session) { |out,_,_| out.puts "MORNING" }.
|
||||||
:after_session => proc { |out,_,_| out.puts "EVENING" }
|
add_hook(:after_session) { |out,_,_| out.puts "EVENING" }
|
||||||
}
|
|
||||||
).repl
|
).repl
|
||||||
|
|
||||||
str_output.string.should =~ /MORNING/
|
str_output.string.should =~ /MORNING/
|
||||||
|
@ -1308,9 +1306,8 @@ describe Pry do
|
||||||
Pry.input.rewind
|
Pry.input.rewind
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
Pry.new(:output => str_output,
|
Pry.new(:output => str_output,
|
||||||
:hooks => {
|
:hooks => Pry::Hooks.new.
|
||||||
:before_session => proc { |out,_,_| out.puts "OPEN" }
|
add_hook(:before_session) { |out,_,_| out.puts "OPEN" }
|
||||||
}
|
|
||||||
).repl
|
).repl
|
||||||
|
|
||||||
str_output.string.should =~ /OPEN/
|
str_output.string.should =~ /OPEN/
|
||||||
|
@ -1318,9 +1315,8 @@ describe Pry do
|
||||||
Pry.input.rewind
|
Pry.input.rewind
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
Pry.new(:output => str_output,
|
Pry.new(:output => str_output,
|
||||||
:hooks => {
|
:hooks => Pry::Hooks.new.
|
||||||
:after_session => proc { |out,_,_| out.puts "CLOSE" }
|
add_hook(:after_session) { |out,_,_| out.puts "CLOSE" }
|
||||||
}
|
|
||||||
).repl
|
).repl
|
||||||
|
|
||||||
str_output.string.should =~ /CLOSE/
|
str_output.string.should =~ /CLOSE/
|
||||||
|
|
Loading…
Reference in a new issue