Skip to content

Commit

Permalink
perlclass: improve wording
Browse files Browse the repository at this point in the history
  • Loading branch information
mauke committed Feb 9, 2024
1 parent 495831c commit 9a68f2e
Showing 1 changed file with 57 additions and 38 deletions.
95 changes: 57 additions & 38 deletions pod/perlclass.pod
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ perlclass - Perl class syntax reference

=head1 DESCRIPTION

This document describes the syntax of the Perl's C<class> feature, which
provides native keywords supporting object-oriented programming paradigm.
This document describes the syntax of Perl's C<class> feature, which provides
native keywords for object-oriented programming.

=head2 History

Expand All @@ -34,14 +34,15 @@ subroutines from the package it was blessed with (or any of its parents). This
system, while bare-bones, was flexible enough to allow creation of multiple
more advanced, community-driven systems for object orientation.

Class feature is a core implementation of class syntax which is familiar to
what one would find in other programming languages. It isn't a C<bless>
wrapper, but a completely new system built right into the perl interpreter.
The C<class> feature is a core implementation of a class syntax that is similar
to what one would find in other programming languages. It is not a wrapper
around C<bless>, but a completely new system built right into the perl
interpreter.

=head1 KEYWORDS

Enabling the C<class> feature allows the usage of the following new keywords in
the scope of current package:
the current lexical scope:

=head2 class

Expand All @@ -57,9 +58,9 @@ the scope of current package:

class NAME VERSION : ATTRIBUTES...;

The C<class> keyword declares a new package which is intended to be a class.
All other keywords from the C<class> feature should be used in scope of this
declaration.
The C<class> keyword declares a new package that is intended to be a class.
All other keywords from the C<class> feature should be used within the scope of
this declaration.

