=pod

=head1 NAME

Package::Transporter::Generator::Constant_Function - base class for generating constant functions at compile time


=head1 SYNOPSIS

The following example demonstrates the creation and use of the
constant functions ATB_NAME, ..., ATB_PRICE.

	package CF3;
	use strict;

	use Package::Transporter sub{eval shift}, sub {
	        $_[0]->register_drain('::Enumerated', 'FOR_SELF', 'ATB_',
	        	qw(NAME  SALE  STOCK  PRICE));
	};
	
	#...
	sub sell {
		my ($self, $amount) = @_;

	#	return if (ABT_SALE == IS_FALSE);
		$self->[ATB_STOCK] -= $amount;
		my $costs = $amount * $self->[ATB_PRICH];

		return($costs);
	}


Perl will tell you at compile time about the typing mistake ATB_PRICH,
which could be seen as the main motivation for the exercise. The
generated symbols can be inherited by other packages, therefore
completing the OO system of Perl. The symbol IS_FALSE is such an
example, it comes from a imaginary upstream package.

=head1 DESCRIPTION

The objective of this class is to promote a greater
expressiveness of Perl5 code, while keeping fundamental programming
practices intact. Practically this is achieved through constant
functions, which are managed in a convenient manner. For details on
constant functions, see the manual page perlsub. In short, such
functions result in an inlined value, meaning that no actual
subroutine call is performed by perl.

The class forms the base for ::Enumerated_CF, ::Random_CF, ::Lowered_CF, and
::Flatened_CF.

=head2 Motivation

Hashes are a popular approach to store information in Perl. Their keys
are based on scalar strings, which opens the door for typing
mistakes. Perl can't tell you about the typing mistake IS_OM_SALE in
package CF0 (see below) at compile time. With Hash::Util you can set a
trigger for a fatal exception once the erroneous code is executed, but
that is unpredictable - maybe it never happens - and really late
compared to the trivial nature of the error.

	# -- common approach using strings (without Package::Transporter)
	package CF0;
	use strict;

	my $states = { 'IS_ON_SALE' => 1 };

	my $apples = $states->{'IS_OM_SALE'};
	my $oranges = 1; # two times faster than apples

The example package CF1 (see below) demonstrates the creation
and use of the constant function IS_ON_SALE. Oh, again a typing
mistake. Good that IS_ON_SALE is an identifier and not a string, so
Perl will tell you at compile time about the unknown identifier
IS_OM_SALE. That is favorable over the case where the customer 
reports the error to you after the whole show crashed.

	# -- manually crafted constant function (without Package::Transporter)
	package CF1;
	use strict;

	sub IS_ON_SALE() { 1 };

	my $apples = IS_OM_SALE;
	my $oranges = 1; # same execution speed as apples

After the assignments to $apples and $oranges, both variables hold the
same value "1". Because of internal optimizations in perl, there is
even no impact on execution speed by using IS_ON_SALE. However, the
expressiveness is higher. From reading the source it is clear that
$apples I<are on sale> and there is an I<amount of one> orange left (in the
basket). The technique to use symbols instead of actual values is even
older than Perl, but not commonly found in Perl.
	
	package CF2;
	use strict;

	use Package::Transporter sub{eval shift}, sub {
	        $_[0]->register_drain('::Flatened', 'FOR_SELF', 'IS_',
			'ON_SALE' => 1);
	};

	my $apples = IS_ON_SALE;
	my $oranges = 1;

The example package CF2 (see above) demonstrates how to create the
constant function with Package::Transporter. Regarding the amount of code
required, the use of Package::Transporter is not efficient for trivial cases.
Remember that the examples CF0, CF1, and CF2 are about the general
motivation for constant functions, not about the motivation to use
Package::Transporter.

Now that you are hopefully convinced about constant functions, you
want to use them all over the place. How about random hash keys for
your objects? Annoy all the people who mess around with the internals
of your objects:

	package CF4;
	use strict;

	use Package::Transporter sub{eval shift}, sub {
	        $_[0]->register_drain('::Random', 'FOR_SELF', 'ATB_',
			qw(NAME  TYPE  STOCK  PRICE));
	};

	#...
	sub sell {
		my ($self, $amount) = @_;

		$self->{+ATB_STOCK} -= $amount;
		my $costs = $amount * $self->{+ATB_PRICE};

		return($costs);
	}

Inconsistencies in 'use strict' enforce a unary plus in front of the
subroutine identifiers ATB_STOCK and ATB_PRICE. Without the plus, the
identifiers would surprisingly be taken as unquoted strings. It is
surprising, because it is the opposite of what 'use strict' was meant
for. Fixed in Perl6.

To end this section and to do what its title implies, namely to
motivate you, it should be mentioned that symbolic array indices can be
shared between packages in a way that is called inheritance in the OO
world.

=head2 The Prefix

This package can easily lead to many symbols being used, thus
potentially increasing the chance of name clashes. Meaning that a name
is allocated for conflicting purposes. You can protect from such
clashes by using a meaningful prefix. Example: IMAP_CST_ as prefix for
DISCONNECTED, to indicate that the symbol IMAP_CST_DISCONNECTED is
about a disconnected IMAP client state.

=head1 PUBLIC INTERFACE REFERENCE

Only the public interface is documented in the following.

=over 8

=item B<new>

The constructor. Calling parameters: package visiting point (subroutine reference). Return value: a Package::Transporter::Package object.

=item B<drop>

The sweeper. Removes the object from the Package::Transporter class with the intention of releasing the allocated memory. No calling parameter or return value.


=head1 KNOWN BUGS AND LIMITATIONS


=head2 WISHLIST

The author hopes that one day there will be a 'use stricter'. Which
does, among other things:

=over 8

=item * Make its effect irreversible. Meaning there is no 'no stricter'.

=item * Introduce 2 as irreversible flag in Internals::SvREADONLY(..., 2); with the purpose of locking the readonly flag.

=item * Let Internals::SvREADONLY also prohibt re-blessing a locked reference, re-declaring a package namespace and re-defining a subroutine.

=item * Complain about the unqouted string in { key => 'value' }. Yes, there is an unqouted string and it should be treated as such. Or at least give precedence to constant functions.

=item * Make the namespace of a package read-only for other packages. (Indirect access to the symbol table via '::' is read-only.).

=item * Disable direct access to the symbol table. No \*, no \%::. Or at least restricted to the current package.

=item * Let 'package' return a reference to or name of the namespace.

=back



=head1 AUTHOR

Winfried Trumper E<lt>pub+perl(a)wt.tuxomania.netE<gt>


=head1 COPYRIGHT

Copyright (C) 2009, 2010 Winfried Trumper

This module is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


=head1 SEE ALSO

The manual page for L<Package::Transporter::Package> contains the details
of using and extending Package::Transporter.

Different approaches are provided by the Perl modules L<Exporter> and L<constant>.

The following packages provide support for objects as array references and are therefore loosely related to Transporter: L<Class-Gomor> (there are more, but I can't find them right now).

The following packages treat arrays as objects, which Transporter is not about, but that also clarifies things: 
L<List::oo>, 
L<Class-Builtin>, 
L<Devel-Ladybug>, and
L<Object-Array>.

The package L<POE> is features a lot of constant functions

=cut