PHP 8.2.31
Preview: pp.rb Size: 13.31 KB
/proc/thread-self/root/opt/alt/ruby19/lib64/ruby/1.9.1/pp.rb

# == Pretty-printer for Ruby objects.
#
# = Which seems better?
#
# non-pretty-printed output by #p is:
#   #<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline="\n", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>
#
# pretty-printed output by #pp is:
#   #<PP:0x81fedf0
#    @buffer=[],
#    @buffer_width=0,
#    @genspace=#<Proc:0x81feda0>,
#    @group_queue=
#     #<PrettyPrint::GroupQueue:0x81fed3c
#      @queue=
#       [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
#        []]>,
#    @group_stack=
#     [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
#    @indent=0,
#    @maxwidth=79,
#    @newline="\n",
#    @output=#<IO:0x8114ee4>,
#    @output_width=2>
#
# I like the latter.  If you do too, this library is for you.
#
# = Usage
#
#   pp(obj)
#
# output +obj+ to +$>+ in pretty printed format.
#
# It returns +nil+.
#
# = Output Customization
# To define your customized pretty printing function for your classes,
# redefine a method #pretty_print(+pp+) in the class.
# It takes an argument +pp+ which is an instance of the class PP.
# The method should use PP#text, PP#breakable, PP#nest, PP#group and
# PP#pp to print the object.
#
# = Author
# Tanaka Akira <akr@m17n.org>

require 'prettyprint'

module Kernel
  # returns a pretty printed object as a string.
  def pretty_inspect
    PP.pp(self, '')
  end

  private
  # prints arguments in pretty form.
  #
  # pp returns argument(s).
  def pp(*objs) # :doc:
    objs.each {|obj|
      PP.pp(obj)
    }
    objs.size <= 1 ? objs.first : objs
  end
  module_function :pp
end

