1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

started code_object stuff

This commit is contained in:
John Mair 2012-12-19 12:16:05 +01:00
parent 4686de3d9b
commit bbd4df87d4
3 changed files with 210 additions and 0 deletions

View file

@ -248,3 +248,4 @@ require 'pry/pry_instance'
require 'pry/cli'
require 'pry/pager'
require 'pry/terminal_info'
require 'pry/code_object'

63
lib/pry/code_object.rb Normal file
View file

@ -0,0 +1,63 @@
class Pry
class CodeObject
class << self
def lookup(str, target, _pry_, options={})
co = new(str, target, _pry_, options)
co.other_object || co.method_or_class || co.command
end
end
attr_accessor :str
attr_accessor :target
attr_accessor :pry
attr_accessor :super_level
def initialize(str, target, _pry_, options={})
options = {
:super => 0
}.merge!(options)
@str = str
@target = target
@pry = _pry_
@super_level = options[:super]
end
def command
pry.commands[str]
end
def other_object
if target.eval("defined? #{str} ") =~ /variable|constant/
obj = target.eval(str)
if obj.respond_to?(:source_location)
Pry::Method(obj)
elsif !obj.is_a?(Module)
Pry::WrappedModule(obj.class)
else
nil
end
end
rescue Pry::RescuableException
nil
end
def method_or_class
obj = if str =~ /::(?:\S+)\Z/
Pry::WrappedModule.from_str(str,target) || Pry::Method.from_str(str, target)
else
Pry::Method.from_str(str,target) || Pry::WrappedModule.from_str(str, target)
end
sup = obj.super(super_level) if obj
if obj && !sup
raise ArgumentError, "No superclass found for #{obj.wrapped}"
else
sup
end
end
end
end

146
spec/code_object_spec.rb Normal file
View file

@ -0,0 +1,146 @@
require 'helper'
describe Pry::CodeObject do
describe "basic lookups" do
before do
@obj = Object.new
def @obj.ziggy
"a flight of scarlet pigeons thunders round my thoughts"
end
class ClassyWassy
def piggy
end
end
end
after do
Object.remove_const(:ClassyWassy)
end
it 'should lookup methods' do
m = Pry::CodeObject.lookup("@obj.ziggy", binding, Pry.new)
m.is_a?(Pry::Method).should == true
m.name.to_sym.should == :ziggy
end
it 'should lookup modules' do
m = Pry::CodeObject.lookup("ClassyWassy", binding, Pry.new)
m.is_a?(Pry::WrappedModule).should == true
m.source.should =~ /piggy/
end
it 'should lookup procs' do
my_proc = proc { :hello }
m = Pry::CodeObject.lookup("my_proc", binding, Pry.new)
m.is_a?(Pry::Method).should == true
m.source.should =~ /hello/
end
it 'should lookup commands' do
p = Pry.new
p.commands.command "jeremy-jones" do
"lobster"
end
m = Pry::CodeObject.lookup("jeremy-jones", binding, p)
(m <= Pry::Command).should == true
m.source.should =~ /lobster/
end
it 'should lookup the class of an object (when given a variable)' do
moddy = ClassyWassy.new
m = Pry::CodeObject.lookup("moddy", binding, Pry.new)
m.is_a?(Pry::WrappedModule).should == true
m.source.should =~ /piggy/
end
end
describe "lookups with :super" do
before do
class MyClassyWassy; end
class CuteSubclass < MyClassyWassy; end
end
after do
Object.remove_const(:MyClassyWassy)
Object.remove_const(:CuteSubclass)
end
it 'should lookup original class with :super => 0' do
m = Pry::CodeObject.lookup("CuteSubclass", binding, Pry.new, :super => 0)
m.is_a?(Pry::WrappedModule).should == true
m.wrapped.should == CuteSubclass
end
it 'should lookup immediate super class with :super => 1' do
m = Pry::CodeObject.lookup("CuteSubclass", binding, Pry.new, :super => 1)
m.is_a?(Pry::WrappedModule).should == true
m.wrapped.should == MyClassyWassy
end
it 'should ignore :super parameter for commands' do
p = Pry.new
p.commands.command "jeremy-jones" do
"lobster"
end
m = Pry::CodeObject.lookup("jeremy-jones", binding, p, :super => 10)
m.source.should =~ /lobster/
end
end
describe "precedence" do
before do
class ClassyWassy
class Puff
def tiggy
end
end
def Puff
end
def piggy
end
end
Object.class_eval do
def ClassyWassy
:ducky
end
end
end
after do
Object.remove_const(:ClassyWassy)
Object.remove_method(:ClassyWassy)
end
it 'should look up methods before classes (at top-level)' do
m = Pry::CodeObject.lookup("ClassyWassy", binding, Pry.new)
m.is_a?(Pry::Method).should == true
m.source.should =~ /ducky/
end
it 'should look up classes before methods when namespaced' do
m = Pry::CodeObject.lookup("ClassyWassy::Puff", binding, Pry.new)
m.is_a?(Pry::WrappedModule).should == true
m.source.should =~ /tiggy/
end
it 'should look up locals before methods' do
b = Pry.binding_for(ClassyWassy)
b.eval("piggy = Puff.new")
o = Pry::CodeObject.lookup("piggy", b, Pry.new)
o.is_a?(Pry::WrappedModule).should == true
end
# actually locals are never looked up (via co.other_object) when they're classes, it
# just falls through to co.method_or_class
it 'should look up classes before locals' do
c = ClassyWassy
o = Pry::CodeObject.lookup("c", binding, Pry.new)
o.is_a?(Pry::WrappedModule).should == true
o.wrapped.should == ClassyWassy
end
end
end