in reply to Role::Tiny: When to use apply_roles_to_object?

One example might be you have a Backend class where your app sends all its data. You might instantiate the backend object like this:

my $backend = Backend->new(); Role::Tiny->apply_roles_to_object( $backend, qw( Backend::Storage::PostgreSQL Backend::Log::Debug Backend::Interf +ace::TCP ), );

And now your backend object will store its data in PostgreSQL, and spit out debugging information to its log file, and listen on a TCP port for instructions.

If you have eight different possibilities for storage (different types of database, XML files, JSON files, etc), 4 different options for logging, and 4 different interfaces (TCP, Unix Sockets, Command Line, and HTTP), that gives 128 possible combinations. You don't really want to have to create classes for Backend::PostgreSQL_Debugging_TCP, Backend::MySQL_Debugging_TCP, Backend::PostgreSQL_Debugging_HTTP, etc. Instead you just compose the combination of roles you want.

(In this particular example, there's an argument for making more use of delegation instead of composition, but I digress.)

Replies are listed 'Best First'.
Re^2: Role::Tiny: When to use apply_roles_to_object?
by LanX (Saint) on May 03, 2019 at 17:57 UTC
    > In this particular example, there's an argument for making more use of delegation instead of composition

    actually I also had rather delegation in mind when answering this question.

    As far as I understood does Role::Tiny -> apply_roles_to_object() actually create a new anonymous package and is reblessing the object. °

    IMHO delegation sounds like a better approach, unless the performance penalty of the extra forwarding sub matters.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

    °) quote "Object is reblessed into the resulting class."

      That's how it works, but should be considered an internal implementation detail.

      Delegation is probably a better approach for the example I used earlier, but it requires the base class to have prior knowledge of the kinds of "plugin functionality" that will be added to it, so that it knows when to delegate to them. In many cases, the base class won't have prior knowledge.

        > but it requires the base class to have prior knowledge of the kinds of "plugin functionality" that will be added to it, so that it knows when to delegate to them.

        Hmm, ... in theory it should be possible to combine roles and delegation.

        Such that the role plugs in the delegations and apply_roles_to_object is blessing the object into the new singleton class.

        Will try it out next week.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      "does Role::Tiny -> apply_roles_to_object() actually create a new anonymous package and is reblessing the object"

      That's a feature.

      use strict; use warnings; use feature 'say'; use Role::Tiny; package MyClass { use Moo }; package MyRole { use Moo::Role }; my $o = MyClass->new; Role::Tiny->apply_roles_to_object($o, 'MyRole'); say ref($o);
      Output:
      MyClass__WITH__MyRole


      The way forward always starts with a minimal test.
Re^2: Role::Tiny: When to use apply_roles_to_object?
by karlgoethebier (Abbot) on May 05, 2019 at 11:39 UTC

    Thank you. Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help