Perl-Apollo / Corinna

Corinna - Bring Modern OO to the Core of Perl
Artistic License 2.0
156 stars 19 forks source link

Doesn't appear to work with any existing code #105

Open jjn1056 opened 1 year ago

jjn1056 commented 1 year ago

So I tried to use core class with a basic Catalyst controller:

use Moose;
use MooseX::MethodAttributes;
use Example::Syntax;

class Example::Controller::Account :isa(Example::Controller) {

  sub root :At('$path_end/...') Via('../protected')  ($self, $c, $user) {
    $c->action->next($user->account);
  }

    sub prepare_edit :At('...') Via('root') ($self, $c, $account) { 
      $self->view_for('edit', account => $account);
      $c->action->next($account);
    }

      sub edit :Get('edit') Via('prepare_edit') ($self, $c, $account) {
        return  $c->view->set_http_ok;
      }

      sub update :Patch('') Via('prepare_edit') BodyModel ($self, $c, $account, $bm) {
        return $account->update_account($bm) ?
          $c->view->set_http_ok : 
            $c->view->set_http_bad_request;
      }
}

__PACKAGE__->meta->make_immutable;

But when I try to run I get a compile time error:

Class :isa attribute requires a class but "Example::Controller" is not one at lib/Example/Controller/Account.pm line 5.

I'm enabling the class pragma via the 'Example::Syntax' module , it basically does 'use experimental class'.

I would propose that code like this working should be considered mandatory before moving this out of experimental status.

Ovid commented 1 year ago

I'm enabling the class pragma via the 'Example::Syntax' module , it basically does 'use experimental class'.

Hi John. I'm not sure I understand. Can you also show the code for the Example::Syntax module?

If you're just using use experimental 'class'; but leaving the package declaration, the code doesn't know that you really have a class. Instead, you have to have a proper class built. Since I can't see your code, I'm unsure what's happening.

Also, this won't work (it might work now, but we're going to make a distinction between subs and methods, so it will break in the future):

  sub root :At('$path_end/...') Via('../protected')  ($self, $c, $user) {
    $c->action->next($user->account);
  }

Instead:

method root :At('$path_end/...') Via('../protected')  ($c, $user) {
    $c->action->next($user->account);
}

I'm also unsure of how the Moose attributes work with the new class syntax. I've never tried that. Much of the Moose code heavily uses the MOP.

jjn1056 commented 1 year ago

@Ovid

Here's the syntax class

package Example::Syntax;

use strict;
use warnings;

use Import::Into;
use Module::Runtime;

sub importables {
  my ($class) = @_;
  return (
    'utf8',
    'strict',
    'warnings',
    ['feature', ':5.38'],
    ['experimental', 'class', 'try', 'defer'],
  );
}

sub import {
  my ($class, @args) = @_;
  my $caller = caller;
  foreach my $import_proto($class->importables) {
    my ($module, @args) = (ref($import_proto)||'') eq 'ARRAY' ? 
      @$import_proto : ($import_proto, ());
    Module::Runtime::use_module($module)
      ->import::into($caller, @args)
  }
}

1;
jjn1056 commented 1 year ago

@Ovid I put the entire codebase into git https://github.com/jjn1056/Valiant/blob/main/example/lib/Example/Controller/Account.pm if that helps.

jjn1056 commented 1 year ago

I'm just saying maybe things like this working could be part of a 'definition of done' which might take future iterations. And I'm also suggesting as my personal opinion, that maybe this project should start thinking about compatibility.