The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Scalar::Footnote - Attach hidden scalars to references

SYNOPSIS

  use Data::Dumper;
  use Scalar::Footnote;

  my $obj = Foo->new;

  # attach invisible footnote to $obj:
  $obj->Scalar::Footnote::set( my_key => 'my footnote' );
  print Dumper( $obj );

  # get it back:
  my $note = $obj->Scalar::Footnote::get( 'my_key' );
  print "footnote: $note\n";

  # remove it:
  my $note = $obj->Scalar::Footnote::remove( 'my_key' );

DESCRIPTION

Scalar::Footnote lets you attach scalar footnotes to an object (or any kind of reference, really) that are essentially invisible from Perl. For example, if you try dumping an object that has a footnote attached to it, you won't actually see the footnote:

  my $obj = bless [qw( foo bar )], 'Foo';
  $obj->Scalar::Footnote::set( 'Foo' => 'foo note' );
  print Dumper( $obj );

prints:

  $VAR1 = bless [
            'foo',
            'bar'
          ], 'Foo';

You can of course still access the footnote with Scalar::Footnote::get.

Footnote Keys

To avoid overwriting footnotes other people have created, you have to specify a key to store your footnote under. You should pick something fairly unique, such as a namespace you're using:

  $obj->Scalar::Footnote::set( 'My::Project' => 'foo note' );

What Are Footnotes Attached To?

Footnotes are attached to the referenced value of the $ref you pass in (not the variable $ref itself). So in the following:

  my $ref1;
  {
      my $ref2 = {};
      $ref1    = $ref2;
      set_footnote( $ref2, ['a footnote'] );
  }
  print get_footnote( $ref1 );

The footnote is attached to the anonymous hashref, {}, not $ref2. That's why you can still access it through $ref1 after $ref2 goes out of scope.

What Can I Attach Footnotes To?

Pretty much any kind of reference -- scalar refs, hash refs, array refs, and code refs have been tested.

What Can I Use As A Footnote?

Pretty much any kind of scalar. Constants, scalar refs, hash refs, array refs, and code refs have been tested.

When Are Footnotes Destroyed?

Footnotes go away when the reference they're attached to goes away, unless you hold a copy of the footnote elsewhere:

  my $ref  = {};
  my $note = bless [qw( bar note )], 'Bar';
  Scalar::Footnote::set( $ref, 'my footnote key' => $note );

  $note = undef;
  # $note is still accessible via Scalar::Footnote::get

  $ref  = undef;
  # $note is now destroyed

CLASS METHODS / FUNCTIONS

These are not quite class methods, but were intended to be used in an OO style.

$ref = Scalar::Footnote::set( $ref, $key => $footnote )

Attaches $footnote to $ref (which must be a reference), and overwrites any footnotes that were previously attached. Dies if $ref is not a reference, or if there was an error. Returns the $ref on success.

$footnote = Scalar::Footnote::get( $ref, $key )

Gets the footnote attached to $ref (which must be a reference). Dies if $ref is not a reference, or if there was an error. Returns the $footnote, or undef if no footnote was attached.

$footnote = Scalar::Footnote::remove( $ref, $key )

Removes the footnote attached to $ref (which must be a reference). Dies if $ref is not a reference, or if there was an error. Returns the removed $footnote, or undef if no footnote was attached.

$footnote_obj = Scalar::Footnote::remove_all( $ref )

Removes all footnotes attached to $ref (which must be a reference). Dies if $ref is not a reference, or if there was an error. Returns the removed Scalar::Footnote object, or undef if no footnote was attached.

$footnote_obj = Scalar::Footnote->get_footnote_object_for( $ref )

Returns the Scalar::Footnote object attached to $ref (which must be a reference) or undef if no footnote was attached. Dies if $ref is not a reference, or if there was an error.

$footnote_obj = Scalar::Footnote->attach_new_footnote_object_to( $ref )

Creates a new Scalar::Footnote object and attaches it to $ref (which must be a reference), overwriting any previous footnotes attached. Dies if $ref is not a reference, or if there was an error. Returns the new footnote object.

INSTANCE METHODS

These can be used on Scalar::Footnote objects returned by any of the class methods above. They return the footnote object unless otherwise specified.

$footnote_obj->set_value_for( $key => $val )

As in $footnotes{$key} = $val .

$val = $footnote_obj->get_value_for( $key )

As in $footnotes{$key} .

$val = $footnote_obj->remove_value_for( $key )

As in delete $footnotes{$key} .

CAVEATS

Watch out for circular references - Scalar::Util's weaken() is your friend, as is Data::Structure::Util's has_circular_ref() and curcular_off().

KNOWN BUGS

Attempts to clone objects using Clone dies with:

  Don't know how to handle magic of type \37777777633 at ...

AUTHORS

M. Friebe, original concept.

Converted to Pixie by Piers Cawley (changed the magic type, module name, stole the idea).

Converted to Scalar::Footnote by Steve Purkis <spurkis@cpan.org>, OO interface added, updated XS to store a copy of the footnote.

SEE ALSO

Scalar::Util, Data::Structure::Util