mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Add a wrapped module abstraction
This commit is contained in:
parent
d33991ae6a
commit
22ca4a8e13
3 changed files with 126 additions and 0 deletions
|
@ -179,6 +179,7 @@ require "pry/version"
|
|||
require "pry/rbx_method"
|
||||
require "pry/rbx_path"
|
||||
require "pry/method"
|
||||
require "pry/wrapped_module"
|
||||
require "pry/history_array"
|
||||
require "pry/helpers"
|
||||
require "pry/history"
|
||||
|
|
62
lib/pry/wrapped_module.rb
Normal file
62
lib/pry/wrapped_module.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
class Pry
|
||||
class WrappedModule
|
||||
|
||||
attr_reader :wrapped
|
||||
private :wrapped
|
||||
|
||||
# Create a new WrappedModule
|
||||
# @raise ArgumentError, if the argument is not a Module
|
||||
# @param [Module]
|
||||
def initialize(mod)
|
||||
raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod
|
||||
@wrapped = mod
|
||||
end
|
||||
|
||||
# The prefix that would appear before methods defined on this class.
|
||||
#
|
||||
# i.e. the "String." or "String#" in String.new and String#initialize.
|
||||
#
|
||||
# @return String
|
||||
def method_prefix
|
||||
if singleton_class?
|
||||
if Module === singleton_instance
|
||||
"#{singleton_instance.name}."
|
||||
else
|
||||
"self."
|
||||
end
|
||||
else
|
||||
"#{name}#"
|
||||
end
|
||||
end
|
||||
|
||||
# Is this a singleton class?
|
||||
# @return [Boolean]
|
||||
def singleton_class?
|
||||
wrapped != wrapped.ancestors.first
|
||||
end
|
||||
|
||||
# Get the instance associated with this singleton class.
|
||||
#
|
||||
# @raise ArgumentError: tried to get instance of non singleton class
|
||||
#
|
||||
# @return [Object]
|
||||
def singleton_instance
|
||||
raise ArgumentError, "tried to get instance of non singleton class" unless singleton_class?
|
||||
|
||||
if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/
|
||||
wrapped.to_java.attached
|
||||
else
|
||||
@singleton_instance ||= ObjectSpace.each_object(wrapped).detect{ |x| (class << x; self; end) == wrapped }
|
||||
end
|
||||
end
|
||||
|
||||
# Forward method invocations to the wrapped module
|
||||
def method_missing(method_name, *args, &block)
|
||||
wrapped.send(method_name, *args, &block)
|
||||
end
|
||||
|
||||
def respond_to?(method_name)
|
||||
super || wrapped.send(method_name, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
63
test/test_wrapped_module.rb
Normal file
63
test/test_wrapped_module.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
require 'helper'
|
||||
|
||||
describe Pry::WrappedModule do
|
||||
|
||||
describe "#initialize" do
|
||||
it "should raise an exception when a non-module is passed" do
|
||||
lambda{ Pry::WrappedModule.new(nil) }.should.raise ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
describe ".method_prefix" do
|
||||
before do
|
||||
Foo = Class.new
|
||||
@foo = Foo.new
|
||||
end
|
||||
|
||||
after do
|
||||
Object.remove_const(:Foo)
|
||||
end
|
||||
|
||||
it "should return Foo# for normal classes" do
|
||||
Pry::WrappedModule.new(Foo).method_prefix.should == "Foo#"
|
||||
end
|
||||
|
||||
it "should return Bar# for modules" do
|
||||
Pry::WrappedModule.new(Kernel).method_prefix.should == "Kernel#"
|
||||
end
|
||||
|
||||
it "should return Foo. for singleton classes of classes" do
|
||||
Pry::WrappedModule.new(class << Foo; self; end).method_prefix.should == "Foo."
|
||||
end
|
||||
|
||||
describe "of singleton classes of objects" do
|
||||
Pry::WrappedModule.new(class << @foo; self; end).method_prefix.should == "self."
|
||||
end
|
||||
end
|
||||
|
||||
describe ".singleton_class?" do
|
||||
it "should be true for singleton classes" do
|
||||
Pry::WrappedModule.new(class << ""; self; end).singleton_class?.should == true
|
||||
end
|
||||
|
||||
it "should be false for normal classes" do
|
||||
Pry::WrappedModule.new(Class.new).singleton_class?.should == false
|
||||
end
|
||||
|
||||
it "should be false for modules" do
|
||||
Pry::WrappedModule.new(Module.new).singleton_class?.should == false
|
||||
end
|
||||
end
|
||||
|
||||
describe ".singleton_instance" do
|
||||
it "should raise an exception when called on a non-singleton-class" do
|
||||
lambda{ Pry::WrappedModule.new(Class).singleton_instance }.should.raise ArgumentError
|
||||
end
|
||||
|
||||
it "should return the attached object" do
|
||||
Pry::WrappedModule.new(class << "hi"; self; end).singleton_instance.should == "hi"
|
||||
Pry::WrappedModule.new(class << Object; self; end).singleton_instance.should.equal?(Object)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue