v4.13
[language-befunge.git] / lib / Language / Befunge / Debug.pm
bloba6e28246a88328d779049050a469b06ff6315995
2 # This file is part of Language::Befunge.
3 # Copyright (c) 2001-2009 Jerome Quelin, all rights reserved.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the same terms as Perl itself.
10 package Language::Befunge::Debug;
12 use 5.010;
13 use strict;
14 use warnings;
16 use base qw{ Exporter };
17 our @EXPORT = qw{ debug };
20 # -- public subs
22 sub debug {}
24 my %redef;
25 sub enable {
26 %redef = ( debug => sub { warn @_; } );
27 _redef();
30 sub disable {
31 %redef = ( debug => sub {} );
32 _redef();
36 # -- private subs
39 # _redef()
41 # recursively walk the symbol table, and replace subs named after %redef
42 # keys with the matching value of %redef.
44 # this is not really clean, but since the sub debug() is exported in
45 # other modules, replacing the sub in *this* module is not enough: other
46 # modules still refer to their local copy.
48 # also, calling sub with full name Language::Befunge::Debug::debug() has
49 # performance issues (10%-15%) compared to using an exported sub...
51 my %orig; # original subs
52 sub _redef {
53 my $parent = shift;
54 if ( not defined $parent ) {
55 $parent = '::';
56 foreach my $sub ( keys %redef ) {
57 $orig{ $sub } = \&$sub;
60 no strict 'refs';
61 no warnings 'redefine';
62 foreach my $ns ( grep /^\w+::/, keys %{$parent} ) {
63 $ns = $parent . $ns;
64 _redef($ns) unless $ns eq '::main::';
65 foreach my $sub (keys %redef) {
66 next # before replacing, check that...
67 unless exists ${$ns}{$sub} # named sub exist...
68 && \&{ ${$ns}{$sub} } == $orig{$sub}; # ... and refer to the one we want to replace
69 *{$ns . $sub} = $redef{$sub};
76 __END__
78 =head1 NAME
80 Language::Befunge::Debug - optimized debug solution for language::befunge
83 =head1 SYNOPSIS
85 use Language::Befunge::Debug;
86 debug("foo\n"); # does nothing by default
87 Language::Befunge::Debug::enable();
88 debug("bar\n"); # now that debug is enabled, output on STDERR
89 Language::Befunge::Debug::disable();
90 debug("baz\n"); # sorry dave, back to no output
94 =head1 DESCRIPTION
96 This module provides a C<debug()> subroutine, which output on STDERR if
97 debugging is enabled. If debugging is disabled (the default), perl will
98 optimize out those debugging calls.
102 =head1 PUBLIC API
104 =head2 Exported functions
106 The module is exporting only one function:
108 =over 4
110 =item * debug( @stuff );
112 If debugging is enabled (which is B<not> the default), write C<@stuff>
113 on STDERR.
115 =back
118 =head2 Other functions
120 The module also provides 2 functions to control debugging:
122 =over 4
124 =item * Language::Befunge::Debug::enable();
126 Request that calls to C<debug()> really start output on STDERR.
129 =item * Language::Befunge::Debug::disable();
131 Request that calls to C<debug()> stop output-ing on STDERR.
134 =back
138 =head1 SEE ALSO
140 L<Language::Befunge>
144 =head1 AUTHOR
146 Jerome Quelin, C<< <jquelin@cpan.org> >>
148 Development is discussed on C<< <language-befunge@mongueurs.net> >>
152 =head1 COPYRIGHT & LICENSE
154 Copyright (c) 2001-2009 Jerome Quelin, all rights reserved.
156 This program is free software; you can redistribute it and/or modify
157 it under the same terms as Perl itself.
160 =cut