Build a Small Perl Class with the Experimental class Feature
You will finish with a working Perl class that has a private field, a constructor parameter, a method, an adjustment block and a subclass. The examples are verified against Perl 5.38.2 and its perl-doc manpage on Ubuntu.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need Perl 5.38 or newer with the core class feature available. This syntax is still experimental and incomplete, so use it for controlled experiments or code whose Perl-version requirement you can enforce. It is not a drop-in replacement for established object systems.
1. Confirm the interpreter and feature
Check the interpreter before writing a class. This is an ordinary, read-only command and does not need elevated privileges:
$ perl -v
This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi
$ perl -e 'use v5.38; use feature "class"; print "class feature available\n"'
class feature available
The use v5.38 declaration sets the minimum language version for this example. use feature "class" enables the keywords in the current lexical scope. Without it, class, field and method are not ordinary Perl syntax.
Checkpoint: if the second command fails, stop. Do not remove the version declaration to hide the problem. Install or select an interpreter that supports the feature, then rerun the check.
2. Define a class with a field and method
A class declaration creates a package-like class and supplies a new constructor automatically. Fields are lexical to the class, but each object receives separate storage. A method gets the current object in the automatically provided $self lexical, although $self is not written in the method signature.
use v5.38;
use feature "class";
class Greeter {
field $name = "world";
method greet {
return "Hello, $name";
}
}
say Greeter->new->greet;
Run it as a one-off probe:
$ perl greeter.pl
class is experimental at greeter.pl line 4.
field is experimental at greeter.pl line 5.
method is experimental at greeter.pl line 7.
Hello, world
The experimental warnings are expected on this Perl build. The warning line numbers can change when you edit the file. The useful application result is Hello, world. There is no constructor to write: adding a manual new is contrary to the feature's intended model.
3. Accept named constructor parameters
Add the :param attribute to a scalar field when its value should come from the constructor. By default, the parameter name is the field name without its sigil. A default expression makes the parameter optional; without one, the caller must provide it.
use v5.38;
use feature "class";
class Greeter {
field $name :param = "world";
method greet {
return "Hello, $name";
}
}
say Greeter->new->greet;
say Greeter->new(name => "Ada")->greet;
Expected output is:
Hello, world
Hello, Ada
Use :param(the_name) when the external name should differ from the field name. The attribute applies to scalar fields. Keep the constructor call as named pairs, and do not assume that a positional argument will populate a field.
4. Run construction-time adjustment code
Use an ADJUST block for code that should run during construction and can see fields created before it. Each object gets its own field values:
use v5.38;
use feature "class";
class Counter {
field $count = 0;
ADJUST {
$count++;
}
method value {
return $count;
}
}
my $first = Counter->new;
my $second = Counter->new;
say $first->value, " ", $second->value;
Both objects print 1 1. The initializer and adjustment run for each construction, rather than sharing one mutable package variable.
Do not put an assumption about $self into a field initializer: during that expression the instance is not yet constructed. An ADJUST block is the appropriate place for work that needs the object.
5. Add one superclass
Declare a single parent with the :isa class attribute. Inherited methods are visible to the subclass, but fields remain private lexical storage and are not directly inherited into the subclass's scope.
use v5.38;
use feature "class";
class Base {
method label {
return "base";
}
}
class Child :isa(Base) {
}
say Child->new->label;
The result is:
base
:isa(Base 2.345) can request a minimum version of the parent, and the declaration may try to load the named module. Treat that as a dependency boundary: check the module is present and compatible before deploying the class.
6. Keep the experimental boundary visible
Perl's native classes are a new interpreter feature, not a wrapper around traditional bless-based objects. The local reference marks the feature as incomplete. Roles, configurable ADJUST parameters, generated accessors and broader metaprogramming support are listed as future work or proposals, not promises to build against.
There is no service change, package installation or persistent state in these examples, so there is nothing to undo. If you place the code in a project, the recovery action is to remove or revert that project file and restore the previous implementation. Do that through your normal version-control workflow; do not edit a production copy during a feature experiment.
Before committing, run the exact file with the target interpreter and treat any experimental warning as a deliberate compatibility decision. If a future Perl release changes the feature, pin the supported Perl range and keep a small executable test like the probes above.
Done means
perl -vconfirmed a compatible interpreter and the feature probe succeeded.- A class created objects through the automatic
newconstructor. - A field had per-object storage and a method could read it.
:paramaccepted a named constructor value and its default worked.- An
ADJUSTblock ran once for each object. :isaexposed an inherited method without pretending fields are public.- You recorded that the syntax is experimental and verified it with the Perl version you will deploy.