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