dwww Home | Manual pages | Find package

Object::Pad(3pm)      User Contributed Perl Documentation     Object::Pad(3pm)

NAME
       "Object::Pad" - a simple syntax for lexical field-based objects

SYNOPSIS
       On perl version 5.26 onwards:

          use v5.26;
          use Object::Pad;

          class Point {
             field $x :param = 0;
             field $y :param = 0;

             method move ($dX, $dY) {
                $x += $dX;
                $y += $dY;
             }

             method describe () {
                print "A point at ($x, $y)\n";
             }
          }

          Point->new(x => 5, y => 10)->describe;

       Or, for older perls that lack signatures:

          use Object::Pad;

          class Point {
             field $x :param = 0;
             field $y :param = 0;

             method move {
                my ($dX, $dY) = @_;
                $x += $dX;
                $y += $dY;
             }

             method describe {
                print "A point at ($x, $y)\n";
             }
          }

          Point->new(x => 5, y => 10)->describe;

DESCRIPTION
       This module provides a simple syntax for creating object classes, which
       uses private variables that look like lexicals as object member fields.

       While most of this module has evolved into a stable state in practice,
       parts remain experimental because the design is still evolving, and
       many features and ideas have yet to implemented. I don't yet guarantee
       I won't have to change existing details in order to continue its
       development. Feel free to try it out in experimental or newly-developed
       code, but don't complain if a later version is incompatible with your
       current code and you'll have to change it.

       That all said, please do get in contact if you find the module overall
       useful.  The more feedback you provide in terms of what features you
       are using, what you find works, and what doesn't, will help the ongoing
       development and hopefully eventual stability of the design. See the
       "FEEDBACK" section.

   Experimental Features
       Since version 0.63.

       Some of the features of this module are currently marked as
       experimental. They will provoke warnings in the "experimental"
       category, unless silenced.

       You can silence this with "no warnings 'experimental'" but then that
       will silence every experimental warning, which may hide others
       unintentionally. For a more fine-grained approach you can instead use
       the import line for this module to only silence the module's warnings
       selectively:

          use Object::Pad ':experimental(init_expr)';

          use Object::Pad ':experimental(mop)';

          use Object::Pad ':experimental(custom_field_attr)';

          use Object::Pad ':experimental(adjust_params)';

          use Object::Pad ':experimental';  # all of the above

       Since version 0.64.

       Multiple experimental features can be enabled at once by giving
       multiple names in the parens, separated by spaces:

          use Object::Pad ':experimental(init_expr mop)';

   Automatic Construction
       Classes are automatically provided with a constructor method, called
       "new", which helps create the object instances. This may respond to
       passed arguments, automatically assigning values of fields, and
       invoking other blocks of code provided by the class. It proceeds in the
       following stages:

       The BUILDARGS phase

       If the class provides a "BUILDARGS" class method, that is used to
       mangle the list of arguments before the "BUILD" blocks are called. Note
       this must be a class method not an instance method (and so implemented
       using "sub"). It should perform any "SUPER" chaining as may be
       required.

          @args = $class->BUILDARGS( @_ )

       Field assignment

       If any field in the class has the ":param" attribute, then the
       constructor will expect to receive its argmuents in an even-sized list
       of name/value pairs. This applies even to fields inherited from the
       parent class or applied roles. It is therefore a good idea to shape the
       parameters to the constructor in this way in roles, and in classes if
       you intend your class to be extended.

       The constructor will also check for required parameters (these are all
       the parameters for fields that do not have default initialisation
       expressions). If any of these are missing an exception is thrown.

       The BUILD phase

       As part of the construction process, the "BUILD" block of every
       component class will be invoked, passing in the list of arguments the
       constructor was invoked with. Each class should perform its required
       setup behaviour, but does not need to chain to the "SUPER" class first;
       this is handled automatically.

       The ADJUST phase

       Next, the "ADJUST" block of every component class is invoked. This
       happens after the fields are assigned their initial values and the
       "BUILD" blocks have been run.

       The strict-checking phase

       Finally, before the object is returned, if the ":strict(params)" class
       attribute is present, then the constructor will throw an exception if
       there are any remaining named arguments left over after assigning them
       to fields as per ":param" declarations, and running any "ADJUST"
       blocks.

