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

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--; } } }
  • Comment on Re^3: perl 5.38: can the body of a class declaration contain arbitrary code?
  • Download Code

Replies are listed 'Best First'.
Re^4: perl 5.38: can the body of a class declaration contain arbitrary code?
by jdporter (Paladin) on Jul 05, 2023 at 18:59 UTC

    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.

      Careful, that is misleading. The field initializers run before ADJUST, regardless of the order in which they are written. This has been specified in the Corinna RFC and is how it is implemented. I don't see it specified in the docs, though, which is a bad omission and should be fixed for 5.38.1. Demo code here:

      use 5.038; use feature 'class'; no warnings 'experimental'; class WithACounter { my $next_count = 1; ADJUST { say "Next count in ADJUST: $next_count"; } field $count = do { say "Next count in field init: ", $next_count; $next_count++; }; method count { $count } } say "Next count in the object: ",WithACounter->new->count;

      Output:

      Next count in field init: 1 Next count in ADJUST: 2 Next count in the object: 1
      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.

      This is true. Since $count = $next_count++; is an initialization with a side effect (incrementing a class variable), I would also move that into the ADJUST block. It is the only way to get it executed after other code in ADJUST.

        The field initializers run before ADJUST, regardless of the order in which they are written.

        Well that just fscking sucks. It makes Scala-like code impossible. May as well just declare all the fields and then put all the code in one ADJUST block. :-#