class PP < PrettyPrint
  # Outputs +obj+ to +out+ in pretty printed format of
  # +width+ columns in width.
  #
  # If +out+ is omitted, +$>+ is assumed.
  # If +width+ is omitted, 79 is assumed.
  #
  # PP.pp returns +out+.
  def PP.pp(obj, out=$>, width=79)
    q = PP.new(out, width)
    q.guard_inspect_key {q.pp obj}
    q.flush
    #$pp = q
    out << "\n"
  end

  # Outputs +obj+ to +out+ like PP.pp but with no indent and
  # newline.
  #
  # PP.singleline_pp returns +out+.
  def PP.singleline_pp(obj, out=$>)
    q = SingleLine.new(out)
    q.guard_inspect_key {q.pp obj}
    q.flush
    out
  end

  # :stopdoc:
  def PP.mcall(obj, mod, meth, *args, &block)
    mod.instance_method(meth).bind(obj).call(*args, &block)
  end
  # :startdoc:

  @sharing_detection = false
  class << self
    # Returns the sharing detection flag as a boolean value.
    # It is false by default.
    attr_accessor :sharing_detection
  end

  module PPMethods
    def guard_inspect_key
      if Thread.current[:__recursive_key__] == nil
        Thread.current[:__recursive_key__] = {}.untrust
      end

      if Thread.current[:__recursive_key__][:inspect] == nil
        Thread.current[:__recursive_key__][:inspect] = {}.untrust
      end

      save = Thread.current[:__recursive_key__][:inspect]

      begin
        Thread.current[:__recursive_key__][:inspect] = {}.untrust
        yield
      ensure
        Thread.current[:__recursive_key__][:inspect] = save
      end
    end

    def check_inspect_key(id)
      Thread.current[:__recursive_key__] &&
      Thread.current[:__recursive_key__][:inspect] &&
      Thread.current[:__recursive_key__][:inspect].include?(id)
    end
    def push_inspect_key(id)
      Thread.current[:__recursive_key__][:inspect][id] = true
    end
    def pop_inspect_key(id)
      Thread.current[:__recursive_key__][:inspect].delete id
    end

    # Adds +obj+ to the pretty printing buffer
    # using Object#pretty_print or Object#pretty_print_cycle.
    #
    # Object#pretty_print_cycle is used when +obj+ is already
    # printed, a.k.a the object reference chain has a cycle.
    def pp(obj)
      id = obj.object_id

      if check_inspect_key(id)
        group {obj.pretty_print_cycle self}
        return
      end

      begin
        push_inspect_key(id)
        group {obj.pretty_print self}
      ensure
        pop_inspect_key(id) unless PP.sharing_detection
      end
    end

    # A convenience method which is same as follows:
    #
    #   group(1, '#<' + obj.class.name, '>') { ... }
    def object_group(obj, &block) # :yield:
      group(1, '#<' + obj.class.name, '>', &block)
    end

    PointerMask = (1 << ([""].pack("p").size * 8)) - 1

    case Object.new.inspect
    when /\A\#<Object:0x([0-9a-f]+)>\z/
      PointerFormat = "%0#{$1.length}x"
    else
      PointerFormat = "%x"
    end

    def object_address_group(obj, &block)
      id = PointerFormat % (obj.object_id * 2 & PointerMask)
      group(1, "\#<#{obj.class}:0x#{id}", '>', &block)
    end

    # A convenience method which is same as follows:
    #
    #   text ','
    #   breakable
    def comma_breakable
      text ','
      breakable
    end

    # Adds a separated list.
    # The list is separated by comma with breakable space, by default.
    #
    # #seplist iterates the +list+ using +iter_method+.
    # It yields each object to the block given for #seplist.
    # The procedure +separator_proc+ is called between each yields.
    #
    # If the iteration is zero times, +separator_proc+ is not called at all.
    #
    # If +separator_proc+ is nil or not given,
    # +lambda { comma_breakable }+ is used.
    # If +iter_method+ is not given, :each is used.
    #
    # For example, following 3 code fragments has similar effect.
    #
    #   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
    def seplist(list, sep=nil, iter_method=:each) # :yield: element
      sep ||= lambda { comma_breakable }
      first = true
      list.__send__(iter_method) {|*v|
        if first
          first = false
        else
          sep.call
        end
        yield(*v)
      }
    end

    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

    def pp_hash(obj)
      group(1, '{', '}') {
        seplist(obj, nil, :each_pair) {|k, v|
          group {
            pp k
            text '=>'
            group(1) {
              breakable ''
              pp v
            }
          }
        }
      }
    end
  end

  include PPMethods

  class SingleLine < PrettyPrint::SingleLine
    include PPMethods
  end

  module ObjectMixin
    # 1. specific pretty_print
    # 2. specific inspect
    # 3. specific to_s
    # 4. generic pretty_print

    # A default pretty printing method for general objects.
    # It calls #pretty_print_instance_variables to list instance variables.
    #
    # If +self+ has a customized (redefined) #inspect method,
    # the result of self.inspect is used but it obviously has no
    # line break hints.
    #
    # This module provides predefined #pretty_print methods for some of
    # the most commonly used built-in classes for convenience.
    def pretty_print(q)
      method_method = Object.instance_method(:method).bind(self)
      begin
        inspect_method = method_method.call(:inspect)
      rescue NameError
      end
      begin
        to_s_method = method_method.call(:to_s)
      rescue NameError
      end
      if inspect_method && /\(Kernel\)#/ !~ inspect_method.inspect
        q.text self.inspect
      elsif !inspect_method && self.respond_to?(:inspect)
        q.text self.inspect
      elsif to_s_method && /\(Kernel\)#/ !~ to_s_method.inspect
        q.text self.to_s
      elsif !to_s_method && self.respond_to?(:to_s)
        q.text self.to_s
      else
        q.pp_object(self)
      end
    end

    # A default pretty printing method for general objects that are
    # detected as part of a cycle.
    def pretty_print_cycle(q)
      q.object_address_group(self) {
        q.breakable
        q.text '...'
      }
    end

    # Returns a sorted array of instance variable names.
    #
    # This method should return an array of names of instance variables as symbols or strings as:
    # +[:@a, :@b]+.
    def pretty_print_instance_variables
      instance_variables.sort
    end

    # Is #inspect implementation using #pretty_print.
    # If you implement #pretty_print, it can be used as follows.
    #
    #   alias inspect pretty_print_inspect
    #
    # However, doing this requires that every class that #inspect is called on
    # implement #pretty_print, or a RuntimeError will be raised.
    def pretty_print_inspect
      if /\(PP::ObjectMixin\)#/ =~ Object.instance_method(:method).bind(self).call(:pretty_print).inspect
        raise "pretty_print is not overridden for #{self.class}"
      end
      PP.singleline_pp(self, '')
    end
  end
