Cataly...mponent(3pm)

πŸ“¦
version 5.90132 Β· 6 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

πŸ’– NAME πŸ’–

Catalyst::Component β€” the Catalyst Component Base Class 🫢

okay so bestie, welcome to Cataly...mponent(3pm) β€” yes that's the truncated little nickname the terminal gives it, it's giving mystery, it's giving ✨enigmatic✨. It's a Perl man page from the User Contributed Perl Documentation collection. Let's get into it. πŸ’…


🌸 SYNOPSIS 🌸

    # lib/MyApp/Model/Something.pm
    package MyApp::Model::Something;

    use base 'Catalyst::Component';

    __PACKAGE__->config( foo => 'bar' );

    has foo => (
        is => 'ro',
    );

    sub test {
        my $self = shift;
        return $self->foo;
    }

    sub forward_to_me {
        my ( $self, $c ) = @_;
        $c->response->output( $self->foo );
    }

    1;

    # Methods can be a request step
    $c->forward(qw/MyApp::Model::Something forward_to_me/);

    # Or just methods
    print $c->comp('MyApp::Model::Something')->test;

    print $c->comp('MyApp::Model::Something')->foo;

like. look at her go. πŸ¦‹ a whole component in like 20 lines and she's thriving.


✨ DESCRIPTION ✨

So this is the universal base class for Catalyst components β€” that's Model, View, and Controller, the whole trio, the main character energy of the framework. πŸ‘‘

What it hands you, no cap:

  • a generic new() for building your component, wired up through Catalyst's component loader, with config() support
  • a process() method that's just a placeholder chilling there
⚠️ big warning, bestie, listen up: calling $self->config inside a component is strongly not recommended. The correctly merged config should already have been passed to the constructor and stashed in your attributes. If you go grabbing the config accessor straight off an instance, you're likely to get the wrong values β€” because it only holds the class-wide config, not the stuff loaded from the config file! 😭 iykyk.

πŸŽ€ METHODS πŸŽ€

πŸ’œ new($app, $arguments)

Called by COMPONENT to actually instantiate the component. It should return an object, and that object gets stored in the application's component hash. slay.

πŸ’œ COMPONENT

"my $component_instance = $component->COMPONENT($app, $arguments);"

If this method is present (and btw it is present on every Catalyst::Component subclass, no exceptions 🫢), Catalyst calls it during setup_components with:

  • the application class as $app
  • any config entry on the application for this component β€” like, for MyApp::Controller::Foo that'd be "MyApp->config('Controller::Foo' => \%conf"

The arguments are expected to be a hashref and get merged with the __PACKAGE__->config hashref before ->new is called to instantiate the component. ✨

You can totally override it in your own components for custom construction, like this:

  sub COMPONENT {
      my ($class, $app, $args) = @_;
      $args = $class->merge_config_hashes($class->config, $args);
      return $class->new($app, $args);
  }
πŸ“Œ NOTE: Generally when Catalyst starts, it initializes all the components and passes the hashref present in any configuration information to the COMPONENT method. For example
    MyApp->config(
      'Model::Foo' => {
        bar => 'baz',
      });

You'd expect COMPONENT to be called like this β†’ COMPONENT( 'MyApp', +{ bar=>'baz'});

And this happens ONCE during setup. one time. periodt. πŸ”₯

πŸ’œ $c->config

πŸ’œ $c->config($hashref)

πŸ’œ $c->config($key, $value, ...)

Accessor for this component's config hash. You can set config values as key value pairs, or you can hand over a hashref β€” either way the keys get merged with whatever config settings already exist. Every single component in a Catalyst application has its own config hash. πŸ’…

That config hash gets merged with any config entry on the application for this component and passed to new() (as mentioned above at "COMPONENT" πŸ‘€). And the recommended practice for getting at the merged config is to use a Moose attribute for each config entry on the receiving component. that's the vibe.

πŸ’œ $c->process()

This is the default method that gets called on a Catalyst component in the dispatcher. For instance, Views implement this action to render the response body when you forward to them. The default is an abstract method.

πŸ’œ $c->merge_config_hashes( $hashref, $hashref )

Merges two hashes together recursively, giving right-hand precedence. It's an alias for the method in Catalyst::Utils. 🧚

πŸ’œ $c->expand_modules( $setup_component_config )

Returns a list of extra components that this component has created. By default it just looks for a list of inner packages of this component. 🌈


πŸ¦‹ OPTIONAL METHODS πŸ¦‹

🌟 ACCEPT_CONTEXT($c, @args)

Catalyst components are normally initialized during server startup, either as a Class or an Instance. But some components need info about the current request. For that, they can implement an ACCEPT_CONTEXT method. πŸ’–

If this method is present, it gets called during $c->comp/controller/model/view with the current $c and any additional args (so like, $c->model('Foo', qw/bar baz/) would cause your MyApp::Model::Foo instance's ACCEPT_CONTEXT to be called with ($c, 'bar', 'baz')) β€” and the return value of this method gets returned to the calling code in the application, rather than the component itself. iconic behaviour honestly.

πŸ“Œ NOTE: All classes that are Catalyst::Components will have a COMPONENT method, but classes intended to be factories or generators will have ACCEPT_CONTEXT. If you have initialization arguments (like from configuration) that you want to expose to the ACCEPT_CONTEXT, you should proxy them in the factory instance. For example:
    MyApp::Model::FooFactory;

    use Moose;
    extends 'Catalyst::Model';

    has type => (is=>'ro', required=>1);

    sub ACCEPT_CONTEXT {
      my ($self, $c, @args) = @_;
      return bless { args=>\@args }, $self->type;
    }

    MyApp::Model::Foo->meta->make_immutable;
    MyApp::Model::Foo->config( type => 'Type1' );

And in a controller:

    my $type = $c->model('FooFactory', 1,2,3,4): # $type->isa('Type1')
🚨 NOTE, and this one is serious, no skimming: If you define an ACCEPT_CONTEXT method it MUST check whether the second argument is blessed (meaning it's a context) or not (meaning it's an application class name), and it MUST return something valid for the case when the scope is application. This is required because a component may be called from the application scope even if it requires a context β€” and you have to prevent errors from being issued if that happens. 😭 And remember: not all components that ACCEPT_CONTEXT actually need or use context information (and there's a school of thought that suggests doing so is a design error anyway... πŸ’€).

πŸ‘‘ SEE ALSO πŸ‘‘

Catalyst, Catalyst::Model, Catalyst::View, Catalyst::Controller.


πŸ’œ AUTHORS πŸ’œ

Catalyst Contributors, see Catalyst.pm


This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.


and that's the whole page bestie, you ate it up 🫢 this gorgeous thing shipped as part of perl v5.40.0, dated 2024-11-15 β€” mwah, go build something iconic with it πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from