update docs for add_package_symbol
[gitmo/Package-Stash.git] / lib / Package / Stash.pm
index 84a4d0b..6f0910c 100644 (file)
@@ -98,7 +98,7 @@ sub namespace {
     }
 }
 
-=head2 add_package_symbol $variable $value
+=head2 add_package_symbol $variable $value %opts
 
 Adds a new package symbol, for the symbol given as C<$variable>, and optionally
 gives it an initial value of C<$value>. C<$variable> should be the name of
@@ -108,6 +108,22 @@ variable including the sigil, so
 
 will create C<%Foo::foo>.
 
+Valid options (all optional) are C<filename>, C<first_line_num>, and
+C<last_line_num>.
+
+C<$opts{filename}>, C<$opts{first_line_num}>, and C<$opts{last_line_num}> can
+be used to indicate where the symbol should be regarded as having been defined.
+Currently these values are only used if the symbol is a subroutine ('C<&>'
+sigil) and only if C<$^P & 0x10> is true, in which case the special C<%DB::sub>
+hash is updated to record the values of C<filename>, C<first_line_num>, and
+C<last_line_num> for the subroutine. If these are not passed, their values are
+inferred (as much as possible) from C<caller> information.
+
+This is especially useful for debuggers and profilers, which use C<%DB::sub> to
+determine where the source code for a subroutine can be found.  See
+L<http://perldoc.perl.org/perldebguts.html#Debugger-Internals> for more
+information about C<%DB::sub>.
+
 =cut
 
 sub _valid_for_type {
@@ -124,18 +140,32 @@ sub _valid_for_type {
 }
 
 sub add_package_symbol {
-    my ($self, $variable, $initial_value) = @_;
+    my ($self, $variable, $initial_value, %opts) = @_;
 
     my ($name, $sigil, $type) = ref $variable eq 'HASH'
         ? @{$variable}{qw[name sigil type]}
         : $self->_deconstruct_variable_name($variable);
 
+    my $pkg = $self->name;
+
     if (@_ > 2) {
         $self->_valid_for_type($initial_value, $type)
             || confess "$initial_value is not of type $type";
-    }
 
-    my $pkg = $self->name;
+        # cheap fail-fast check for PERLDBf_SUBLINE and '&'
+        if ($^P and $^P & 0x10 && $sigil eq '&') {
+            my $filename = $opts{filename};
+            my $first_line_num = $opts{first_line_num};
+
+            (undef, $filename, $first_line_num) = caller
+                if not defined $filename;
+
+            my $last_line_num = $opts{last_line_num} || ($first_line_num ||= 0);
+
+            # http://perldoc.perl.org/perldebguts.html#Debugger-Internals
+            $DB::sub{$pkg . '::' . $name} = "$filename:$first_line_num-$last_line_num";
+        }
+    }
 
     no strict 'refs';
     no warnings 'redefine', 'misc', 'prototype';