Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sysread/slot
Fast, simple, compile-time class declaration for Perl
https://github.com/sysread/slot
class object oo perl slot
Last synced: about 2 months ago
JSON representation
Fast, simple, compile-time class declaration for Perl
- Host: GitHub
- URL: https://github.com/sysread/slot
- Owner: sysread
- Created: 2018-03-30T12:14:08.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2020-02-10T19:12:27.000Z (almost 5 years ago)
- Last Synced: 2023-08-20T23:09:54.553Z (over 1 year ago)
- Topics: class, object, oo, perl, slot
- Language: Perl
- Size: 96.7 KB
- Stars: 0
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.pod
- Changelog: Changes
Awesome Lists containing this project
README
=pod
=encoding UTF-8
=head1 NAME
Class::Slot - Simple, efficient, comple-time class declaration
=head1 VERSION
version 0.09
=head1 SYNOPSIS
package Point;
use Class::Slot;
use Types::Standard -types;slot x => Int, rw => 1, req => 1;
slot y => Int, rw => 1, req => 1;
slot z => Int, rw => 1, def => 0;1;
my $p = Point->new(x => 10, y => 20);
$p->x(30); # x is set to 30
$p->y; # 20
$p->z; # 0=head1 DESCRIPTION
Similar to the L pragma, C declares individual fields in a
class, building a constructor and slot accessor methods.Although not nearly as full-featured as L L,
C is light-weight, fast, works with basic Perl objects, and
imposes no dependencies outside of the Perl core distribution. Currently, only
the unit tests require non-core packages.C is intended for use with Perl's bare metal objects. It provides
a simple mechanism for building accessor and constructor code at compile time.It does I provide inheritance; that is done by setting C<@ISA> or via the
C or C pragmas.It does I provide method wrappers; that is done with the C
pseudo-class.It I build a constructor method, C, with support for default and
required slots as keyword arguments and type validation of caller-supplied
values.It I build accesor methods (reader or combined reader/writer, using the
slot's name) for each slot declared, with support for type validation.=head1 @SLOTS
The C<@SLOTS> package variable is added to the declaring package and is a list
of quoted slot identifiers. C<@SLOTS> includes I slots available to this
class, including those defined in its ancestors.=head1 CONSTRUCTOR
C generates a constructor method named C. If there is already
an existing method with that name, it may be overwritten, depending on the
order of execution.=head1 DECLARING SLOTS
The pragma itself accepts two positional parameters: the slot name and optional
type. The type is validated during construction and in the setter, if the slot
is read-write.Slot names must be valid perl identifiers suitable for subroutine names. Types
must be either a code ref which returns true for valid values or an instance of
a class that supports the C, C, and C
methods (see L).The C pragma may be used as either a keyword or a pragma. The following
are equivalent:use Class::Slot x => Int;
use slot x => Int;
slot x => Int;A simple source filter is used to translate uses of C and C
into C. This is a somewhat brittle solution to ensuring
compile time code generation while avoiding a clash with
L, which uses the C namespace internally but
nevertheless holds the keys to it on CPAN.As a result, care must be taken when defining slots using the C
syntax (rather than C). The source filter identifies
the keyword C when it appears as the first value on a line, followed by
a word boundary. There is the potential for false positives, such as with:my @ots = qw(
slot blot glot clot
);=head1 OPTIONS
=head2 rw
When true, the accessor method accepts a single parameter to modify the slot
value. If the slot declares a type, the accessor will croak if the new value
does not validate.=head2 req
When true, this constructor will croak if the slot is missing from the named
parameters passed to the constructor. If the slot also declares a
L value, this attribute is moot.=head2 def
When present, this value or code ref which returns a value is used as the
default if the slot is missing from the named parameters passed to the
constructor.If the default is a code ref which generates a value and a type is specified,
note that the code ref will be called during compilation to validate its type
rather than re-validating it with every accessor call.=head2 fwd
When present, generates delegate accessor methods that forward to a mapped
method on the object stored in the slot. For example:# Foo.pm
class Foo;sub life{ 42 }
1;
# Bar.pm
class Bar;
use Class::Slot;
use parent 'Foo';slot 'foo', fwd => ['life'];
1;
# main.pl
my $bar = Bar->new(foo => Foo->new);
say $bar->life; # calls $bar->foo->lifeAlternately, C may be defined as a hash ref mapping new local method
names to method names in the delegate class:# Bar.pm
class Bar;
use Class::Slot;
use parent 'Foo';slot 'foo', fwd => {barlife => 'life'};
1;
# main.pl
my $bar = Bar->new(foo => Foo->new);
say $bar->barlife; # calls $bar->foo->life
say $bar->life; # dies: method not found=head1 INHERITANCE
When a class declares a slot which is also declared in the parent class, the
parent class' settings are overridden. Any options I included in the
overriding class' slot declaration remain in effect in the child class.package A;
use Class::Slot;slot 'foo', rw => 1;
slot 'bar', req => 1, rw => 1;1;
package B;
use Class::Slot;
use parent -norequire, 'A';slot 'foo', req => 1; # B->foo is req, inherits rw
slot 'bar', rw => 0; # B->bar inherits req, but is no longer rw1;
=head1 COMPILATION PHASES
=head2 BEGIN
C statements are evaluated by the perl interpreter at the earliest
possible moment. At this time, C is still gathering slot
declarations and the class is not fully assembled.=head2 CHECK
All slots are assumed to be declared by the C phase. The first slot
declaration adds a C block to the package that installs all generated
accessor methods in the declaring class. This may additionally trigger any
parent classes (identified by C<@ISA>) which are not yet complete.=head2 RUNTIME
If C is not available (for example, because the class was generated in a
string eval), the generated code will be evaluated at run-time the first time
the class' C method is called.=head1 DEBUGGING
Adding C to your class will cause C to
print the generated constructor and accessor code just before it is evaluated.Adding C anywhere will cause C to emit
debug messages globally.These may be set from the shell with the C environmental
variable.=head1 PERFORMANCE
C is designed to be fast and have a low overhead. When available,
L is used to generate the class accessors. This applies to
slots that are not writable or are writable but have no declared type.This behavior can be disabled by setting C<$Class::Slot::XS> to a falsey value,
although this must be done in a C block before declaring any slots, or
by setting the environmental variable C to a truthy value
before the module is loaded.A minimal benchmark on my admittedly underpowered system compares L,
L, and L. The test includes multiple setters using a mix of
inherited, typed and untyped, attributes, which ammortizes the benefit of
Class::XSAccessor to L and L.| Rate moo moose slot
| moo 355872/s -- -51% -63%
| moose 719424/s 102% -- -25%
| slot 961538/s 170% 34% --Oddly, L seemed to perform better running the same test without
L installed.| Rate moo moose slot
| moo 377358/s -- -50% -56%
| moose 757576/s 101% -- -12%
| slot 862069/s 128% 14% --=head1 AUTHOR
Jeff Ober
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2020 by Jeff Ober.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.=cut