1#
2#   irb/inspector.rb - inspect methods
3#   	$Release Version: 0.9.6$
4#   	$Revision: 1.19 $
5#   	$Date: 2002/06/11 07:51:31 $
6#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
7#
8# --
9#
10#
11#
12
13module IRB # :nodoc:
14
15
16  # Convenience method to create a new Inspector, using the given +inspect+
17  # proc, and optional +init+ proc and passes them to Inspector.new
18  #
19  #     irb(main):001:0> ins = IRB::Inspector(proc{ |v| "omg! #{v}" })
20  #     irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! #<IRB::Inspector:0x007f46f7ba7d28>
21  #     irb(main):001:0> "what?" #=> omg! what?
22  #
23  def IRB::Inspector(inspect, init = nil)
24    Inspector.new(inspect, init)
25  end
26
27  # An irb inspector
28  #
29  # In order to create your own custom inspector there are two things you
30  # should be aware of:
31  #
32  # Inspector uses #inspect_value, or +inspect_proc+, for output of return values.
33  #
34  # This also allows for an optional #init+, or +init_proc+, which is called
35  # when the inspector is activated.
36  #
37  # Knowing this, you can create a rudimentary inspector as follows:
38  #
39  #     irb(main):001:0> ins = IRB::Inspector.new(proc{ |v| "omg! #{v}" })
40  #     irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! #<IRB::Inspector:0x007f46f7ba7d28>
41  #     irb(main):001:0> "what?" #=> omg! what?
42  #
43  class Inspector
44    # Default inspectors available to irb, this includes:
45    #
46    # +:pp+::       Using Kernel#pretty_inspect
47    # +:yaml+::     Using YAML.dump
48    # +:marshal+::  Using Marshal.dump
49    INSPECTORS = {}
50
51    # Determines the inspector to use where +inspector+ is one of the keys passed
52    # during inspector definition.
53    def self.keys_with_inspector(inspector)
54      INSPECTORS.select{|k,v| v == inspector}.collect{|k, v| k}
55    end
56
57    # Example
58    #
59    #     Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
60    #     Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
61    #     Inspector.def_inspector(key, inspector)
62    #     Inspector.def_inspector([key1,...], inspector)
63    def self.def_inspector(key, arg=nil, &block)
64  #     if !block_given?
65  #       case arg
66  #       when nil, Proc
67  # 	inspector = IRB::Inspector(init_p)
68  #       when Inspector
69  # 	inspector = init_p
70  #       else
71  # 	IRB.Raise IllegalParameter, init_p
72  #       end
73  #       init_p = nil
74  #     else
75  #       inspector = IRB::Inspector(block, init_p)
76  #     end
77
78      if block_given?
79        inspector = IRB::Inspector(block, arg)
80      else
81        inspector = arg
82      end
83
84      case key
85      when Array
86        for k in key
87          def_inspector(k, inspector)
88        end
89      when Symbol
90        INSPECTORS[key] = inspector
91        INSPECTORS[key.to_s] = inspector
92      when String
93        INSPECTORS[key] = inspector
94        INSPECTORS[key.intern] = inspector
95      else
96        INSPECTORS[key] = inspector
97      end
98    end
99
100    # Creates a new inspector object, using the given +inspect_proc+ when
101    # output return values in irb.
102    def initialize(inspect_proc, init_proc = nil)
103      @init = init_proc
104      @inspect = inspect_proc
105    end
106
107    # Proc to call when the inspector is activated, good for requiring
108    # dependant libraries.
109    def init
110      @init.call if @init
111    end
112
113    # Proc to call when the input is evaluated and output in irb.
114    def inspect_value(v)
115      @inspect.call(v)
116    end
117  end
118
119  Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
120  Inspector.def_inspector([true, :p, :inspect]){|v|
121    begin
122      v.inspect
123    rescue NoMethodError
124      puts "(Object doesn't support #inspect)"
125    end
126  }
127  Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v| v.pretty_inspect.chomp}
128  Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
129    begin
130      YAML.dump(v)
131    rescue
132      puts "(can't dump yaml. use inspect)"
133      v.inspect
134    end
135  }
136
137  Inspector.def_inspector([:marshal, :Marshal, :MARSHAL, Marshal]){|v|
138    Marshal.dump(v)
139  }
140end
141
142
143
144
145
146