/usr/share/perl5/XXX.pm is in libxxx-perl 0.18-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | ##
# name: XXX
# abstract: See Your Data in the Nude
# author: Ingy döt Net <ingy@cpan.org>
# license: perl
# copyright: 2006, 2008, 2010-2011
package XXX;
use 5.006001;
use strict;
use warnings;
use base 'Exporter';
our $VERSION = '0.18';
our @EXPORT = qw( WWW XXX YYY ZZZ );
our $DumpModule = 'YAML';
sub import {
my ($package, @args) = @_;
for (my $i = 0; $i < @args; $i++) {
my $arg = $args[$i];
if ($arg eq '-with') {
die "-with requires another argument"
unless $i++ < @args;
$DumpModule = $args[$i];
die "Don't know how to use XXX -with '$DumpModule'"
unless $DumpModule =~ /^(YAML|Data::Dumper$)/;
}
# TODO Deprecation. These options are now undocumented. Next releases:
# warn, then die, then remove.
elsif ($arg =~ /^-dumper$/i) {
$DumpModule = 'Data::Dumper';
}
elsif ($arg =~ /^-yaml$/i) {
$DumpModule = 'YAML';
}
else {
next;
}
last;
}
@_ = ($package);
goto &Exporter::import;
}
sub _xxx_dump {
no strict 'refs';
no warnings;
$DumpModule ||= 'YAML';
my $dump_type =
($DumpModule =~ /^YAML/) ? 'yaml' :
($DumpModule eq 'Data::Dumper') ? 'dumper' :
die 'Invalid dump module in $DumpModule';
if (not defined ${"$DumpModule\::VERSION"}) {
eval "require $DumpModule; 1" or die $@;
}
if ($dump_type eq 'yaml') {
return &{"$DumpModule\::Dump"}(@_) . "...\n";
}
elsif ($dump_type eq 'dumper') {
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Indent = 2;
return Data::Dumper::Dumper(@_);
}
else {
die "XXX had an internal error";
}
}
sub _at_line_number {
my ($file_path, $line_number);
my $caller = 0;
while (++$caller) {
no strict 'refs';
my $skipper = (caller($caller))[0] . "::XXX_skip";
next if defined &$skipper and &$skipper();
($file_path, $line_number) = (caller($caller))[1,2];
last;
}
" at $file_path line $line_number\n";
}
sub WWW {
my $dump = _xxx_dump(@_) . _at_line_number();
if (defined &main::diag and
defined &Test::More::diag and
\&main::diag eq \&Test::More::diag
) {
main::diag($dump);
}
else {
warn($dump);
}
return wantarray ? @_ : $_[0];
}
sub XXX {
die _xxx_dump(@_) . _at_line_number();
}
sub YYY {
my $dump = _xxx_dump(@_) . _at_line_number();
if (defined &main::note and
defined &Test::More::note and
\&main::note eq \&Test::More::note
) {
main::note($dump);
}
else {
print($dump);
}
return wantarray ? @_ : $_[0];
}
sub ZZZ {
require Carp;
Carp::confess(_xxx_dump(@_));
}
1;
=head1 SYNOPSIS
use XXX;
XXX my $dog = Dog->new({has => ['fleas', 'style']});
my $dog = XXX Dog->new({has => ['fleas', 'style']});
my $dog = Dog->new(XXX {has => ['fleas', 'style']});
my $dog = Dog->new({XXX has => ['fleas', 'style']});
my $dog = Dog->new({has => XXX ['fleas', 'style']});
my $dog = Dog->new({has => [XXX 'fleas', 'style']});
=head1 DESCRIPTION
XXX.pm exports a function called XXX that you can put just about
anywhere in your Perl code to make it die with a YAML dump of the
arguments to its right.
The charm of XXX-debugging is that it is easy to type, rarely requires
parens and stands out visually so that you remember to remove it.
XXX.pm also exports WWW, YYY and ZZZ which do similar debugging things.
=head1 FUNCTIONS
=over
=item WWW
WWW will warn a dump of its arguments, and then return the original
arguments. This means you can stick it in the middle of expressions.
NOTE: If you use WWW with Test::More, it will <diag()> rather than C<warn()>.
mnemonic: W for warn
=item XXX
XXX will die with a dump of its arguments.
mnemonic: XXX == Death, Nudity
=item YYY
YYY will print a dump of its arguments, and then return the original
arguments. This means you can stick it in the middle of expressions.
NOTE: If you use YYY with Test::More, it will <note()> rather than C<print()>.
mnemonic: YYY == Why Why Why??? or YAML YAML YAML
=item ZZZ
ZZZ will Carp::confess a dump of its arguments.
mnemonic: You should confess all your sins before you sleep. zzzzzzzz
=back
=head1 CONFIGURATION
By default, XXX uses YAML.pm to dump your data. You can change this like so:
use XXX -with => 'Data::Dumper';
use XXX -with => 'YAML::XS';
use XXX -with => 'YAML::SomeOtherYamlModule';
Only modules with names beginning with 'YAML' and the Data::Dumper
module are supported.
If you need to load XXX with C<require>, you can set the dumper module
with the C<$XXX::DumpModule> global variable.
require XXX;
$XXX::DumpModule = 'YAML::Syck';
XXX::XXX($variable);
=head1 STACK TRACE LEVEL
If you call a debugging function that calls XXX for you, XXX will print the
wrong file and line number. To force XXX to skip a package in the call stack,
just define the C<XXX_skip> constant like this:
package MyDebugger;
use constant XXX_skip => 1;
sub debug {
require XXX;
XXX::XXX(@_);
}
Now calls to MyDebugger::debug will print the file name you called it from,
not from MyDebugger itself.
|