module PP::PPMethods
为 pretty_print 定义辅助方法的模块。
Public Instance Methods
Source
# File lib/pp.rb, line 161 def check_inspect_key(id) recursive_state = Thread.current[:__recursive_key__] or return false recursive_state[:inspect]&.include?(id) end
检查对象 ID id 是否在当前将被 pretty print 的对象缓冲区中。用于打破对象链中的循环,这些对象将被 pretty print。
Source
# File lib/pp.rb, line 238 def comma_breakable text ',' breakable end
一个方便的方法,它与以下方法相同
text ',' breakable
Source
# File lib/pp.rb, line 147 def guard_inspect_key recursive_state = Thread.current[:__recursive_key__] ||= {}.compare_by_identity save = recursive_state[:inspect] ||= {}.compare_by_identity begin recursive_state[:inspect] = {}.compare_by_identity yield ensure recursive_state[:inspect] = save end end
会屈服于一个块,并保留之前正在打印的对象集。
Source
# File lib/pp.rb, line 228 def object_address_group(obj, &block) str = Kernel.instance_method(:to_s).bind_call(obj) str.chomp!('>') group(1, str, '>', &block) end
一个方便的方法,类似于 object_group,但还会重新格式化 Object 的 object_id。
Source
# File lib/pp.rb, line 222 def object_group(obj, &block) # :yield: group(1, '#<' + obj.class.name, '>', &block) end
一个方便的方法,它与以下方法相同
group(1, '#<' + obj.class.name, '>') { ... }
Source
# File lib/pp.rb, line 173 def pop_inspect_key(id) Thread.current[:__recursive_key__][:inspect].delete id end
从正在 pretty print 的对象集中移除一个对象。
Source
# File lib/pp.rb, line 200 def pp(obj) # If obj is a Delegator then use the object being delegated to for cycle # detection obj = obj.__getobj__ if defined?(::Delegator) and ::Delegator === obj if check_inspect_key(obj) group {obj.pretty_print_cycle self} return end guard_inspect(obj) do group do obj.pretty_print self rescue NoMethodError text Kernel.instance_method(:inspect).bind_call(obj) end end end
使用 Object#pretty_print 或 Object#pretty_print_cycle 将 obj 添加到 pretty printing 缓冲区。
当 obj 已经被打印,即对象引用链中存在循环时,将使用 Object#pretty_print_cycle。
Source
# File lib/pp.rb, line 302 def pp_hash(obj) group(1, '{', '}') { seplist(obj, nil, :each_pair) {|k, v| group { pp_hash_pair k, v } } } end
一个 Hash 的 pretty print 方法。
Source
# File lib/pp.rb, line 314 def pp_hash_pair(k, v) if Symbol === k if k.inspect.match?(%r[\A:["$@!]|[%&*+\-\/<=>@\]^`|~]\z]) k = k.to_s.inspect end text "#{k}:" else pp k text ' ' text '=>' end group(1) { breakable pp v } end
一个 Hash 对的 pretty print 方法。
Source
# File lib/pp.rb, line 286 def pp_object(obj) object_address_group(obj) { seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v| breakable v = v.to_s if Symbol === v text v text '=' group(1) { breakable '' pp(obj.instance_eval(v)) } } } end
一个标准的、安全的、用于 pretty printing 任何给定 Object 的方法。
Source
# File lib/pp.rb, line 168 def push_inspect_key(id) Thread.current[:__recursive_key__][:inspect][id] = true end
将对象 ID id 添加到正在 pretty print 的对象集中,以避免重复对象。
Source
# File lib/pp.rb, line 267 def seplist(list, sep=nil, iter_method=:each) # :yield: element sep ||= lambda { comma_breakable } first = true kwsplat = EMPTY_KWHASH list.__send__(iter_method) {|*v| if first first = false else sep.call end kwsplat ? yield(*v, **kwsplat) : yield(*v) } end
添加一个分隔列表。默认情况下,列表由逗号和可断开的空格分隔。
seplist 使用 iter_method 迭代 list。它会将每个对象屈服给为 seplist 提供的块。分隔符过程 separator_proc 会在每次屈服之间调用。
如果迭代次数为零,则根本不调用 separator_proc。
如果 separator_proc 为 nil 或未提供,则使用 +lambda { comma_breakable }+。如果未提供 iter_method,则使用 :each。
例如,以下 3 段代码具有相似的效果。
q.seplist([1,2,3]) {|v| xxx v } q.seplist([1,2,3], lambda { q.comma_breakable }, :each) {|v| xxx v } xxx 1 q.comma_breakable xxx 2 q.comma_breakable xxx 3