The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

fields::aliased - alias members created by the 'fields' pragma

DESCRIPTION

fields::aliased extends the fields pragmatic module to make compile-time class fields even easier to use...you get them aliased to lexical variables so that you don't have to constantly dereference the object within methods.

As an example, let's take the following inane excerpt of a class named Example:

        package Example;
        use strict;
        use fields qw(scalar array hash);

        ## Constructor
        sub new {
            my $self = fields::new(shift);

            $self->{scalar} = 3;
            $self->{array}  = [];
            $self->{hash}   = {};

            return $self;
        }

        sub sample_method {
            my ($self) = @_;

            $self->{array}[0] = 'yup';
            print $self->{scalar}, "\n";
        }

The exact same effect could be achieved by the following:

        package Example;
        use strict;
        use fields::aliased qw($scalar @array %hash);

        ## Constructor
        sub new {
            my $self = shift->SUPER::new;
            field vars : $self;

            $scalar = 3;

            return $self;
        }

        sub sample_method {
            field vars : my $self (@array, $scalar);

            $array[0] = 'yup';
            print $scalar, "\n";
        }

They perform the same operations, but you don't have to type $self-> around all of the fields. This can make code much easier to read, especially for arrays and hashes.

DECLARING FIELDS

use fields::aliased qw($scalar @array %hash);

use fields::aliased qw(:strict $scalar @array %hash);

You declare fields similar to the way you do using fields. The difference is that you precede each one with a type character to indicate what kind of data it will store, just as when declaring regular variables. Specifying use fields::aliased not only declares the variables, but it installs a source filter (see Filter::Simple) that takes care of inserting the appropriate declarations into methods when needed.

The word :strict occurring in the list requires all fields to be explicitly named when used in a method.

CREATING FIELDS

my $object = fields::aliased::new($class);

The class that uses fields::aliased automatically has a class inserted into its @ISA array which provides a constructor (see "new") that automatically sets up the fields and give them suitable initial value. If you provide your own constructor, be sure to call the superclass's method.

You don't need to know if $object is an array or a hash, and in fact it could change between versions of Perl, since pseudohashes (the current implementation, as of 5.8.4) are scheduled to go away in 5.10.

USING FIELDS

field vars [ : [ my ] $self ] [ ( $var1 [, ...] ) ]

This is the part that makes it all worthwhile. To access the fields defined for an object, use a field vars statement somewhere near the beginning of the method. The various parts are explained below.

field vars

This part is constant.

: $self

Specifies the variable to be used as the object reference for access to the fields. This variable must have been declared and set prior to the field vars statement.

: my $self

As above, but in addition declares $self and assigns it a value by shifting the first element of @_ into it.

If neither form is specified, the fields are accessed via $_[0], but this is not removed from @_ or stored anywhere.

(Note that the variable can be named anything, but it must be a simple scalar variable.)

( $var1, ... )

You may specify an optional list of variables to restrict the aliased fields to just those variables. It is an error to name a variable for which a corresponding field was not declared.

If you don't specify a list of variables, all applicable fields have lexical variables aliased to them.

If you specify the word :strict anywhere in the list of fields to be created (at use fields::aliased time), then only variables named in the list will be aliased, and a fatal error will be given if the list isn't specified.

Private variables in superclasses can't be specified in this list, and don't have aliases created for them if the list isn't specified.

Once you've executed this statement, you access the fields in your object reference as if they were simple scalar variables.

METHODS

The following methods are automatically added to the class that calls use fields::aliased:

new

$object = new $class;

Creates an object of $class and returns a reference to it. The fields defined for the object, including inherited fields, are all created and suitably initialized.

create_aliases

$object->create_aliases('varname' ...);

Creates lexical variables in its caller aliased to the corresponding fields in $object. This is called by the code introduced as a result of the field vars statement; you shouldn't ever have an occasion to use it directly.

pedigree

@list = $class->pedigree;

@list = $object->pedigree;

Returns the list of classes that comprise the specified class, starting with $class itself and continuing on up, in the order Perl will search for methods.

NOTES

  • This whole thing is currently experimental. It seems to work, but for now you should probably avoid using it in really important code.

  • Because of the way use fields works, you can't have two fields with the same name even if they are different types. For example, you couldn't have both @var and $var defined. You will get a compile-time error message if you try this, even if one of the variables is inherited.

  • Also, because of the way use fields works, you can only use single inheritance for any classes that have fields defined. If the fields pragma (actually, the base pragma) somehow doesn't detect this, the "fields::aliased::new" method will. It's a fatal error either way.

  • If for some reason you have a class split across two or more files, you must either place all fields in one file or make sure that all component files are seen at compile time, prior to a field vars being encountered in any of them.

  • If you split the class across multiple files and have defined all fields in one of them, you must include a use fields::aliased; line in each of the others in order to be sure the field vars statements are properly compiled.

  • If you define more than one class in the same source file, you must turn off the filtering by using

    no fields::aliased;

    prior to beginning the new package.

DIAGNOSTICS

multiple definition of variable: name

The named variable was declared multiple times, each time with the same type.

name1 already defined as name2

The same field name has been used for variables of different types, e.g. $vars and @vars.

name1 already defined as name2 in class

The same member name was used multiple times in different classes, with different types.

invalid variable name: name

The specified field name is not a valid Perl identifier.

invalid item in import list: item

An item was seen in the import list on the use fields::aliased line that was neither a valid Perl variable name nor the word :strict.

no such field varname

There is no field corresponding to varname.

variable 'name' doesn't match type of field

The type (scalar, array, or hash) of variable name doesn't match that of the value stored in the specified field.

must specify variable list when ':strict' is specified

You didn't.

invalid field variables: list

The items specified appeared in the variable list of a field vars statement, but not in the actual list of fields.

PREREQUISITES

Tie::IxHash, Filter::Simple, Lexical::Util

SEE ALSO

Alias, Lexical::Alias, Perl6::Binding

HISTORY

0.2

Fixed the example code so it actually compiles and runs. (Thanks to Slaven Rezic for finding this.)

Changed to allow trailing whitespace and/or a trailing comma at the end of the variable list in the field vars statement.

0.1

Initial release, May 31, 2004.

COPYRIGHT AND LICENSE

Copyright 2004 Kevin Michael Vail

This program is free software. It may be copied and/or redistributed under the same terms as Perl itself.

AUTHOR

Kevin Michael Vail <kevin@vaildc.net>