end

class Array
  def pretty_print(q)
    q.group(1, '[', ']') {
      q.seplist(self) {|v|
        q.pp v
      }
    }
  end

  def pretty_print_cycle(q)
    q.text(empty? ? '[]' : '[...]')
  end
end

class Hash
  def pretty_print(q)
    q.pp_hash self
  end

  def pretty_print_cycle(q)
    q.text(empty? ? '{}' : '{...}')
  end
end

class << ENV
  def pretty_print(q)
    h = {}
    ENV.keys.sort.each {|k|
      h[k] = ENV[k]
    }
    q.pp_hash h
  end
end

class Struct
  def pretty_print(q)
    q.group(1, sprintf("#<struct %s", PP.mcall(self, Kernel, :class).name), '>') {
      q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member|
        q.breakable
        q.text member.to_s
        q.text '='
        q.group(1) {
          q.breakable ''
          q.pp self[member]
        }
      }
    }
  end

  def pretty_print_cycle(q)
    q.text sprintf("#<struct %s:...>", PP.mcall(self, Kernel, :class).name)
  end
end

class Range
  def pretty_print(q)
    q.pp self.begin
    q.breakable ''
    q.text(self.exclude_end? ? '...' : '..')
    q.breakable ''
    q.pp self.end
  end
end

class File < IO
  class Stat
    def pretty_print(q)
      require 'etc.so'
      q.object_group(self) {
        q.breakable
        q.text sprintf("dev=0x%x", self.dev); q.comma_breakable
        q.text "ino="; q.pp self.ino; q.comma_breakable
        q.group {
          m = self.mode
          q.text sprintf("mode=0%o", m)
          q.breakable
          q.text sprintf("(%s %c%c%c%c%c%c%c%c%c)",
            self.ftype,
            (m & 0400 == 0 ? ?- : ?r),
            (m & 0200 == 0 ? ?- : ?w),
            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
                             (m & 04000 == 0 ? ?x : ?s)),
            (m & 0040 == 0 ? ?- : ?r),
            (m & 0020 == 0 ? ?- : ?w),
            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
                             (m & 02000 == 0 ? ?x : ?s)),
            (m & 0004 == 0 ? ?- : ?r),
            (m & 0002 == 0 ? ?- : ?w),
            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
                             (m & 01000 == 0 ? ?x : ?t)))
        }
        q.comma_breakable
        q.text "nlink="; q.pp self.nlink; q.comma_breakable
        q.group {
          q.text "uid="; q.pp self.uid
          begin
            pw = Etc.getpwuid(self.uid)
          rescue ArgumentError
          end
          if pw
            q.breakable; q.text "(#{pw.name})"
          end
        }
        q.comma_breakable
        q.group {
          q.text "gid="; q.pp self.gid
          begin
            gr = Etc.getgrgid(self.gid)
          rescue ArgumentError
          end
          if gr
            q.breakable; q.text "(#{gr.name})"
          end
        }
        q.comma_breakable
        q.group {
          q.text sprintf("rdev=0x%x", self.rdev)
          q.breakable
          q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor)
        }
        q.comma_breakable
        q.text "size="; q.pp self.size; q.comma_breakable
        q.text "blksize="; q.pp self.blksize; q.comma_breakable
        q.text "blocks="; q.pp self.blocks; q.comma_breakable
        q.group {
          t = self.atime
          q.text "atime="; q.pp t
          q.breakable; q.text "(#{t.tv_sec})"
        }
        q.comma_breakable
        q.group {
          t = self.mtime
          q.text "mtime="; q.pp t
          q.breakable; q.text "(#{t.tv_sec})"
        }
        q.comma_breakable
        q.group {
          t = self.ctime
          q.text "ctime="; q.pp t
          q.breakable; q.text "(#{t.tv_sec})"
        }
      }
    end
  end
end

