perception 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/0 start all Tests.bat +20 -0
- data/History.txt +4 -0
- data/License.txt +21 -0
- data/Manifest.txt +29 -0
- data/PostInstall.txt +6 -0
- data/README.txt +55 -0
- data/Rakefile.rb +127 -0
- data/demo/demo_pp.rb +163 -0
- data/demo/demo_zz.rb +332 -0
- data/init.rb +2 -0
- data/lib/perception/const.rb +78 -0
- data/lib/perception/date_and_time.rb +78 -0
- data/lib/perception/logging.rb +123 -0
- data/lib/perception/numeric.rb +194 -0
- data/lib/perception/perception_main.rb +317 -0
- data/lib/perception/perception_private.rb +231 -0
- data/lib/perception/ppp.rb +377 -0
- data/lib/perception/string_spread.rb +155 -0
- data/lib/perception/test.rb +114 -0
- data/lib/perception.rb +36 -0
- data/test/_start_all.rb +10 -0
- data/test/test_date_and_time.rb +54 -0
- data/test/test_numeric.rb +104 -0
- data/test/test_ppp.rb +297 -0
- data/website/index.html +11 -0
- data/website/index.txt +83 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +119 -0
@@ -0,0 +1,231 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'perception' ) if $0 == __FILE__
|
3
|
+
|
4
|
+
module Perception #:nodoc
|
5
|
+
|
6
|
+
|
7
|
+
# Eine SeeSession-Instanz entspricht einer Session mit der Konsole.
|
8
|
+
class SeeSession
|
9
|
+
@@instance = nil
|
10
|
+
attr_accessor :time_last, :delayed_newlines, :level, :indent, :out
|
11
|
+
|
12
|
+
# ------------------------------------------------------------------------------
|
13
|
+
# Verwalten
|
14
|
+
#
|
15
|
+
|
16
|
+
# Liefert die eine notwendige Instanz
|
17
|
+
def self.instance
|
18
|
+
return @@instance if @@instance
|
19
|
+
@@instance = SeeSession.new
|
20
|
+
@@instance
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
init
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def init
|
30
|
+
# früher
|
31
|
+
@string_last = '' # enthält den letzten ausgegebenen String (damit man ihn löschen und wiederherstellen kann)
|
32
|
+
@time_last = nil # enthält den Zeitpunkt des letzten Prints
|
33
|
+
@method_last = nil # enthält die Methode, mit der der letzte String geprinted wurde
|
34
|
+
@call_stack_last = 0 # Wie lang war der Stack beim letzten #see?
|
35
|
+
|
36
|
+
# jetzt
|
37
|
+
@speed = nil # nil = unverzögert, 1= lesbar, 2 = lesbar / doppelt so schnell, 0.5 = lesbar / halb so schnell
|
38
|
+
@cursor_now = 0 # enthält die aktuelle Position des Cursors
|
39
|
+
@method_now = nil # mit welcher Methode wird der aktuelle Print ausgeführt?
|
40
|
+
@call_stack_now = 0 # Wie lang ist der Stack beim aktuellen #see?
|
41
|
+
@indent = SEE_INDENT_START # sollen die Prints automatisch eingerückt werden?
|
42
|
+
@level = SEE_LEVEL_START # aktueller Einrückungslevel
|
43
|
+
|
44
|
+
# nächstes
|
45
|
+
@delayed_newlines = 1 # Mit wie vielen Newline-Zeichen soll der nächste Print beginnen? (Newlines werden verzögert, damit man noch löschen kann)
|
46
|
+
@delayed_clear = false # Soll der nächste Print den vorhergehenden überschreiben?
|
47
|
+
|
48
|
+
@logger = nil # wird erst bei Bedarf erzeugt
|
49
|
+
@out = Set.new # Wohin geht der Output? , :log
|
50
|
+
@out << :console
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
# ------------------------------------------------------------------------------
|
59
|
+
# Ausgeben
|
60
|
+
#
|
61
|
+
|
62
|
+
def wait!(string_akt)
|
63
|
+
return unless @time_last
|
64
|
+
verstrichene_zeit = Time.now - @time_last
|
65
|
+
alter_string = @string_last.strip.chomp.scan(/\w+/)
|
66
|
+
neuer_string = string_akt.strip.chomp.scan(/\w+/)
|
67
|
+
differenz_information = Math.sqrt((alter_string - neuer_string).size + 0.3 )
|
68
|
+
time_for_perception = (differenz_information * SEE_PERCEPTION_TIME_PER_WORD * @speed ) / 1000
|
69
|
+
if verstrichene_zeit < time_for_perception
|
70
|
+
sleep (time_for_perception - verstrichene_zeit)
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end # wait
|
74
|
+
|
75
|
+
|
76
|
+
def adjust_level
|
77
|
+
@call_stack_now = caller.size
|
78
|
+
call_stack_diff = @call_stack_now - @call_stack_last
|
79
|
+
# puts "call_stack_diff=#{ call_stack_diff }"
|
80
|
+
# puts
|
81
|
+
if @indent
|
82
|
+
if call_stack_diff > 0 && @call_stack_last != 0
|
83
|
+
@level += 1
|
84
|
+
elsif call_stack_diff < 0 && @level > 1
|
85
|
+
@level -= 1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def clear_indent!
|
93
|
+
@call_stack_last = 0 # wie direkt nach der Initialisierung
|
94
|
+
@call_stack_now = 0
|
95
|
+
@level = SEE_LEVEL_START
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
# Gibt das see aus
|
104
|
+
def process_print( input, options={} )
|
105
|
+
|
106
|
+
# vorbereiten
|
107
|
+
@method_now = options[:method] || :puts
|
108
|
+
self.clear! if @delayed_clear
|
109
|
+
self.adjust_level
|
110
|
+
newlines = self.process_newline if @delayed_newlines > 0
|
111
|
+
|
112
|
+
# ausgeben
|
113
|
+
case @method_now
|
114
|
+
|
115
|
+
when :puts
|
116
|
+
result = input.inspect_or_to_s
|
117
|
+
self.wait!(result) if @speed
|
118
|
+
printout(result)
|
119
|
+
@delayed_newlines += 1 # das newline wird erst später eingefügt
|
120
|
+
|
121
|
+
when :pp
|
122
|
+
result = input.inspect_see
|
123
|
+
self.wait!(result) if @speed
|
124
|
+
printout(result)
|
125
|
+
@delayed_newlines += 1 # und das newline später eingefügt
|
126
|
+
|
127
|
+
when :print
|
128
|
+
result = input.inspect_or_to_s
|
129
|
+
self.wait!(result) if @speed
|
130
|
+
printout(result)
|
131
|
+
|
132
|
+
when :multi
|
133
|
+
result = ''
|
134
|
+
result = PPP::pp(input, result, 200) # normal prettyprint
|
135
|
+
result = PPP.beautify_multi(result)
|
136
|
+
self.wait!(result) if @speed
|
137
|
+
printout(result)
|
138
|
+
@delayed_newlines += 1 # und das newline später eingefügt
|
139
|
+
|
140
|
+
end # case
|
141
|
+
|
142
|
+
# verwalten
|
143
|
+
@string_last = result.dup
|
144
|
+
@time_last = Time.now
|
145
|
+
@method_last = @method_now
|
146
|
+
@call_stack_last = @call_stack_now
|
147
|
+
return (newlines ||'') + result
|
148
|
+
end # def
|
149
|
+
|
150
|
+
|
151
|
+
# Führt die aufgeschobenen Newlines aus. Ohne Berücksichtigung der Zeit.
|
152
|
+
def process_newline
|
153
|
+
result = "\n" * @delayed_newlines
|
154
|
+
self.clear! if @delayed_clear
|
155
|
+
printout(result)
|
156
|
+
@delayed_newlines = 0
|
157
|
+
return result
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
def printout(string, backward=nil)
|
162
|
+
if @out.include?(:console)
|
163
|
+
spacer = (' '*SEE_TAB_WIDTH * @level)
|
164
|
+
outputstring = string.gsub(/\n/, ("\n" + spacer) )
|
165
|
+
Kernel.print(spacer) if @cursor_now == 0
|
166
|
+
Kernel.print(outputstring)
|
167
|
+
end
|
168
|
+
if @out.include?(:log)
|
169
|
+
# spacer = seee.bench.inspect_see + (' '*SEE_TAB_WIDTH * @level) + ' '
|
170
|
+
spacer = ''
|
171
|
+
outputstring = string.gsub(/\n/, ("\n" + spacer) )
|
172
|
+
logger << (spacer) if @cursor_now == 0
|
173
|
+
logger << (outputstring)
|
174
|
+
end
|
175
|
+
|
176
|
+
# TODO: \n berücksichtigen
|
177
|
+
unless backward
|
178
|
+
@cursor_now += outputstring.size
|
179
|
+
else
|
180
|
+
@cursor_now -= backward
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
end # class
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
end # module
|
196
|
+
|
197
|
+
|
198
|
+
class Object
|
199
|
+
|
200
|
+
# Liefert entweder inspect oder to_s, je nach Klassenzugehörigkeit
|
201
|
+
# Explizite Typabfrage ohne duck typing!
|
202
|
+
def inspect_or_to_s
|
203
|
+
return 'empty' if self == ''
|
204
|
+
return self.to_s if self.class == String
|
205
|
+
return self.inspect_see if self.class == Time
|
206
|
+
return self.inspect_see if self.kind_of?(Numeric)
|
207
|
+
return self.inspect_see if self.kind_of?(Set)
|
208
|
+
return self.inspect
|
209
|
+
end
|
210
|
+
|
211
|
+
end # class
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
# -----------------------------------------------------------------------------------------
|
221
|
+
# ausprobieren
|
222
|
+
#
|
223
|
+
if $0 == __FILE__ then
|
224
|
+
|
225
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'demo', 'demo_pp' )
|
226
|
+
Perception::DemoSee.see_all_demos
|
227
|
+
|
228
|
+
end # if
|
229
|
+
|
230
|
+
|
231
|
+
|
@@ -0,0 +1,377 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'perception' ) if $0 == __FILE__
|
3
|
+
|
4
|
+
class PPP < PP
|
5
|
+
|
6
|
+
|
7
|
+
# ------------------------------------------------------------------------------
|
8
|
+
#
|
9
|
+
#
|
10
|
+
|
11
|
+
def self.pp(obj, out=$>, width=79 )
|
12
|
+
q = PPP.new(out, width, "\n")
|
13
|
+
q.guard_inspect_key {q.pp(obj)}
|
14
|
+
q.flush
|
15
|
+
#$pp = q
|
16
|
+
out
|
17
|
+
end
|
18
|
+
|
19
|
+
# sorgt dafür, dass Listen länger als 3 Elemente untereinander ausgegeben werden
|
20
|
+
def seplist(list, sep=nil, iter_method=:each) # :yield: element
|
21
|
+
sep = lambda { comma_newline } if (sep.kind_of?(Integer) && list.size > sep )
|
22
|
+
sep = lambda { comma_breakable } if (sep.nil? || sep.kind_of?(Integer))
|
23
|
+
first = true
|
24
|
+
list.__send__(iter_method) {|*v|
|
25
|
+
if first
|
26
|
+
first = false
|
27
|
+
else
|
28
|
+
sep.call
|
29
|
+
end
|
30
|
+
yield(*v)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def comma_newline
|
35
|
+
text ","
|
36
|
+
breakable('',9999)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Hashes mit mehr als drei Keys werden untereinander dargestellt
|
41
|
+
def pp_hash(obj)
|
42
|
+
group(1, '{', '}') {
|
43
|
+
seplist(obj, 3, :each_pair) {|k, v|
|
44
|
+
group {
|
45
|
+
pp k
|
46
|
+
text '=>'
|
47
|
+
group(1) {
|
48
|
+
breakable ''
|
49
|
+
pp v
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
# ------------------------------------------------------------------------------
|
60
|
+
#
|
61
|
+
#
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
# Nachbearbeitung des PrettyPrint-Results
|
67
|
+
def self.beautify(string)
|
68
|
+
begin
|
69
|
+
result = string# .gsub!("`","'")
|
70
|
+
result = beautify_focus_level1(result)
|
71
|
+
case classify_structure(string)
|
72
|
+
when :object then result = beautify_object(result)
|
73
|
+
when :hash then result = beautify_hash(result)
|
74
|
+
when :array_1dim then result = beautify_array_1dim(result)
|
75
|
+
when :array_2dim then result = beautify_array_2dim(result)
|
76
|
+
end
|
77
|
+
return result
|
78
|
+
# rescue
|
79
|
+
# return string
|
80
|
+
end
|
81
|
+
end # def
|
82
|
+
|
83
|
+
|
84
|
+
# Klassifiziert die Struktur eines Objektes für die Ausgabe
|
85
|
+
def self.classify_structure(object)
|
86
|
+
|
87
|
+
# Hash
|
88
|
+
return :hash if object =~ /^\{.*=>.*\}/m
|
89
|
+
|
90
|
+
# Object
|
91
|
+
return :object if object =~ /^#<.*>$/m
|
92
|
+
|
93
|
+
# Eindimensionales Array
|
94
|
+
# oder Objekt, das sich wie ein Array ausdruckt -- vor der eckigen Klammer ist ein Identifier erlaubt, z.B. WP[ 1, 2, 3]
|
95
|
+
return :array_1dim if object =~ /^[A-Z_0-9a-z]{0,30}\[[^\[].*[^\]]\]$/m
|
96
|
+
|
97
|
+
# Zweidimensionales Array
|
98
|
+
# Anfang prüfen: Zwei eckige Klammern auf, danach keine eckige Klammer auf
|
99
|
+
# oder alternativ ein Text zwischen den beiden Klammern auf
|
100
|
+
return :array_2dim if object =~ /^\[[A-Z_0-9a-z]{0,30}\[[^\[]/m
|
101
|
+
#return self unless object =~ /[^\]]\]\]$/ # Ende prüfen: Zwei eckige Klammern zu, davor keine eckige Klammer zu
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
# Level 2+ : nur noch eine Zeile
|
108
|
+
# Level 3+ : komplexe Objekte zusammenkürzen
|
109
|
+
def self.beautify_focus_level1(string)
|
110
|
+
#return string
|
111
|
+
replaces = [[/\n/, ''], [/ {2,}/,' ']]
|
112
|
+
result = string
|
113
|
+
result = string.mask( :level_start => 2 ) { |s| s.mgsub(replaces)}
|
114
|
+
result = result.mask( :level_start => 3 ) { |s| (s =~ /@.*=.*/ ? '' : s) }
|
115
|
+
return result
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
# Object
|
121
|
+
def self.beautify_object(string)
|
122
|
+
result = string
|
123
|
+
result.gsub!(/= *\n */m, '=' ) # unnötigen Zeilenumbruch vermeiden
|
124
|
+
result = result.mask( :level_start => 1,
|
125
|
+
:level_end => 1,
|
126
|
+
:pattern => /</ ) { |s| s.gsub(/=/, ' = ')}
|
127
|
+
replaces = [ [/ @/, ' @'], [/= #/,'=#'] ] # Unterobjekte formatieren
|
128
|
+
result = result.mask( :level_start => 2,
|
129
|
+
:level_end => 2 ) { |s| s.mgsub(replaces)}
|
130
|
+
result = result.mask( :level_start => 4 ) { |s| ''}
|
131
|
+
|
132
|
+
tabstops = result.analyze_columns( :level_start => 0,
|
133
|
+
:level_end => 0,
|
134
|
+
:search => '=' ) || [25]
|
135
|
+
tabstops2 = []
|
136
|
+
tabstops2 << tabstops[0]
|
137
|
+
tabstops2 << tabstops[0] + 5
|
138
|
+
|
139
|
+
result = result.spread( :level_start => 1,
|
140
|
+
:level_end => 1,
|
141
|
+
:search => /=[^>=]/,
|
142
|
+
:position_add => 1, # alle '=' links
|
143
|
+
:tabstops => tabstops2 )
|
144
|
+
|
145
|
+
result
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
# Hash
|
151
|
+
def self.beautify_hash(string)
|
152
|
+
result = string
|
153
|
+
result.gsub!(/=> *\n */m, '=>' ) # unnötigen Zeilenumbruch vermeiden
|
154
|
+
|
155
|
+
# mehrzeilige Darstellung
|
156
|
+
if result.include?("\n")
|
157
|
+
result = string.mask( :level_start => 1,
|
158
|
+
:level_end => 1,
|
159
|
+
:pattern => /\{/ ) { |s| s.gsub(/=>/, ' =>')}
|
160
|
+
|
161
|
+
# Pfeil retten
|
162
|
+
result = result.mask( :level_start => 2,
|
163
|
+
:pattern => /\{/ ) { |s| s.gsub('=>', Perception::PPP_PFEIL)}
|
164
|
+
|
165
|
+
# Unterobjekte formatieren
|
166
|
+
replaces = [ [/, /,', '] ]
|
167
|
+
result = result.mask( :level_start => 2,
|
168
|
+
:level_end => 2 ) { |s| s.mgsub(replaces)}
|
169
|
+
|
170
|
+
# Tiefere Level retten
|
171
|
+
result = result.mask( :level_start => 1,
|
172
|
+
:with_brackets => true,
|
173
|
+
:pattern => /\{/
|
174
|
+
) { |s| s.tr(Perception::PPP_TR_ARRAY_P[0..5], Perception::PPP_TR_ARRAY_Q)}
|
175
|
+
|
176
|
+
tabstops = result.analyze_columns( :level_start => 0,
|
177
|
+
:level_end => 0,
|
178
|
+
:search => '=' ) || [25]
|
179
|
+
tabstops2 = []
|
180
|
+
tabstops2 << tabstops[0] + 1
|
181
|
+
tabstops2 << tabstops[0] + 5
|
182
|
+
|
183
|
+
# ausrichten
|
184
|
+
result = result.spread( :level_start => 1,
|
185
|
+
:level_end => 1,
|
186
|
+
:search => /=>/,
|
187
|
+
:position_add => 0, # alle '=>' übereinander
|
188
|
+
:tabstops => tabstops2 )
|
189
|
+
result.gsub!('=>','=> ')
|
190
|
+
|
191
|
+
# Tiefere Level zurück
|
192
|
+
result = result.mask( :level_start => 1,
|
193
|
+
:with_brackets => true,
|
194
|
+
:pattern => /\{/
|
195
|
+
) { |s| s.tr(Perception::PPP_TR_ARRAY_Q, Perception::PPP_TR_ARRAY_R)}
|
196
|
+
|
197
|
+
# Pfeil zurück
|
198
|
+
result = result.mask( :level_start => 2,
|
199
|
+
:pattern => /\{/ ) { |s| s.gsub(Perception::PPP_PFEIL, '=>')}
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
# einzeilige Darstellung
|
204
|
+
else
|
205
|
+
result = string.mask( :level_start => 1,
|
206
|
+
:level_end => 1,
|
207
|
+
:pattern => /\{/ ) { |s| s.gsub(/, /, ', ')}
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
result
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
# Eindimensionales Array
|
217
|
+
# oder Objekt, das sich wie ein Array ausdruckt -- vor der eckigen Klammer ist ein Identifier erlaubt, z.B. WP[ 1, 2, 3]
|
218
|
+
def self.beautify_array_1dim(string)
|
219
|
+
return string
|
220
|
+
# tabstops = result[1..-2].analyze_columns( :level_start => 0,
|
221
|
+
# :level_end => 0,
|
222
|
+
# :search => ',',
|
223
|
+
# :stretch => 0 )
|
224
|
+
# tabstops = [25] if tabstops.empty?
|
225
|
+
# maxtab = tabstops.sort[-1]
|
226
|
+
|
227
|
+
|
228
|
+
# result = result.spread( :level_start => 1,
|
229
|
+
# :level_end => 1,
|
230
|
+
# :tabstops => (1..10).collect {|i| i * (maxtab+1)},
|
231
|
+
# :search => ',',
|
232
|
+
# :position_add => 1 )
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
# Zweidimensionales Array
|
238
|
+
# very hackish
|
239
|
+
def self.beautify_array_2dim(string)
|
240
|
+
result = string
|
241
|
+
|
242
|
+
# Komma retten
|
243
|
+
result = result.mask( :level_start => 3,
|
244
|
+
:pattern => /['"({<\[]/
|
245
|
+
) { |s| s.tr(',', Perception::PPP_KOMMA)}
|
246
|
+
|
247
|
+
# Tiefere Level retten
|
248
|
+
result = result.mask( :level_start => 2,
|
249
|
+
:with_brackets => true,
|
250
|
+
:pattern => /\[/
|
251
|
+
) { |s| s.tr(Perception::PPP_TR_ARRAY_P, Perception::PPP_TR_ARRAY_Q)}
|
252
|
+
|
253
|
+
# zeilenweise
|
254
|
+
replaces = [[/,[^\n]/, ", \n "]]
|
255
|
+
result = result.mask( :level_start => 1,
|
256
|
+
:level_end => 1,
|
257
|
+
:pattern => /\[/
|
258
|
+
) { |s| s.mgsub(replaces)}
|
259
|
+
|
260
|
+
# Tabstops
|
261
|
+
tabstops = result[1..-2].analyze_columns( :level_start => 1,
|
262
|
+
:level_end => 1,
|
263
|
+
:search => ',',
|
264
|
+
:stretch => 1 ) || [25]
|
265
|
+
tabstops2 = []
|
266
|
+
tabstops.each do |t|
|
267
|
+
tabstops2 << t + (tabstops2[-1]||0)
|
268
|
+
end
|
269
|
+
|
270
|
+
# ausrichten
|
271
|
+
result = result.spread( :level_start => 2,
|
272
|
+
:level_end => 2,
|
273
|
+
:tabstops => tabstops2,
|
274
|
+
:search => /,/ )
|
275
|
+
|
276
|
+
# Tiefere Level zurück
|
277
|
+
result = result.mask( :level_start => 2,
|
278
|
+
:with_brackets => true,
|
279
|
+
:pattern => /\[/
|
280
|
+
) { |s| s.tr(Perception::PPP_TR_ARRAY_Q, Perception::PPP_TR_ARRAY_R)}
|
281
|
+
|
282
|
+
#Komma zurück
|
283
|
+
result = result.mask( :level_start => 3,
|
284
|
+
:pattern => /['"({<\[]/
|
285
|
+
) { |s| s.gsub(Perception::PPP_KOMMA, ',')}
|
286
|
+
|
287
|
+
return result
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
# Mehrere Ausgaben in einer Zeile.
|
293
|
+
# Die einzelnen Ausgaben liegen als Array vor.
|
294
|
+
# Das Ergebnis soll aber nicht wie ein Array ausssehen.
|
295
|
+
def self.beautify_multi(string)
|
296
|
+
result = string
|
297
|
+
result = beautify_focus_level1(result)
|
298
|
+
result = result.mask( :level_start => 1,
|
299
|
+
:level_end => 1,
|
300
|
+
:pattern => /\[/
|
301
|
+
) {|s| s.tr(',', Perception::PPP_KOMMA)}
|
302
|
+
result = result.spread_line( [25], Perception::PPP_KOMMA, 0 )
|
303
|
+
|
304
|
+
# Äußeres Array entfernen
|
305
|
+
result = result.tr(Perception::PPP_TR_ALL,'')
|
306
|
+
result = result.mask( :with_brackets => true,
|
307
|
+
:level_start => 0,
|
308
|
+
:level_end => 0,
|
309
|
+
:pattern => /\[/
|
310
|
+
) {|s| s.tr('[]','')}
|
311
|
+
return result
|
312
|
+
end # def
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
end # class
|
321
|
+
|
322
|
+
|
323
|
+
class String
|
324
|
+
def pretty_print(q)
|
325
|
+
q.text "'#{self}'"
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
class Set
|
330
|
+
def pretty_print(q)
|
331
|
+
q.group(1, '{', '}') {
|
332
|
+
q.seplist(self) {|v|
|
333
|
+
q.pp v
|
334
|
+
}
|
335
|
+
}
|
336
|
+
end
|
337
|
+
|
338
|
+
def pretty_print_cycle(q)
|
339
|
+
q.text(empty? ? '{}' : '{...}')
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
class Dictionary
|
345
|
+
def inspect
|
346
|
+
ary = []
|
347
|
+
each {|k,v| ary << k.inspect + "=>" + v.inspect}
|
348
|
+
'{' + ary.join(", ") + '}'
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
|
353
|
+
class Dictionary
|
354
|
+
def pretty_print(q)
|
355
|
+
q.pp_hash self
|
356
|
+
end
|
357
|
+
|
358
|
+
def pretty_print_cycle(q)
|
359
|
+
q.text(empty? ? '{}' : '{...}')
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
|
368
|
+
|
369
|
+
|
370
|
+
# -----------------------------------------------------------------------------------------
|
371
|
+
# Tests
|
372
|
+
#
|
373
|
+
if $0 == __FILE__ then
|
374
|
+
|
375
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test', 'test_ppp' )
|
376
|
+
|
377
|
+
end # if
|