jdporter has asked for the wisdom of the Perl Monks concerning the following question:

The doco saith:

Fields may optionally have initializing expressions. . . . the expression can . . . see any other variables in scope.
class WithACounter { my $next_count = 1; field $count = $next_count++; }

But it doesn't say that any other kind of code can be present there. For example, maybe I'd like to do this:

class WithACounter { my $next_count = 1; if (last_one_was_bad()) { delete_last_one(); $next_count--; } field $count = $next_count++; }

Would that be permitted?

Also: it looks like the my variables there are essentially "class static" members — so called in other languages e.g. C#. Is that an accurate characterization?

Today's latest and greatest software contains tomorrow's zero day exploits.

Replies are listed 'Best First'.
Re: perl 5.38: can the body of a class declaration contain arbitrary code?
by haj (Vicar) on Jul 04, 2023 at 21:54 UTC
    Code in a class block behaves like code in a package block: It is evaluated once. So last_one_was_bad is executed once. The next_count++ statement is executed on every creation of a WithACounter object (if next_count was flagged as a :param, then it would be executed only if the caller didn't specify it).
    Also: it looks like the my variables there are essentially "class static" members — so called in other languages e.g. C#. Is that an accurate characterization?

    Pretty much yes. There is a discussion whether the class system needs its own syntax for "class static" members, but this is about convenience details which are not yet implemented: A "field" in Object::Pad can get attributes like :reader which will create appropriate accessor functions. You might want to permit a field $foo :static :reader, but there was some opposition against my $foo :reader which would make the syntax of the existing my keyword depend on the context. Damian Conway points out that a my variable is a private implementation detail, but a static field with a reader is part of the class interface (and maybe subject to inheritance). As far as Perl 5.38 is concerned, the distinction doesn't exist.

      Code in a class block behaves like code in a package block: It is evaluated once.

      Ok, thanks. I can see the reason for that. Principle of least surprise. But I was kinda hoping they had gone for something like Scala's semantics, where all code in the class definition outside of methods constitutes the constructor.

      Today's latest and greatest software contains tomorrow's zero day exploits.

        There is a place for code which goes into the constructor: It is the ADJUST block. So you can have both: Class initialization as in my $next_count = 1, and constructor code.

        "Class methods" in Perl 5.38 are just subs. So, to expand your example:

        use 5.038; use feature 'class'; no warnings 'experimental'; class WithACounter { my $next_count = 1; # class initialization, called once my sub last_one_was_bad() { 0 } my sub delete_last_one() { ...; } field $count = $next_count++; ADJUST { if (last_one_was_bad()) { delete_last_one(); $next_count--; } } }
Re: perl 5.38: can the body of a class declaration contain arbitrary code?
by parv (Parson) on Jul 04, 2023 at 21:11 UTC

    my variables in class would behave as they do in a package, per ...

    The class keyword declares a new package which is intended to be a class
    ...
    class and package declarations are similar, but classes automatically get a constructor named new - You don't have to (and should not) write one.