KEYWORDS
   class
          class Name :ATTRS... {
             ...
          }

          class Name :ATTRS...;

       Behaves similarly to the "package" keyword, but provides a package that
       defines a new class. Such a class provides an automatic constructor
       method called "new".

       As with "package", an optional block may be provided. If so, the
       contents of that block define the new class and the preceding package
       continues afterwards. If not, it sets the class as the package context
       of following keywords and definitions.

       As with "package", an optional version declaration may be given. If so,
       this sets the value of the package's $VERSION variable.

          class Name VERSION { ... }

          class Name VERSION;

       A single superclass is supported by the keyword "isa"

       Since version 0.41.

          class Name isa BASECLASS {
             ...
          }

          class Name isa BASECLASS BASEVER {
             ...
          }

       Prior to version 0.41 this was called "extends", but since version 0.73
       this is no longer recognised. The "isa" keyword is now deprecated, in
       favour of the ":isa" attribute which is preferred because it follows a
       more standard grammar without this special-case.

       One or more roles can be composed into the class by the keyword "does"

       Since version 0.41.

          class Name does ROLE, ROLE,... {
             ...
          }

       Prior to version 0.41 this was called "implements", but since version
       0.73 this is no longer recognised. The "does" keyword is now
       deprecated, in favour of the ":does" attribute which is preferred
       because it follows a more standard grammar without this special-case.

       An optional list of attributes may be supplied in similar syntax as for
       subs or lexical variables. (These are annotations about the class
       itself; the concept should not be confused with per-object-instance
       data, which here is called "fields").

       Whitespace is permitted within the value and is automatically trimmed,
       but as standard Perl parsing rules, no space is permitted between the
       attribute's name and the open parenthesis of its value:

          :attr( value here )     # is permitted
          :attr (value here)      # not permitted

       The following class attributes are supported:

       :isa

          :isa(CLASS)

          :isa(CLASS CLASSVER)

       Since version 0.57.

       Declares a superclass that this class extends. At most one superclass
       is supported.

       If the package providing the superclass does not exist, an attempt is
       made to load it by code equivalent to

          require CLASS;

       and thus it must either already exist, or be locatable via the usual
       @INC mechanisms.

       The superclass may or may not itself be implemented by "Object::Pad",
       but if it is not then see "SUBCLASSING CLASSIC PERL CLASSES" for
       further detail on the semantics of how this operates.

       An optional version check can also be supplied; it performs the
       equivalent of

          BaseClass->VERSION( $ver )

       :does

          :does(ROLE)

          :does(ROLE ROLEVER)

       Since version 0.57.

       Composes a role into the class; optionally requiring a version check on
       the role package. This is a newer form of the "implements" and "does"
       keywords and should be preferred for new code.

       Multiple roles can be composed by using multiple ":does" attributes,
       one per role.

       The package will be loaded in a similar way to how the ":isa" attribute
       is handled.

       :repr(TYPE)

       Sets the representation type for instances of this class. Must be one
       of the following values:

          :repr(native)

       The native representation. This is an opaque representation type whose
       contents are not specified. It only works for classes whose entire
       inheritance hierarchy is built only from classes based on
       "Object::Pad".

          :repr(HASH)

       The representation will be a blessed hash reference. The instance data
       will be stored in an array referenced by a key called
       "Object::Pad/slots", which is fairly unlikely to clash with existing
       storage on the instance. No other keys will be used; they are available
       for implementions and subclasses to use.  The exact format of the value
       stored here is not specified and may change between module versions,
       though it can be relied on to be well-behaved as some kind of perl data
       structure for purposes of modules like Data::Dumper or serialisation
       into things like "YAML" or "JSON".

       This representation type may be useful when converting existing classes
       into using "Object::Pad" where there may be existing subclasses of it
       that presume a blessed hash for their own use.

          :repr(magic)

       The representation will use MAGIC to apply the instance data in a way
       that is invisible at the Perl level, and shouldn't get in the way of
       other things the instance is doing even in XS modules.

       This representation type is the only one that will work for subclassing
       existing classes that do not use blessed hashes.

          :repr(autoselect), :repr(default)

       Since version 0.23.

       This representation will select one of the representations above
       depending on what is best for the situation. Classes not derived from a
       non-"Object::Pad" base class will pick "native", and classes derived
       from non-"Object::Pad" bases will pick either the "HASH" or "magic"
       forms depending on whether the instance is a blessed hash reference or
       some other kind.

       This achieves the best combination of DWIM while still allowing the
       common forms of hash reference to be inspected by "Data::Dumper", etc.
       This is the default representation type, and does not have to be
       specifically requested.

       :strict(params)

       Since version 0.43.

       Can only be applied to classes that contain no "BUILD" blocks. If set,
       then the constructor will complain about any unrecognised named
       arguments passed to it (i.e. names that do not correspond to the
       ":param" of any defined field and left unconsumed by any "ADJUST"
       block).

       Since "BUILD" blocks can inspect the arguments arbitrarily, the
       presence of any such block means the constructor cannot determine which
       named arguments are not recognised.

       This attribute is a temporary stepping-stone for compatibility with
       existing code. It is recommended to enable this whenever possible, as a
       later version of this module will likely perform this behaviour
       unconditionally whenever no "BUILD" blocks are present.

   role
          role Name :ATTRS... {
             ...
          }

          role Name :ATTRS...;

       Since version 0.32.

       Similar to "class", but provides a package that defines a new role. A
       role acts similar to a class in some respects, and differently in
       others.

       Like a class, a role can have a version, and named methods.

          role Name VERSION {
             method a { ... }
             method b { ... }
          }

       A role does not provide a constructor, and instances cannot directly be
       constructed. A role cannot extend a class.

       A role can declare that it requires methods of given names from any
       class that implements the role.

          role Name {
             requires METHOD;
          }

       A role can provide instance fields. These are visible to any "ADJUST"
       blocks or methods provided by that role.

       Since version 0.33.

          role Name {
             field $f;

             ADJUST { $f = "a value"; }

             method field { return $f; }
          }

       Since version 0.57 a role can declare that it provides another role:

          role Name :does(OTHERROLE) { ... }
          role Name :does(OTHERROLE OTHERVER) { ... }

       This will include all of the methods from the included role.
       Effectively this means that applying the "outer" role to a class will
       imply applying the other role as well.

       The following role attributes are supported:

       :compat(invokable)

       Since version 0.35.

       Enables a form of backward-compatibility behaviour useful for gradually
       upgrading existing code from classical Perl inheritance or mixins into
       using roles.

       Normally, methods of a role cannot be directly invoked and the role
       must be applied to an Object::Pad-based class in order to be used. This
       however presents a problem when gradually upgrading existing code that
       already uses techniques like roles, multiple inheritance or mixins when
       that code may be split across multiple distributions, or for some other
       reason cannot be upgraded all at once. Methods within a role that has
       the ":compat(invokable)" attribute applied to it may be directly
       invoked on any object instance. This allows the creation of a role that
       can still provide code for existing classes written in classical Perl
       that has not yet been rewritten to use "Object::Pad".

       The tradeoff is that a ":compat(invokable)" role may not create field
       data using the "field" keyword. Whatever behaviours the role wishes to
       perform must be provided only by calling other methods on $self, or
       perhaps by making assumptions about the representation type of
       instances.

       It should be stressed again: This option is only intended for gradual
       upgrade of existing classical Perl code into using "Object::Pad". When
       all existing code is using "Object::Pad" then this attribute can be
       removed from the role.

   field
          field $var;
          field @var;
          field %var;

          field $var :ATTR ATTR...;

          field $var = EXPR;

          field $var //= EXPR;
          field $var ||= EXPR;

          field $var { BLOCK }

       Since version 0.66.

       Declares that the instances of the class or role have a member field of
       the given name. This member field will be accessible as a lexical
       variable within any "method" declarations in the class.

       Array and hash members are permitted and behave as expected; you do not
       need to store references to anonymous arrays or hashes.

       Member fields are private to a class or role. They are not visible to
       users of the class, nor inherited by subclasses nor any class that a
       role is applied to. In order to provide access to them a class may wish
       to use "method" to create an accessor, or use the attributes such as
       ":reader" to get one generated.

       The following field attributes are supported:

       :reader, :reader(NAME)

       Since version 0.27.

       Generates a reader method to return the current value of the field. If
       no name is given, the name of the field is used. A single prefix
       character "_" will be removed if present.

          field $x :reader;

          # equivalent to
          field $x;  method x { return $x }

       Since version 0.55 these are permitted on any field type, but prior
       versions only allowed them on scalar fields. The reader method behaves
       identically to how a lexical variable would behave in the same context;
       namely returning a list of values from an array or key/value pairs from
       a hash when in list context, or the number of items or keys when in
       scalar context.

          field @items :reader;

          foreach my $item ( $obj->items ) { ... }   # iterates the list of items

          my $count = $obj->items;                   # yields count of items

       :writer, :writer(NAME)

       Since version 0.27.

       Generates a writer method to set a new value of the field from its
       arguments.  If no name is given, the name of the field is used prefixed
       by "set_". A single prefix character "_" will be removed if present.

          field $x :writer;

          # equivalent to
          field $x;  method set_x { $x = shift; return $self }

       Since version 0.28 a generated writer method will return the object
       invocant itself, allowing a chaining style.

          $obj->set_x("x")
             ->set_y("y")
             ->set_z("z");

       Since version 0.55 these are permitted on any field type, but prior
       versions only allowed them on scalar fields. On arrays or hashes, the
       writer method takes a list of values to be assigned into the field,
       completely replacing any values previously there.

       :mutator, :mutator(NAME)

       Since version 0.27.

       Generates an lvalue mutator method to return or set the value of the
       field.  These are only permitted for scalar fields. If no name is
       given, the name of the field is used. A single prefix character "_"
       will be removed if present.

          field $x :mutator;

          # equivalent to
          field $x;  method x :lvalue { $x }

       Since version 0.28 all of these generated accessor methods will include
       argument checking similar to that used by subroutine signatures, to
       ensure the correct number of arguments are passed - usually zero, but
       exactly one in the case of a ":writer" method.

       :accessor, :accessor(NAME)

       Since version 0.53.

       Generates a combined reader-writer accessor method to set or return the
       value of the field. These are only permitted for scalar fields. If no
       name is given, the name of the field is used. A prefix character "_"
       will be removed if present.

       This method takes either zero or one additional arguments. If an
       argument is passed, the value of the field is set from this argument
       (even if it is "undef"). If no argument is passed (i.e. "scalar @_" is
       false) then the field is not modified. In either case, the value of the
       field is then returned.

          field $x :accessor;

          # equivalent to
          field $x;

          method field {
             $x = shift if @_;
             return $x;
          }

       :weak

       Since version 0.44.

       Generated code which sets the value of this field will weaken it if it
       contains a reference. This applies to within the constructor if
       ":param" is given, and to a ":writer" accessor method. Note that this
       only applies to automatically generated code; not normal code written
       in regular method bodies. If you assign into the field variable you
       must remember to call "Scalar::Util::weaken" (or "builtin::weaken" on
       Perl 5.36 or above) yourself.

       :param, :param(NAME)

       Since version 0.41.

       Sets this field to be initialised automatically in the generated
       constructor.  This is only permitted on scalar fields. If no name is
       given, the name of the field is used. A single prefix character "_"
       will be removed if present.

       Any field that has ":param" but does not have a default initialisation
       expression or block becomes a required argument to the constructor.
       Attempting to invoke the constructor without a named argument for this
       will throw an exception. In order to make a parameter optional, make
       sure to give it a default expression - even if that expression is
       "undef":

          field $x :param;          # this is required
          field $z :param = undef;  # this is optional

       Any field that has a ":param" and an initialisation block will only run
       the code in the block if required by the constructor. If a named
       parameter is passed to the constructor for this field, then its code
       block will not be executed.

       Values for fields are assigned by the constructor before any "BUILD"
       blocks are invoked.

       Field Initialiser Expressions

       Since version 0.54 a deferred statement block is also permitted, on any
       field variable type. This permits code to be executed as part of the
       instance constructor, rather than running just once when the class is
       set up. Code in a field initialisation block is roughly equivalent to
       being placed in a "BUILD" or "ADJUST" block.

       Since version 0.73 this may also be written as a plain expression
       introduced by an equals symbol ("="). This is equivalent to using a
       block.  Note carefully: the equals symbol is part of the "field"
       syntax; it is not simply a runtime assignment operator that happens
       once at the time the class is declared. Just like the block form
       describe above, the expression is evaluated during the constructor of
       every instance.

       Since version 0.74 this expression may also be written using a defined-
       or or logical-or assignment operator ("//=" or "||="). In these case,
       the default expression will be evaluated and assigned if the caller did
       not pass a value to the constructor at all, or if the value passed was
       undef (for "//=") or false (for "||="). For most scalar parameters,
       where "undef" is not a valid value, you probably wanted to use "//=" to
       assign defaults.

          class Action {
             field $timeout :param //= 20;
             ...
          }

          # The default of 20 will apply here too
          my $act = Action->new( timeout => $opts{timeout} );

       Note that $self is specifically not visible during an initialiser
       expression. This is because the object is not yet fully constructed, so
       it would be dangerous to allow access to it while in this state.
       However, the "__CLASS__" keyword is available, so initialiser
       expressions can make use of class-based dispatch to invoke class-level
       methods to help provide values.

       This feature should be considered partly experimental and may emit
       warnings to that effect. They can be silenced with

          use Object::Pad ':experimental(init_expr)';

       Since version 0.76 expressions that are purely compiletime constants
       (either as single scalars or entire lists of constants) are no longer
       considered experimental. They can be used without silencing the
       warning.

       Control flow that attempts to leave a field initialiser expression or
       block is not permitted. This includes any "return" expression, any
       "next/last/redo" outside of a loop, with a dynamically-calculated label
       expression, or with a label that it doesn't appear in. "goto"
       statements are also currently forbidden, though known-safe ones may be
       permitted in future.

       Loop control expressions that are known at compiletime to affect a loop
       that they appear within are permitted.

          field $x { foreach(@list) { next; } }       # this is fine

          field $x { LOOP: while(1) { last LOOP; } }  # this is fine too

   has
          has $var;
          has @var;
          has %var;

          has $var = EXPR;

          has $var { BLOCK }

       An older version of the "field" keyword.

       This generally behaves like "field", except that inline expressions are
       evaluated immediately, once, during class declaration time. These are
       not stored to be evaluated for each constructor.

       Because of the one-shot immediate nature of these initialisation
       expressions (and a bunch of other reasons), the "has" keyword is now
       discouraged for use.  Use the "field" keyword instead.

       If you need to evaluate an expression exactly once during the class
       declaration and assign its now-constant value to every instace, store
       it in a regular "my" variable instead:

          my $default_var = EXPR;
          field $var = $default_var;

   method
          method NAME {
             ...
          }

          method NAME (SIGNATURE) {
             ...
          }

          method NAME :ATTRS... {
             ...
          }

          method NAME;

       Declares a new named method. This behaves similarly to the "sub"
       keyword, except that within the body of the method all of the member
       fields are also accessible. In addition, the method body will have a
       lexical called $self which contains the invocant object directly; it
       will already have been shifted from the @_ array.

       If the method has no body and is given simply as a name, this declares
       a required method for a role. Such a method must be provided by any
       class that implements the role. It will be a compiletime error to
       combine the role with a class that does not provide this.

       The "signatures" feature is automatically enabled for method
       declarations. In this case the signature does not have to account for
       the invocant instance; that is handled directly.

          method m ($one, $two) {
             say "$self invokes method on one=$one two=$two";
          }

          ...
          $obj->m(1, 2);

       A list of attributes may be supplied as for "sub". The most useful of
       these is ":lvalue", allowing easy creation of read-write accessors for
       fields (but see also the ":reader", ":writer" and ":mutator" field
       attributes).

          class Counter {
             field $count;

             method count :lvalue { $count }
          }

          my $c = Counter->new;
          $c->count++;

       Every method automatically gets the ":method" attribute applied, which
       suppresses warnings about ambiguous calls resolved to core functions if
       the name of a method matches a core function.

       The following additional attributes are recognised by "Object::Pad"
       directly:

       :override

       Since version 0.29.

       Marks that this method expects to override another of the same name
       from a superclass. It is an error at compiletime if the superclass does
       not provide such a method.

       :common

       Since version 0.62.

       Marks that this method is a class-common method, instead of a regular
       instance method. A class-common method may be invoked on class names
       instead of instances. Within the method body there is a lexical $class
       available, rather than $self. Because it is not associated with a
       particular object instance, a class-common method cannot see instance
       fields.

   method (lexical)
          method $var { ... }

          method $var :ATTRS... (SIGNATURE) { ... }

       Since version 0.59.

       Declares a new lexical method. Lexical methods are not visible via the
       package namespace, but instead are stored directly in a lexical
       variable (with the same scoping rules as regular "my" variables). These
       can be invoked by subsequent method code in the same block by using
       "$self->$var(...)"  method call syntax.

          class WithPrivate {
             field $var;

             # Lexical methods can still see instance fields as normal
             method $inc_var { $var++; say "Var was incremented"; }
             method $dec_var { $var--; say "Var was decremented"; }

             method bump {
                $self->$inc_var;
                say "In the middle";
                $self->$dec_var;
             }
          }

          my $obj = WithPrivate->new;

          $obj->bump;

          # Neither $inc_var nor $dec_var are visible here

       This effectively provides the ability to define private methods, as
       they are inaccessible from outside the block that defines the class. In
       addition, there is no chance of a name collision because lexical
       variables in different scopes are independent, even if they share the
       same name. This is particularly useful in roles, to create internal
       helper methods without letting those methods be visible to callers, or
       risking their names colliding with other named methods defined on the
       consuming class.

   BUILD
          BUILD {
             ...
          }

          BUILD (SIGNATURE) {
             ...
          }

       Since version 0.27.

       Declares the builder block for this component class. A builder block
       may use subroutine signature syntax, as for methods, to assist in
       unpacking its arguments. A build block is not a subroutine and thus is
       not permitted to use subroutine attributes (for example ":lvalue").

       Note that a "BUILD" block is a named phaser block and not a method.
       Attempts to create a method named "BUILD" (i.e. with syntax "method
       BUILD {...}") will fail with a compiletime error, to avoid this
       confusion.

   ADJUST
          ADJUST {
             ...
          }

       Since version 0.43.

       Declares an adjust block for this component class. This block of code
       runs within the constructor, after any "BUILD" blocks and automatic
       field value assignment. It can make any final adjustments to the
       instance (such as initialising fields from calculated values).

       An adjust block is not a subroutine and thus is not permitted to use
       subroutine attributes (except see below). Note that an "ADJUST" block
       is a named phaser block and not a method; it does not use the "sub" or
       "method" keyword.

       Currently, an "ADJUST" block receives a reference to the hash
       containing the current constructor arguments, as per "ADJUSTPARAMS"
       (see below). This was added in version 0.66 but will be removed again
       as it conflicts with the more flexible and generally nicer named-
       parameter "ADJUST :params" syntax (see below). Such uses should be
       considered deprecated. A warning will be printed to indicate this
       whenever an "ADJUST" block uses a signature. This warning can be
       quieted by using "ADJUSTPARAMS" instead. Additionally, a warning may be
       printed on code that attempts to access the params hashref via the @_
       array.

   ADJUST :params
          ADJUST :params ( :$var1, :$var2, ... ) {
             ...
          }

          ADJUST :params ( :$var1, :$var2, ..., %varN ) {
             ...
          }

       Since version 0.70.

       An "ADJUST" block can marked with a ":params" attribute, meaning that
       it consumes additional constructor parameters by assigning them into
       lexical variables.

       This feature should be considered experimental, and will emit warnings
       to that effect. They can be silenced with

          use Object::Pad ':experimental(adjust_params)';

       Before the block itself, a list of lexical variables are introduced,
       inside parentheses. The name of each one is preceeded by a colon, and
       consumes a constructor parameter of the same name. These parameters are
       considered "consumed" for the purposes of a ":strict(params)" check.

       A named parameter may be provided with default expression, which is
       evaluated if no matching named argument is provided to the constructor.
       As with fields, if a named parameter has no defaulting expression it
       becomes a required argument to the constructor; an exception is thrown
       by the constructor if it absent.

       For example,

          ADJUST :params ( :$x, :$y = "default", :$z ) { ... }

       Note here that "x" and "z" are required parameters for the constructor
       of a class containing this block, but "y" is an optional parameter
       whose value will be filled in by the expression if not provided.
       Because these parameters are named and not positional, there is no
       ordering constraint; required and optional parameters can be freely
       mixed.

       Optional parameters can also use the "//=" and "||=" operators to
       provide a default expression. In these cases, the default will be
       applied if the caller did not provide the named argument at all, or if
       the provided value was not defined (for "//=") or not true (for "||=").

          ADJUST :params ( :$name //= "unnamed" ) { ... }

       Like with subroutine signature parameters, every declared named
       parameter is visible to the defaulting expression of all the later
       ones. This permits values to be calculated based on other ones. For
       example,

          ADJUST :params ( :$thing = undef, :$things = [ $thing ] ) {
             # Here, @$things is a list of values
          }

       This permits the caller to pass a list of values via an array reference
       in the "things" parameter, or a single value in "thing".

       The final element may be a regular hash variable. This requests that
       all remaining named parameters are made available inside it. The code
       in the block should "delete" from this hash any parameters it wishes to
       consume, as with the earlier case above.

       It is unspecified whether named fields or parameters for subclasses yet
       to be processed are visible to hashes of earlier superclasses. In the
       current implementation they are, but code should not rely on this fact.

       Note also that there must be a space between the ":params" attribute
       and the parentheses holding the named parameters. If this space is not
       present, perl will parse the parentheses as if they are the value to
       the ":params()" attribute, and this will fail to parse as intended. As
       with other attributes and subroutine signatures, this whitespace is
       significant.

       (This notation is borrowed from a plan to add named parameter support
       to perl's subroutine signature syntax).

   ADJUSTPARAMS
       Since version 0.51.

          ADJUSTPARAMS ( $params ) {    # on perl 5.26 onwards
             ...
          }

          ADJUST {
             my $params = shift;
             ...
          }

       A variant of an "ADJUST" block that receives a reference to the hash
       containing the current constructor parameters. This hash will not
       contain any constructor parameters already consumed by ":param"
       declarations on any fields, but only the leftovers once those are
       processed.

       The code in the block should "delete" from this hash any parameters it
       wishes to consume. Once all the "ADJUST" blocks have run, any remaining
       keys in the hash will be considered errors, subject to the
       ":strict(params)" check.

   __CLASS__
          my $classname = __CLASS__;

       Since version 0.72.

       Only valid within the body (or signature) of a "method", an "ADJUST"
       block, or the initialising expression of a "field". Yields the class
       name of the instance that the method, block or expression is invoked
       on.

       This is similar to the core perl "__PACKAGE__" constant, except that it
       cares about the dynamic class of the actual instance, not the static
       class the code belongs to. When invoked by a subclass instance that
       inherited code from its superclass it yields the name of the class of
       the instance regardless of which class defined the code.

       For example,

          class BaseClass {
             ADJUST { say "Constructing an instance of " . __CLASS__; }
          }

          class DerivedClass :isa(BaseClass) { }

          my $obj = DerivedClass->new;

       Will produce the following output

          Constructing an instance of DerivedClass

       This is particularly useful in field initialisers for invoking
       (constant) methods on the invoking class to provide default values for
       fields. This way a subclass could provide a different value.

          class Timer {
             use constant DEFAULT_DURATION => 60;
             field $duration = __CLASS__->DEFAULT_DURATION;
          }

          class ThreeMinuteTimer :isa(Timer) {
             use constant DEFAULT_DURATION => 3 * 60;
          }

   requires
          requires NAME;

       Declares that this role requires a method of the given name from any
       class that implements it. It is an error at compiletime if the
       implementing class does not provide such a method.

       This form of declaring a required method is now vaguely discouraged, in
       favour of the bodyless "method" form described above.

CREPT FEATURES
       While not strictly part of being an object system, this module has
       nevertheless gained a number of behaviours by feature creep, as they
       have been found useful.

   Implied Pragmata
       In order to encourage users to write clean, modern code, the body of
       the "class" block acts as if the following pragmata are in effect:

          use strict;
          use warnings;
          no indirect ':fatal';  # or  no feature 'indirect' on perl 5.32 onwards
          use feature 'signatures';

       This list may be extended in subsequent versions to add further
       restrictions and should not be considered exhaustive.

       Further additions will only be ones that remove "discouraged" or
       deprecated language features with the overall goal of enforcing a more
       clean modern style within the body. As long as you write code that is
       in a clean, modern style (and I fully accept that this wording is vague
       and subjective) you should not find any new restrictions to be majorly
       problematic. Either the code will continue to run unaffected, or you
       may have to make some small alterations to bring it into a conforming
       style.

   Yield True
       A "class" statement or block will yield a true boolean value. This
       means that it can be used directly inside a .pm file, avoiding the need
       to explicitly yield a true value from the end of it.

SUBCLASSING CLASSIC PERL CLASSES
       There are a number of details specific to the case of deriving an
       "Object::Pad" class from an existing classic Perl class that is not
       implemented using "Object::Pad".

   Storage of Instance Data
       Instances will pick either the ":repr(HASH)" or ":repr(magic)" storage
       type.

   Object State During Methods Invoked By Superclass Constructor
       It is common in classic Perl OO style to invoke methods on $self during
       the constructor. This is supported here since "Object::Pad" version
       0.19.  Note however that any methods invoked by the superclass
       constructor may not see the object in a fully consistent state. (This
       fact is not specific to using "Object::Pad" and would happen in classic
       Perl OO as well). The field initialisers will have been invoked but the
       "BUILD" and "ADJUST" blocks will not.

       For example; in the following

          package ClassicPerlBaseClass {
             sub new {
                my $self = bless {}, shift;
                say "Value seen by superconstructor is ", $self->get_value;
                return $self;
             }
             sub get_value { return "A" }
          }

          class DerivedClass :isa(ClassicPerlBaseClass) {
             field $_value = "B";
             ADJUST {
                $_value = "C";
             }
             method get_value { return $_value }
          }

          my $obj = DerivedClass->new;
          say "Value seen by user is ", $obj->get_value;

       Until the "ClassicPerlBaseClass::new" superconstructor has returned the
       "ADJUST" block will not have been invoked. The $_value field will still
       exist, but its value will be "B" during the superconstructor. After the
       superconstructor, the "BUILD" and "ADJUST" blocks are invoked before
       the completed object is returned to the user. The result will therefore
       be:

          Value seen by superconstructor is B
          Value seen by user is C

STYLE SUGGESTIONS
       While in no way required, the following suggestions of code style
       should be noted in order to establish a set of best practices, and
       encourage consistency of code which uses this module.

   $VERSION declaration
       While it would be nice for CPAN and other toolchain modules to parse
       the embedded version declarations in "class" statements, the current
       state at time of writing (June 2020) is that none of them actually do.
       As such, it will still be necessary to make a once-per-file $VERSION
       declaration in syntax those modules can parse.

       Further note that these modules will also not parse the "class"
       declaration, so you will have to duplicate this with a "package"
       declaration as well as a "class" keyword. This does involve repeating
       the package name, so is slightly undesirable.

       It is hoped that eventually upstream toolchain modules will be adapted
       to accept the "class" syntax as being sufficient to declare a package
       and set its version.

       See also

       • <https://github.com/Perl-Toolchain-Gang/Module-Metadata/issues/33>

   File Layout
       Begin the file with a "use Object::Pad" line; ideally including a
       minimum-required version. This should be followed by the toplevel
       "package" and "class" declarations for the file. As it is at toplevel
       there is no need to use the block notation; it can be a unit class.

       There is no need to "use strict" or apply other usual pragmata; these
       will be implied by the "class" keyword.

          use Object::Pad 0.16;

          package My::Classname 1.23;
          class My::Classname;

          # other use statements

          # field, methods, etc.. can go here

   Field Names
       Field names should follow similar rules to regular lexical variables in
       code - lowercase, name components separated by underscores. For tiny
       examples such as "dumb record" structures this may be sufficient.

          class Tag {
             field $name  :mutator;
             field $value :mutator;
          }

       In larger examples with lots of non-trivial method bodies, it can get
       confusing to remember where the field variables come from (because we
       no longer have the "$self->{ ... }" visual clue). In these cases it is
       suggested to prefix the field names with a leading underscore, to make
       them more visually distinct.

          class Spudger {
             field $_grapefruit;

             ...

             method mangle {
                $_grapefruit->peel; # The leading underscore reminds us this is a field
             }
          }

WITH OTHER MODULES
   Syntax::Keyword::Dynamically
       A cross-module integration test asserts that "dynamically" works
       correctly on object instance fields:

          use Object::Pad;
          use Syntax::Keyword::Dynamically;

          class Container {
             field $value = 1;

             method example {
                dynamically $value = 2;
                ,..
                # value is restored to 1 on return from this method
             }
          }

   Future::AsyncAwait
       As of Future::AsyncAwait version 0.38 and Object::Pad version 0.15,
       both modules now use XS::Parse::Sublike to parse blocks of code.
       Because of this the two modules can operate together and allow class
       methods to be written as async subs which await expressions:

          use Future::AsyncAwait;
          use Object::Pad;

          class Example
          {
             async method perform ($block)
             {
                say "$self is performing code";
                await $block->();
                say "code finished";
             }
          }

       These three modules combine; there is additionally a cross-module test
       to ensure that object instance fields can be "dynamically" set during a
       suspended "async method".

   Devel::MAT
       When using Devel::MAT to help analyse or debug memory issues with
       programs that use "Object::Pad", you will likely want to additionally
       install the module Devel::MAT::Tool::Object::Pad. This will provide new
       commands and extend existing ones to better assist with analysing
       details related to "Object::Pad" classes and instances of them.

          pmat> fields 0x55d7c173d4b8
          The field AV ARRAY(3)=NativeClass at 0x55d7c173d4b8
          Ix Field   Value
          0  $sfield SCALAR(UV) at 0x55d7c173d938 = 123
          ...

          pmat> identify 0x55d7c17606d8
          REF() at 0x55d7c17606d8 is:
          XXthe %hfield field of ARRAY(3)=NativeClass at 0x55d7c173d4b8, which is:
          ...

DESIGN TODOs
       The following points are details about the design of pad field-based
       object systems in general:

       •   Is multiple inheritance actually required, if role composition is
           implemented including giving roles the ability to use private
           fields?

       •   Consider the visibility of superclass fields to subclasses. Do
           subclasses even need to be able to see their superclass's fields,
           or are accessor methods always appropriate?

           Concrete example: The "$self->{split_at}" access that
           Tickit::Widget::HSplit makes of its parent class
           Tickit::Widget::LinearSplit.

IMPLEMENTATION TODOs
       These points are more about this particular module's implementation:

       •   Consider multiple inheritance of subclassing, if that is still
           considered useful after adding roles.

       •   Work out why "no indirect" doesn't appear to work properly before
           perl 5.20.

       •   Work out why we don't get a "Subroutine new redefined at ..."
           warning if we

             sub new { ... }

       •   The "local" modifier does not work on field variables, because they
           appear to be regular lexicals to the parser at that point. A
           workaround is to use Syntax::Keyword::Dynamically instead:

              use Syntax::Keyword::Dynamically;

              field $loglevel;

              method quietly {
                 dynamically $loglevel = LOG_ERROR;
                 ...
              }

FEEDBACK
       The following resources are useful forms of providing feedback,
       especially in the form of reports of what you find good or bad about
       the module, requests for new features, questions on best practice,
       etc...

       •   The RT queue at
           <https://rt.cpan.org/Dist/Display.html?Name=Object-Pad>.

       •   The "#cor" IRC channel on "irc.perl.org".

SPONSORS
       With thanks to the following sponsors, who have helped me be able to
       spend time working on this module and other perl features.

       •   Oetiker+Partner AG <https://www.oetiker.ch/en/>

       •   Deriv <http://deriv.com>

       •   Perl-Verein Schweiz <https://www.perl-workshop.ch/>

       Additional details may be found at
       <https://github.com/Ovid/Cor/wiki/Sponsors>.

AUTHOR
       Paul Evans <leonerd@leonerd.org.uk>

perl v5.36.0                      2023-01-13                  Object::Pad(3pm)

Generated by dwww version 1.15 on Tue Jun 25 08:09:32 CEST 2024.