class MatchData
  def pretty_print(q)
    nc = []
    self.regexp.named_captures.each {|name, indexes|
      indexes.each {|i| nc[i] = name }
    }
    q.object_group(self) {
      q.breakable
      q.seplist(0...self.size, lambda { q.breakable }) {|i|
        if i == 0
          q.pp self[i]
        else
          if nc[i]
            q.text nc[i]
          else
            q.pp i
          end
          q.text ':'
          q.pp self[i]
        end
      }
    }
  end
end

class Object < BasicObject
  include PP::ObjectMixin
end

[Numeric, Symbol, FalseClass, TrueClass, NilClass, Module].each {|c|
  c.class_eval {
    def pretty_print_cycle(q)
      q.text inspect
    end
  }
}

[Numeric, FalseClass, TrueClass, Module].each {|c|
  c.class_eval {
    def pretty_print(q)
      q.text inspect
    end
  }
}

Directory Contents

Dirs: 30 × Files: 78

Name Size Perms Modified Actions
cgi DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
date DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
digest DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
dl DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
drb DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
fiddle DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
irb DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
json DIR
- drwxr-xr-x 2024-03-03 22:48:09
Edit Download
matrix DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
net DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
openssl DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
optparse DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
psych DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
racc DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
rake DIR
- drwxr-xr-x 2024-03-03 22:50:37
Edit Download
rbconfig DIR
- drwxr-xr-x 2024-03-03 22:48:12
Edit Download
rdoc DIR
- drwxr-xr-x 2024-03-03 22:48:11
Edit Download
rexml DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
rinda DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
ripper DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
rss DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
rubygems DIR
- drwxr-xr-x 2024-03-03 22:48:12
Edit Download
shell DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
syck DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
test DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
uri DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
webrick DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
- drwxr-xr-x 2024-03-03 22:48:09
Edit Download
xmlrpc DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
yaml DIR
- drwxr-xr-x 2024-03-03 22:48:05
Edit Download
2.57 KB lrw-r--r-- 2011-05-18 21:19:18
Edit Download
2.63 KB lrw-r--r-- 2009-10-02 10:45:39
Edit Download
18.00 KB lrw-r--r-- 2011-06-28 06:09:46
Edit Download
9.30 KB lrw-r--r-- 2011-05-16 21:21:35
Edit Download
7.22 KB lrw-r--r-- 2011-07-30 14:53:14
Edit Download
380 B lrw-r--r-- 2009-08-16 15:34:35
Edit Download
82.66 KB lrw-r--r-- 2011-07-21 21:40:21
Edit Download
946 B lrw-r--r-- 2011-05-21 12:25:03
Edit Download
23.23 KB lrw-r--r-- 2011-06-28 11:45:50
Edit Download
9.74 KB lrw-r--r-- 2011-07-27 19:56:28
Edit Download
2.24 KB lrw-r--r-- 2011-05-16 20:52:55
Edit Download
176 B lrw-r--r-- 2010-06-12 15:28:47
Edit Download
19 B lrw-r--r-- 2009-10-02 10:45:39
Edit Download
3.80 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
5.59 KB lrw-r--r-- 2009-10-02 10:45:39
Edit Download
25.72 KB lrw-r--r-- 2012-12-13 05:24:26
Edit Download
1.33 KB lrw-r--r-- 2011-08-26 23:54:49
Edit Download
928 B lrw-r--r-- 2011-08-16 00:51:58
Edit Download
45.32 KB lrw-r--r-- 2012-02-25 08:11:07
Edit Download
2.03 KB lrw-r--r-- 2011-05-18 21:19:18
Edit Download
7.64 KB lrw-r--r-- 2011-05-22 02:14:57
Edit Download
15.38 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
8.83 KB lrw-r--r-- 2013-10-31 14:40:55
Edit Download
24.92 KB lrw-r--r-- 2013-04-11 02:31:05
Edit Download
8.34 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
1.74 KB lrw-r--r-- 2011-08-30 02:25:32
Edit Download
5.74 KB lrw-r--r-- 2010-12-07 11:47:39
Edit Download
20.85 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
6.52 KB lrw-r--r-- 2011-08-26 23:54:49
Edit Download
47.65 KB lrw-r--r-- 2011-07-09 19:11:06
Edit Download
68.90 KB lrw-r--r-- 2014-02-06 05:20:52
Edit Download
6.94 KB lrw-r--r-- 2011-06-17 22:33:54
Edit Download
1.61 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
5.69 KB lrw-r--r-- 2011-05-16 21:53:12
Edit Download
25.84 KB lrw-r--r-- 2014-02-24 03:43:27
Edit Download
20.64 KB lrw-r--r-- 2011-05-18 21:19:18
Edit Download
547 B lrw-r--r-- 2011-07-25 06:38:44
Edit Download
51.13 KB lrw-r--r-- 2014-02-14 04:52:03
Edit Download
6.49 KB lrw-r--r-- 2012-02-24 14:49:51
Edit Download
14.21 KB lrw-r--r-- 2011-08-26 23:54:49
Edit Download
13.31 KB lrw-r--r-- 2010-08-01 14:09:40
Edit Download
9.63 KB lrw-r--r-- 2011-08-02 15:25:59
Edit Download
13.98 KB lrw-r--r-- 2011-06-01 00:21:46
Edit Download
205 B lrw-r--r-- 2009-10-02 10:45:39
Edit Download
1.59 KB lrw-r--r-- 2009-10-02 10:45:39
Edit Download
15.81 KB lrw-r--r-- 2011-10-10 23:14:17
Edit Download
9.82 KB lrw-r--r-- 2012-08-07 20:50:05
Edit Download
2.02 KB lrw-r--r-- 2011-06-29 03:09:34
Edit Download
308 B lrw-r--r-- 2009-09-24 00:42:23
Edit Download
4.29 KB lrw-r--r-- 2013-02-06 08:00:49
Edit Download
1.74 KB lrw-r--r-- 2010-10-29 22:02:39
Edit Download
59.91 KB lrw-r--r-- 2014-02-14 06:56:54
Edit Download
91 B lrw-r--r-- 2009-10-02 10:45:39
Edit Download
2.84 KB lrw-r--r-- 2011-05-11 10:22:16
Edit Download
34.13 KB lrw-r--r-- 2013-12-22 04:38:28
Edit Download
23.53 KB lrw-r--r-- 2011-05-20 12:22:26
Edit Download
8.46 KB lrw-r--r-- 2012-05-07 11:25:45
Edit Download
29.91 KB lrw-r--r-- 2012-02-10 08:28:48
Edit Download
5.90 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
3.88 KB lrw-r--r-- 2012-02-12 07:51:05
Edit Download
4.02 KB lrw-r--r-- 2011-05-18 14:09:38
Edit Download
23.22 KB lrw-r--r-- 2014-01-30 12:04:22
Edit Download
13.91 KB lrw-r--r-- 2010-07-19 04:54:06
Edit Download
6.87 KB lrw-r--r-- 2011-06-29 03:09:34
Edit Download
10.42 KB lrw-r--r-- 2013-10-31 14:44:40
Edit Download
6.59 KB lrw-r--r-- 2014-02-14 03:48:42
Edit Download
3.38 KB lrw-r--r-- 2011-06-29 03:09:34
Edit Download
17.03 KB lrw-r--r-- 2013-10-31 14:06:50
Edit Download
3.26 KB lrw-r--r-- 2013-04-02 04:09:07
Edit Download
3.72 KB lrw-r--r-- 2011-05-18 21:19:18
Edit Download
6.63 KB lrw-r--r-- 2011-06-29 13:19:59
Edit Download
6.79 KB lrw-r--r-- 2009-03-06 04:23:05
Edit Download
268 B lrw-r--r-- 2009-10-02 10:45:39
Edit Download
8.32 KB lrw-r--r-- 2011-05-19 00:07:25
Edit Download
3.07 KB lrw-r--r-- 2011-05-13 20:03:21
Edit Download
2.29 KB lrw-r--r-- 2011-08-26 23:54:49
Edit Download
6.80 KB lrw-r--r-- 2011-05-10 23:37:43
Edit Download
2.58 KB lrw-r--r-- 2013-05-29 12:00:57
Edit Download

If ZipArchive is unavailable, a .tar will be created (no compression).