mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Allow use of hash-based hooks, but show warning.
* Shows a deprecation warning when used with a link to the new `Pry::Hooks` documentation. * When hash-based hooks are used they create anonymous hooks for the associated event. i.e Pry.hooks = { :before_session => proc { puts 'hi' } }, the 'name' of that hook is `nil`. * Anonymous hooks (nil-named) are different to ordinary hooks in that they dont raise an exception when user attempts to define another of the same name, they just silently overwrite previous one. This is to mimic the old hash-based behaviour. * Pry::Hooks[] and Pry::Hooks[]= are defined too, and they get and set the anonymous hook for the given event, i.e hooks[:before_session] = proc { "hi" } is equivalent to: hook.add_hook(:before_session, nil, proc { "hi" }) * Proc::Hook#[] and Pry::Hooks#[]= also display deprecation warnings.
This commit is contained in:
parent
7b2b4d6031
commit
3a4041cb24
4 changed files with 116 additions and 44 deletions
|
@ -49,10 +49,11 @@ class Pry
|
||||||
# @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
|
# @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
|
||||||
def hooks=(v)
|
def hooks=(v)
|
||||||
if v.is_a?(Hash)
|
if v.is_a?(Hash)
|
||||||
raise ObsoleteError, "Hash is now obsolete! Use a Pry::Hooks object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||||
|
@hooks = Pry::Hooks.from_hash(v)
|
||||||
|
else
|
||||||
|
@hooks = v
|
||||||
end
|
end
|
||||||
|
|
||||||
@hooks = v
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get/Set the stack of input objects that a Pry instance switches
|
# Get/Set the stack of input objects that a Pry instance switches
|
||||||
|
|
|
@ -1,6 +1,31 @@
|
||||||
class Pry
|
class Pry
|
||||||
|
|
||||||
|
# Implements a hooks system for Pry. A hook is a callable that is
|
||||||
|
# associated with an event. A number of events are currently
|
||||||
|
# provided by Pry, these include: `:when_started`, `:before_session`, `:after_session`.
|
||||||
|
# A hook must have a name, and is connected with an event by the
|
||||||
|
# `Pry::Hooks#add_hook` method.
|
||||||
|
# @example Adding a hook for the `:before_session` event.
|
||||||
|
# Pry.config.hooks.add_hook(:before_session, :say_hi) do
|
||||||
|
# puts "hello"
|
||||||
|
# end
|
||||||
class Hooks
|
class Hooks
|
||||||
|
|
||||||
|
# Converts a hash to a `Pry::Hooks` instance. All hooks defined
|
||||||
|
# this way are anonymous. This functionality is primarily to
|
||||||
|
# provide backwards-compatibility with the old hash-based hook
|
||||||
|
# system in Pry versions < 0.9.8
|
||||||
|
# @param [Hash] hash The hash to convert to `Pry::Hooks`.
|
||||||
|
# @return [Pry::Hooks] The resulting `Pry::Hooks` instance.
|
||||||
|
def self.from_hash(hash)
|
||||||
|
instance = new
|
||||||
|
hash.each do |k, v|
|
||||||
|
instance.add_hook(k, nil, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
instance
|
||||||
|
end
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@hooks = {}
|
@hooks = {}
|
||||||
end
|
end
|
||||||
|
@ -26,14 +51,18 @@ class Pry
|
||||||
|
|
||||||
# FIXME:
|
# FIXME:
|
||||||
# This is a hack to alert people of the new API.
|
# This is a hack to alert people of the new API.
|
||||||
def [](*)
|
def [](event_name)
|
||||||
raise ObsoleteError, "`Pry.hooks[]` is no longer supported. Please use the new Pry::Hooks API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
warn "`Pry.hooks[]` is deprecated! Please use the new `Pry::Hooks` API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||||
|
|
||||||
|
get_hook(event_name, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
# FIXME:
|
# FIXME:
|
||||||
# This is a hack to alert people of the new API.
|
# This is a hack to alert people of the new API.
|
||||||
def []=(*)
|
def []=(event_name, callable)
|
||||||
raise ObsoleteError, "`Pry.hooks[]=` is no longer supported. Please use the new Pry::Hooks API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
warn "`Pry.hooks[]=` is deprecated! Please use the new `Pry::Hooks` API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||||
|
|
||||||
|
add_hook(event_name, nil, callable)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Destructively merge the contents of two `Pry:Hooks` instances.
|
# Destructively merge the contents of two `Pry:Hooks` instances.
|
||||||
|
@ -85,15 +114,23 @@ class Pry
|
||||||
def add_hook(event_name, hook_name, callable=nil, &block)
|
def add_hook(event_name, hook_name, callable=nil, &block)
|
||||||
@hooks[event_name] ||= []
|
@hooks[event_name] ||= []
|
||||||
|
|
||||||
# do not allow duplicates
|
# do not allow duplicates, but allow multiple `nil` hooks
|
||||||
raise ArgumentError, "Hook with name '#{hook_name}' already defined!" if hook_exists?(event_name, hook_name)
|
# (anonymous hooks)
|
||||||
|
if hook_exists?(event_name, hook_name) && !hook_name.nil?
|
||||||
|
raise ArgumentError, "Hook with name '#{hook_name}' already defined!"
|
||||||
|
end
|
||||||
|
|
||||||
|
if !block && !callable
|
||||||
|
raise ArgumentError, "Must provide a block or callable."
|
||||||
|
end
|
||||||
|
|
||||||
|
# ensure we only have one anonymous hook
|
||||||
|
@hooks[event_name].delete_if { |h, k| h.nil? } if hook_name.nil?
|
||||||
|
|
||||||
if block
|
if block
|
||||||
@hooks[event_name] << [hook_name, block]
|
@hooks[event_name] << [hook_name, block]
|
||||||
elsif callable
|
elsif callable
|
||||||
@hooks[event_name] << [hook_name, callable]
|
@hooks[event_name] << [hook_name, callable]
|
||||||
else
|
|
||||||
raise ArgumentError, "Must provide a block or callable."
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self
|
self
|
||||||
|
@ -194,6 +231,15 @@ class Pry
|
||||||
|
|
||||||
alias_method :clear, :delete_hooks
|
alias_method :clear, :delete_hooks
|
||||||
|
|
||||||
|
# Remove all events and hooks, clearing out the Pry::Hooks
|
||||||
|
# instance completely.
|
||||||
|
# @example
|
||||||
|
# my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
|
||||||
|
# my_hooks.clear_all
|
||||||
|
def clear_all
|
||||||
|
@hooks = {}
|
||||||
|
end
|
||||||
|
|
||||||
# @param [Symbol] event_name Name of the event.
|
# @param [Symbol] event_name Name of the event.
|
||||||
# @param [Symbol] hook_name Name of the hook.
|
# @param [Symbol] hook_name Name of the hook.
|
||||||
# @return [Boolean] Whether the hook by the name `hook_name`
|
# @return [Boolean] Whether the hook by the name `hook_name`
|
||||||
|
|
|
@ -33,10 +33,11 @@ class Pry
|
||||||
# @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
|
# @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
|
||||||
def hooks=(v)
|
def hooks=(v)
|
||||||
if v.is_a?(Hash)
|
if v.is_a?(Hash)
|
||||||
raise ObsoleteError, "Error: Hash is now obsolete! Use a Pry::Hooks object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||||
|
@hooks = Pry::Hooks.from_hash(v)
|
||||||
|
else
|
||||||
|
@hooks = v
|
||||||
end
|
end
|
||||||
|
|
||||||
@hooks = v
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a new `Pry` object.
|
# Create a new `Pry` object.
|
||||||
|
|
|
@ -152,7 +152,7 @@ describe Pry::Hooks do
|
||||||
hooks_dup.get_hook(:test_hook, :testing).should == @hooks.get_hook(:test_hook, :testing)
|
hooks_dup.get_hook(:test_hook, :testing).should == @hooks.get_hook(:test_hook, :testing)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adding a new event to dupped instance should not affect original' do
|
it 'adding a new event to dupped instance should not affect original' do
|
||||||
@hooks.add_hook(:test_hook, :testing) { :none_such }
|
@hooks.add_hook(:test_hook, :testing) { :none_such }
|
||||||
hooks_dup = @hooks.dup
|
hooks_dup = @hooks.dup
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ describe Pry::Hooks do
|
||||||
hooks_dup.get_hook(:other_test_hook, :testing).should.not == @hooks.get_hook(:other_test_hook, :testing)
|
hooks_dup.get_hook(:other_test_hook, :testing).should.not == @hooks.get_hook(:other_test_hook, :testing)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adding a new hook to dupped instance should not affect original' do
|
it 'adding a new hook to dupped instance should not affect original' do
|
||||||
@hooks.add_hook(:test_hook, :testing) { :none_such }
|
@hooks.add_hook(:test_hook, :testing) { :none_such }
|
||||||
hooks_dup = @hooks.dup
|
hooks_dup = @hooks.dup
|
||||||
|
|
||||||
|
@ -417,50 +417,74 @@ describe Pry::Hooks do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "obsolete API" do
|
describe "anonymous hooks" do
|
||||||
describe "Pry.config.hooks" do
|
it 'should allow adding of hook without a name' do
|
||||||
it 'should raise a Pry::ObsoleteError when assigning a hash' do
|
@hooks.add_hook(:test_hook, nil) {}
|
||||||
begin
|
@hooks.hook_count(:test_hook).should == 1
|
||||||
Pry.config.hooks = {}
|
end
|
||||||
rescue => ex
|
|
||||||
end
|
|
||||||
|
|
||||||
ex.is_a?(Pry::ObsoleteError).should == true
|
it 'should only allow one anonymous hook to exist' do
|
||||||
|
@hooks.add_hook(:test_hook, nil) { }
|
||||||
|
@hooks.add_hook(:test_hook, nil) { }
|
||||||
|
@hooks.hook_count(:test_hook).should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should execute most recently added anonymous hook' do
|
||||||
|
x = nil
|
||||||
|
y = nil
|
||||||
|
@hooks.add_hook(:test_hook, nil) { y = 1 }
|
||||||
|
@hooks.add_hook(:test_hook, nil) { x = 2 }
|
||||||
|
@hooks.exec_hook(:test_hook)
|
||||||
|
y.should == nil
|
||||||
|
x.should == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "deprecated hash-based API" do
|
||||||
|
after do
|
||||||
|
Pry.config.hooks.clear_all if Pry.config.hooks
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Pry.config.hooks" do
|
||||||
|
it 'should allow a hash-assignment' do
|
||||||
|
Pry.config.hooks = { :before_session => proc { :hello } }
|
||||||
|
Pry.config.hooks.get_hook(:before_session, nil).call.should == :hello
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Pry.config.hooks[]" do
|
describe "Pry.config.hooks[]" do
|
||||||
it 'should raise a Pry::ObsoleteError when accessing it in a hash style, Pry.config.hooks[]' do
|
it 'should return the only anonymous hook' do
|
||||||
begin
|
Pry.config.hooks = { :before_session => proc { :hello } }
|
||||||
Pry.config.hooks[:before_session]
|
Pry.config.hooks[:before_session].call.should == :hello
|
||||||
rescue => ex
|
|
||||||
end
|
|
||||||
|
|
||||||
ex.is_a?(Pry::ObsoleteError).should == true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should raise a Pry::ObsoleteError when accessing it in a hash style, Pry.config.hooks[]=' do
|
it 'should add an anonymous hook when using Pry.config.hooks[]=' do
|
||||||
begin
|
Pry.config.hooks[:before_session] = proc { :bing }
|
||||||
Pry.config.hooks[:before_session]
|
Pry.config.hooks.hook_count(:before_session).should == 1
|
||||||
rescue => ex
|
|
||||||
end
|
|
||||||
|
|
||||||
ex.is_a?(Pry::ObsoleteError).should == true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should add overwrite previous anonymous hooks with new one when calling Pry.config.hooks[]= multiple times' do
|
||||||
|
x = nil
|
||||||
|
Pry.config.hooks[:before_session] = proc { x = 1 }
|
||||||
|
Pry.config.hooks[:before_session] = proc { x = 2 }
|
||||||
|
|
||||||
|
Pry.config.hooks.exec_hook(:before_session)
|
||||||
|
Pry.config.hooks.hook_count(:before_session).should == 1
|
||||||
|
x.should == 2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Pry.start" do
|
describe "Pry.start" do
|
||||||
it 'should raise a Pry::ObsoleteError when passing in a :hooks option with a hash' do
|
it 'should accept a hash for :hooks parameter' do
|
||||||
begin
|
|
||||||
Pry.start binding, :hooks => { :before_session => proc { puts 'yo' } }
|
redirect_pry_io(InputTester.new("exit-all"), out=StringIO.new) do
|
||||||
rescue => ex
|
Pry.start binding, :hooks => { :before_session => proc { |output, _, _| output.puts 'hello friend' } }
|
||||||
end
|
end
|
||||||
|
|
||||||
ex.is_a?(Pry::ObsoleteError).should == true
|
out.string.should =~ /hello friend/
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue