in reply to perl 5.38: can the body of a class declaration contain arbitrary code?

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.

  • Comment on Re: perl 5.38: can the body of a class declaration contain arbitrary code?

Replies are listed 'Best First'.
Re^2: perl 5.38: can the body of a class declaration contain arbitrary code?
by jdporter (Paladin) on Jul 05, 2023 at 13:27 UTC
    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--; } } }

        But that's not the same. That performs the "adjustment" after the initialization of the field, whereas in my example it happens before. But reading the doco a little closer, it looks like ADJUST code is executed "in line" where it occurs in the class definition. So the following would in fact be equivalent to my original (invalid) suggestion:

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

        Given that, then it would appear that Scala-like class definition is possible; one simply has to wrap any statements other than my/field in ADJUST blocks.