class WithVersion 1.000 {
# class definition goes here
Expand All @@ -72,10 +73,10 @@ C<class> or C<package> statement.

A C<class> declaration can optionally have a version number, similar to the
C<package> keyword. It can also optionally have attributes. If both are
specified, the version number must come first before the attributes.
specified, the version number must come first, before the attributes.

C<class> and C<package> declarations are similar, but classes automatically get
a constructor named C<new> - You don't have to (and should not) write one.
a constructor named C<new> - you don't have to (and should not) write one.
Additionally, in the class BLOCK you are allowed to declare fields and methods.

=head2 field
Expand All @@ -88,9 +89,9 @@ Additionally, in the class BLOCK you are allowed to declare fields and methods.

field VARIABLE_NAME : ATTRIBUTES = EXPR;

Fields are variables which are visible in the scope of the class - more
specifically within L</method> and C<ADJUST> blocks. Each class instance get
their own storage of fields, independent of each other.
Fields are variables that are visible in the scope of the class - more
specifically within L</method> and L<ADJUST|/Adjustment> blocks. Each class
instance gets its own storage of fields, independent of other instances.

A field behaves like a normal lexically scoped variable. It has a sigil and is
private to the class (though creation of an accessor method will make it
Expand All @@ -106,7 +107,7 @@ access different values in the same scope.
Fields may optionally have initializing expressions. If present, the expression
will be evaluated within the constructor of each object instance. During each
evaluation, the expression can use the value of any previously-set field, as
well as see any other variables in scope.
well as any other variables in scope.

class WithACounter {
my $next_count = 1;
Expand Down Expand Up @@ -202,9 +203,9 @@ attribute.
Inherited methods are visible and may be invoked. Fields are always lexical
and therefore not visible by inheritance.

The C<:isa> attribute may request a minimum version of the base class; it is
applied similar to C<use> - if the provided version is too low it will fail at
compile time.
The C<:isa> attribute may request a minimum version of the base class. As with
C<use MODULE VERSION>, if the actual version of the base class is too low,
compilation will fail.

class Example::Subclass :isa(Example::Base 2.345) { ... }

Expand All @@ -223,7 +224,7 @@ can be specified in the attribute.
field $x :param;
field $y :param(the_y_value);

If there is no defaulting expression then the parameter is required by the
If there is no defaulting expression, then the parameter is required by the
constructor; the caller must pass it or an exception is thrown. With a
defaulting expression this becomes optional.

Expand All @@ -239,7 +240,7 @@ signature, and its body will simply return the value of the field variable.
field $s;
method s () { return $s; }

By default accessor method will have the same name as the field (minus the
By default the accessor method will have the same name as the field (minus the
leading sigil), but a different name can be specified in the attribute's value.

field $x :reader(get_x);
Expand All @@ -248,7 +249,7 @@ leading sigil), but a different name can be specified in the attribute's value.
method get_x () { return $x; }

Reader methods can be applied to non-scalar fields. When invoked in list
context they yield the contents of the field; in scalar context they yield
context, they yield the contents of the field; in scalar context they yield
the count of elements, as if the field variable had been placed in scalar
context.

Expand All @@ -270,22 +271,40 @@ named C<new> and is invoked like a method call on the class name:

my $object = My::Class->new(%arguments);

During the construction, class fields are compared to C<%arguments> hash and
populated where possible.
During object construction, class fields are looked up in the C<%arguments>
hash and populated where possible.

=head2 Adjustment

Object adjustment can be performed during the construction to run user-defined
code. It is done with the help of C<ADJUST> blocks, which are called in order
of declaration.
Object adjustment is way to run arbitrary user-defined code during object
construction. This is done by placing code in C<ADJUST> blocks. Every time an
object is constructed, its C<ADJUST> blocks are executed (in the order in which
they are declared).

They are similar to C<BEGIN> blocks, which run during the compilation of a
package. However, they also have access to C<$self> lexical (object instance)
and all object fields created up to that point.
class WellAdjusted {
field $x :param;
ADJUST {
say "Hello!";
}
ADJUST {
say "x = $x";
}
}

my $object = WellAdjusted->new(x => 42);
# Output:
# Hello!
# x = 42

C<ADJUST> blocks are syntactically similar to L<C<BEGIN> or C<INIT>
blocks|perlmod/BEGIN, UNITCHECK, CHECK, INIT and END>, which only run once.
However, C<ADJUST> blocks, like methods, have access to C<$self> (a lexical
variable holding the object being constructed) as well as all object fields
created up to that point.

=head2 Lifetime

After the construction phase, object is ready to be used.
After the construction phase, the object is ready to be used.

Using C<blessed> (C<Scalar::Util::blessed> or C<builtin::blessed>) on the
object will return the name of the class, while C<reftype>
Expand All @@ -294,13 +313,13 @@ C<'OBJECT'>.

=head2 Destruction

Just like with other references, when object reference count reaches zero it
will automatically be destroyed.
An object is destroyed when the last reference to it goes away, just as with
other data structures in Perl.

=head1 TODO

This feature is still experimental and very incomplete. The following list
gives some overview of the kinds of work still to be added or changed:
gives an overview of features still to be added or changed:

=over 4

Expand All @@ -325,11 +344,11 @@ inspired by a similar plan to add named arguments to subroutine signatures.

=item * ADJUST blocks as true blocks

Currently, every ADJUST block is wrapped in its own CV that gets invoked with
the full ENTERSUB overhead. It should be possible to use the same mechanism
that makes all field initializer expressions appear within the same CV on
ADJUST blocks as well, merging them all into a single CV per class. This will
make it faster to invoke if a class has more than one of them.
Currently, every ADJUST block is wrapped in its own CV (subroutine) that gets
invoked with the full ENTERSUB overhead. It should be possible to use the same
mechanism that makes all field initializer expressions appear within the same
CV on ADJUST blocks as well, merging them all into a single CV per class. This
will make it faster to invoke if a class has more than one of them.

=item * More accessor generator attributes

Expand Down

0 comments on commit 9a68f2e

Please sign in to comment.