⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dumper.pm

📁 Altera recommends the following system configuration: * Pentium II 400 with 512-MB system memory (fa
💻 PM
📖 第 1 页 / 共 2 页
字号:
## Data/Dumper.pm## convert perl data structures into perl syntax suitable for both printing# and eval## Documentation at the __END__#package Data::Dumper;$VERSION = '2.102';#$| = 1;require 5.005_64;require Exporter;use XSLoader ();require overload;use Carp;@ISA = qw(Exporter);@EXPORT = qw(Dumper);@EXPORT_OK = qw(DumperX);XSLoader::load 'Data::Dumper';# module vars and their defaults$Indent = 2 unless defined $Indent;$Purity = 0 unless defined $Purity;$Pad = "" unless defined $Pad;$Varname = "VAR" unless defined $Varname;$Useqq = 0 unless defined $Useqq;$Terse = 0 unless defined $Terse;$Freezer = "" unless defined $Freezer;$Toaster = "" unless defined $Toaster;$Deepcopy = 0 unless defined $Deepcopy;$Quotekeys = 1 unless defined $Quotekeys;$Bless = "bless" unless defined $Bless;#$Expdepth = 0 unless defined $Expdepth;$Maxdepth = 0 unless defined $Maxdepth;## expects an arrayref of values to be dumped.# can optionally pass an arrayref of names for the values.# names must have leading $ sign stripped. begin the name with *# to cause output of arrays and hashes rather than refs.#sub new {  my($c, $v, $n) = @_;  croak "Usage:  PACKAGE->new(ARRAYREF, [ARRAYREF])"     unless (defined($v) && (ref($v) eq 'ARRAY'));  $n = [] unless (defined($n) && (ref($v) eq 'ARRAY'));  my($s) = {              level      => 0,           # current recursive depth	     indent     => $Indent,     # various styles of indenting	     pad	=> $Pad,        # all lines prefixed by this string	     xpad       => "",          # padding-per-level	     apad       => "",          # added padding for hash keys n such	     sep        => "",          # list separator	     seen       => {},          # local (nested) refs (id => [name, val])	     todump     => $v,          # values to dump []	     names      => $n,          # optional names for values []	     varname    => $Varname,    # prefix to use for tagging nameless ones             purity     => $Purity,     # degree to which output is evalable             useqq 	=> $Useqq,      # use "" for strings (backslashitis ensues)             terse 	=> $Terse,      # avoid name output (where feasible)             freezer	=> $Freezer,    # name of Freezer method for objects             toaster	=> $Toaster,    # name of method to revive objects             deepcopy	=> $Deepcopy,   # dont cross-ref, except to stop recursion             quotekeys	=> $Quotekeys,  # quote hash keys             'bless'	=> $Bless,	# keyword to use for "bless"#	     expdepth   => $Expdepth,   # cutoff depth for explicit dumping	     maxdepth	=> $Maxdepth,   # depth beyond which we give up	   };  if ($Indent > 0) {    $s->{xpad} = "  ";    $s->{sep} = "\n";  }  return bless($s, $c);}## add-to or query the table of already seen references#sub Seen {  my($s, $g) = @_;  if (defined($g) && (ref($g) eq 'HASH'))  {    my($k, $v, $id);    while (($k, $v) = each %$g) {      if (defined $v and ref $v) {	($id) = (overload::StrVal($v) =~ /\((.*)\)$/);	if ($k =~ /^[*](.*)$/) {	  $k = (ref $v eq 'ARRAY') ? ( "\\\@" . $1 ) :	       (ref $v eq 'HASH')  ? ( "\\\%" . $1 ) :	       (ref $v eq 'CODE')  ? ( "\\\&" . $1 ) :				     (   "\$" . $1 ) ;	}	elsif ($k !~ /^\$/) {	  $k = "\$" . $k;	}	$s->{seen}{$id} = [$k, $v];      }      else {	carp "Only refs supported, ignoring non-ref item \$$k";      }    }    return $s;  }  else {    return map { @$_ } values %{$s->{seen}};  }}## set or query the values to be dumped#sub Values {  my($s, $v) = @_;  if (defined($v) && (ref($v) eq 'ARRAY'))  {    $s->{todump} = [@$v];        # make a copy    return $s;  }  else {    return @{$s->{todump}};  }}## set or query the names of the values to be dumped#sub Names {  my($s, $n) = @_;  if (defined($n) && (ref($n) eq 'ARRAY'))  {    $s->{names} = [@$n];         # make a copy    return $s;  }  else {    return @{$s->{names}};  }}sub DESTROY {}sub Dump {    return &Dumpxs	unless $Data::Dumper::Useqq || (ref($_[0]) && $_[0]->{useqq});    return &Dumpperl;}## dump the refs in the current dumper object.# expects same args as new() if called via package name.#sub Dumpperl {  my($s) = shift;  my(@out, $val, $name);  my($i) = 0;  local(@post);  $s = $s->new(@_) unless ref $s;  for $val (@{$s->{todump}}) {    my $out = "";    @post = ();    $name = $s->{names}[$i++];    if (defined $name) {      if ($name =~ /^[*](.*)$/) {	if (defined $val) {	  $name = (ref $val eq 'ARRAY') ? ( "\@" . $1 ) :		  (ref $val eq 'HASH')  ? ( "\%" . $1 ) :		  (ref $val eq 'CODE')  ? ( "\*" . $1 ) :					  ( "\$" . $1 ) ;	}	else {	  $name = "\$" . $1;	}      }      elsif ($name !~ /^\$/) {	$name = "\$" . $name;      }    }    else {      $name = "\$" . $s->{varname} . $i;    }    my $valstr;    {      local($s->{apad}) = $s->{apad};      $s->{apad} .= ' ' x (length($name) + 3) if $s->{indent} >= 2;      $valstr = $s->_dump($val, $name);    }    $valstr = "$name = " . $valstr . ';' if @post or !$s->{terse};    $out .= $s->{pad} . $valstr . $s->{sep};    $out .= $s->{pad} . join(';' . $s->{sep} . $s->{pad}, @post)       . ';' . $s->{sep} if @post;    push @out, $out;  }  return wantarray ? @out : join('', @out);}## twist, toil and turn;# and recurse, of course.#sub _dump {  my($s, $val, $name) = @_;  my($sname);  my($out, $realpack, $realtype, $type, $ipad, $id, $blesspad);  $type = ref $val;  $out = "";  if ($type) {    # prep it, if it looks like an object    if (my $freezer = $s->{freezer}) {      $val->$freezer() if UNIVERSAL::can($val, $freezer);    }    ($realpack, $realtype, $id) =      (overload::StrVal($val) =~ /^(?:(.*)\=)?([^=]*)\(([^\(]*)\)$/);    # if it has a name, we need to either look it up, or keep a tab    # on it so we know when we hit it later    if (defined($name) and length($name)) {      # keep a tab on it so that we dont fall into recursive pit      if (exists $s->{seen}{$id}) {#	if ($s->{expdepth} < $s->{level}) {	  if ($s->{purity} and $s->{level} > 0) {	    $out = ($realtype eq 'HASH')  ? '{}' :	      ($realtype eq 'ARRAY') ? '[]' :		'do{my $o}' ;	    push @post, $name . " = " . $s->{seen}{$id}[0];	  }	  else {	    $out = $s->{seen}{$id}[0];	    if ($name =~ /^([\@\%])/) {	      my $start = $1;	      if ($out =~ /^\\$start/) {		$out = substr($out, 1);	      }	      else {		$out = $start . '{' . $out . '}';	      }	    }          }	  return $out;#        }      }      else {        # store our name        $s->{seen}{$id} = [ (($name =~ /^[@%]/)     ? ('\\' . $name ) :			     ($realtype eq 'CODE' and			      $name =~ /^[*](.*)$/) ? ('\\&' . $1 )   :			     $name          ),			    $val ];      }    }    if ($realpack and $realpack eq 'Regexp') {	$out = "$val";	$out =~ s,/,\\/,g;	return "qr/$out/";    }    # If purity is not set and maxdepth is set, then check depth:     # if we have reached maximum depth, return the string    # representation of the thing we are currently examining    # at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').     if (!$s->{purity}	and $s->{maxdepth} > 0	and $s->{level} >= $s->{maxdepth})    {      return qq['$val'];    }    # we have a blessed ref    if ($realpack) {      $out = $s->{'bless'} . '( ';      $blesspad = $s->{apad};      $s->{apad} .= '       ' if ($s->{indent} >= 2);    }    $s->{level}++;    $ipad = $s->{xpad} x $s->{level};    if ($realtype eq 'SCALAR' || $realtype eq 'REF') {      if ($realpack) {	$out .= 'do{\\(my $o = ' . $s->_dump($$val, "\${$name}") . ')}';      }      else {	$out .= '\\' . $s->_dump($$val, "\${$name}");      }    }    elsif ($realtype eq 'GLOB') {	$out .= '\\' . $s->_dump($$val, "*{$name}");    }    elsif ($realtype eq 'ARRAY') {      my($v, $pad, $mname);      my($i) = 0;      $out .= ($name =~ /^\@/) ? '(' : '[';      $pad = $s->{sep} . $s->{pad} . $s->{apad};      ($name =~ /^\@(.*)$/) ? ($mname = "\$" . $1) : 	# omit -> if $foo->[0]->{bar}, but not ${$foo->[0]}->{bar}	($name =~ /^\\?[\%\@\*\$][^{].*[]}]$/) ? ($mname = $name) :	  ($mname = $name . '->');      $mname .= '->' if $mname =~ /^\*.+\{[A-Z]+\}$/;      for $v (@$val) {	$sname = $mname . '[' . $i . ']';	$out .= $pad . $ipad . '#' . $i if $s->{indent} >= 3;	$out .= $pad . $ipad . $s->_dump($v, $sname);	$out .= "," if $i++ < $#$val;      }      $out .= $pad . ($s->{xpad} x ($s->{level} - 1)) if $i;      $out .= ($name =~ /^\@/) ? ')' : ']';    }    elsif ($realtype eq 'HASH') {      my($k, $v, $pad, $lpad, $mname);      $out .= ($name =~ /^\%/) ? '(' : '{';      $pad = $s->{sep} . $s->{pad} . $s->{apad};      $lpad = $s->{apad};      ($name =~ /^\%(.*)$/) ? ($mname = "\$" . $1) :	# omit -> if $foo->[0]->{bar}, but not ${$foo->[0]}->{bar}	($name =~ /^\\?[\%\@\*\$][^{].*[]}]$/) ? ($mname = $name) :	  ($mname = $name . '->');      $mname .= '->' if $mname =~ /^\*.+\{[A-Z]+\}$/;      while (($k, $v) = each %$val) {	my $nk = $s->_dump($k, "");	$nk = $1 if !$s->{quotekeys} and $nk =~ /^[\"\']([A-Za-z_]\w*)[\"\']$/;	$sname = $mname . '{' . $nk . '}';	$out .= $pad . $ipad . $nk . " => ";	# temporarily alter apad	$s->{apad} .= (" " x (length($nk) + 4)) if $s->{indent} >= 2;	$out .= $s->_dump($val->{$k}, $sname) . ",";	$s->{apad} = $lpad if $s->{indent} >= 2;      }      if (substr($out, -1) eq ',') {	chop $out;	$out .= $pad . ($s->{xpad} x ($s->{level} - 1));      }      $out .= ($name =~ /^\%/) ? ')' : '}';    }    elsif ($realtype eq 'CODE') {      $out .= 'sub { "DUMMY" }';      carp "Encountered CODE ref, using dummy placeholder" if $s->{purity};    }    else {      croak "Can\'t handle $realtype type.";    }        if ($realpack) { # we have a blessed ref      $out .= ', \'' . $realpack . '\'' . ' )';      $out .= '->' . $s->{toaster} . '()'  if $s->{toaster} ne '';      $s->{apad} = $blesspad;    }    $s->{level}--;  }  else {                                 # simple scalar    my $ref = \$_[1];    # first, catalog the scalar    if ($name ne '') {      ($id) = ("$ref" =~ /\(([^\(]*)\)$/);      if (exists $s->{seen}{$id}) {        if ($s->{seen}{$id}[2]) {	  $out = $s->{seen}{$id}[0];	  #warn "[<$out]\n";	  return "\${$out}";	}      }      else {	#warn "[>\\$name]\n";	$s->{seen}{$id} = ["\\$name", $ref];      }    }    if (ref($ref) eq 'GLOB' or "$ref" =~ /=GLOB\([^()]+\)$/) {  # glob      my $name = substr($val, 1);      if ($name =~ /^[A-Za-z_][\w:]*$/) {	$name =~ s/^main::/::/;	$sname = $name;      }      else {	$sname = $s->_dump($name, "");	$sname = '{' . $sname . '}';      }      if ($s->{purity}) {	my $k;	local ($s->{level}) = 0;	for $k (qw(SCALAR ARRAY HASH)) {	  my $gval = *$val{$k};	  next unless defined $gval;	  next if $k eq "SCALAR" && ! defined $$gval;  # always there	  # _dump can push into @post, so we hold our place using $postlen	  my $postlen = scalar @post;	  $post[$postlen] = "\*$sname = ";	  local ($s->{apad}) = " " x length($post[$postlen]) if $s->{indent} >= 2;	  $post[$postlen] .= $s->_dump($gval, "\*$sname\{$k\}");	}      }      $out .= '*' . $sname;    }    elsif (!defined($val)) {      $out .= "undef";    }    elsif ($val =~ /^(?:0|-?[1-9]\d{0,8})$/) { # safe decimal number      $out .= $val;    }    else {				 # string      if ($s->{useqq}) {	$out .= qquote($val, $s->{useqq});      }      else {	$val =~ s/([\\\'])/\\$1/g;	$out .= '\'' . $val .  '\'';      }    }  }  if ($id) {    # if we made it this far, $id was added to seen list at current    # level, so remove it to get deep copies    if ($s->{deepcopy}) {      delete($s->{seen}{$id});    }    elsif ($name) {      $s->{seen}{$id}[2] = 1;    }  }  return $out;}  ## non-OO style of earlier version#sub Dumper {  return Data::Dumper->Dump([@_]);}# compat stubsub DumperX {  return Data::Dumper->Dumpxs([@_], []);}sub Dumpf { return Data::Dumper->Dump(@_) }sub Dumpp { print Data::Dumper->Dump(@_) }## reset the "seen" cache #sub Reset {  my($s) = shift;  $s->{seen} = {};  return $s;}sub Indent {  my($s, $v) = @_;  if (defined($v)) {    if ($v == 0) {      $s->{xpad} = "";      $s->{sep} = "";    }    else {      $s->{xpad} = "  ";      $s->{sep} = "\n";    }    $s->{indent} = $v;    return $s;  }  else {    return $s->{indent};  }}sub Pad {  my($s, $v) = @_;  defined($v) ? (($s->{pad} = $v), return $s) : $s->{pad};}sub Varname {  my($s, $v) = @_;  defined($v) ? (($s->{varname} = $v), return $s) : $s->{varname};}sub Purity {  my($s, $v) = @_;  defined($v) ? (($s->{purity} = $v), return $s) : $s->{purity};}sub Useqq {  my($s, $v) = @_;  defined($v) ? (($s->{useqq} = $v), return $s) : $s->{useqq};}sub Terse {  my($s, $v) = @_;  defined($v) ? (($s->{terse} = $v), return $s) : $s->{terse};}sub Freezer {  my($s, $v) = @_;  defined($v) ? (($s->{freezer} = $v), return $s) : $s->{freezer};}sub Toaster {  my($s, $v) = @_;  defined($v) ? (($s->{toaster} = $v), return $s) : $s->{toaster};}sub Deepcopy {  my($s, $v) = @_;  defined($v) ? (($s->{deepcopy} = $v), return $s) : $s->{deepcopy};}sub Quotekeys {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -