learning.moose has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks.

I have a class containing text attribute, but I don't want to create printText method inside that class. I would rather create separate object that will manage my print and formatting.

This is where the problem starts. I don't want inheritance, would rather do it with roles. How can I make role read/edit fields (attributes) in a class directly, so I can do it with a code like this:

my $text = TextClass->new( text => 'some text'); $text->interfacePrint->methodPrintWithinInterface();

I dont want to pass $text->text attribute directly.

$text->interfacePrint->methodPrintWithinInterface( $text->text );

^ This is how I dont want to do it

Replies are listed 'Best First'.
Re: delete pls
by ww (Archbishop) on Apr 25, 2015 at 18:33 UTC

    Downvoted -- solely because you removed the question.

    Deleting content once posted is contrary to the values here in the Monastery -- even if (as may be the case) posting your question -- by itself -- unkinked some neuron pathway that told you the answer. (This is known as "the teddy bear effect" (on which, you can read more by searching this site).

    In fact, if that's the case, you might have been upvoted if you'd posted an answer to yourself with a viable solution. Or, had others given you answers, deleting your question deprives any response of its context... and thus, of its value for future readers.

    Please don't delete anything you've posted. If you must disavow it, leave it in place and surround it with <strike> ... </strike> tags.


    <
    Come, let us reason together: Spirit of the Monastery
      Ok, sorry. I thought I managed to find answer to my problem and there wasn't delete option. I'll use my topic to post my problem again.
        When you find the answer to your own question, it's better to post the solution rather than to delete the question. It can help others when they have similar problems. Your current question is quite different to the original one, though, please read How do I change/delete my post?.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Moose attribute modification
by kcott (Archbishop) on Apr 25, 2015 at 21:24 UTC

    G'day learning.moose,

    Is this the type of thing you had in mind?

    #!/usr/bin/env perl -l use strict; use warnings; # Role: TextHolder { package TextHolder; use Moose::Role; has text => ( is => 'rw', isa => 'Str', ); } # Class: TextReference { package TextReference; use Moose; with 'TextHolder'; sub read_text { my $self = shift; return $self->text; } } my $tref_early = TextReference::->new({text => 'early'}); my $tref_late = TextReference::->new; $tref_late->text('late'); print 'Early: ', $tref_early->read_text; print 'Late: ', $tref_late->read_text;

    Output:

    $ pm_1124686_moose_role_attrs.pl Early: early Late: late

    -- Ken

      Wow this is so awesome! Didn't know that attributes from roles can be accessed in class so directly. Thank you
Re: Moose attribute modification
by CountZero (Bishop) on Apr 26, 2015 at 09:00 UTC
    Indeed Moose Roles can do this kind of thing easily.

    First we start with your basic "TextClass" class:

    package TextClass; use Moose; has 'text' => ( is => 'rw', isa => 'Str', ); with 'PrettyPrint'; no Moose; __PACKAGE__->meta->make_immutable; 1;
    Note the with 'PrettyPrint'; That is the module which contains the role we will add.

    We make another module to implement the "prettyprint" role:

    package PrettyPrint; use Moose::Role; requires 'text'; sub prettyprint { my $self = shift; print "So handsome:\n\t", $self->text, "\nYeah, sure!\n"; $self; } 1;
    The prettyprint sub from this module will now become a method in your 'TextClass' class or any other class that provides a text method. That is what the requires 'text' takes care of. Use this role in another class that doesn't provide the text method and it will complain and end the compilation of your script.

    As you see, the methods in your Role-module have access to all the public methods of your object, even those which are provided auto-magically by Moose itself, such as the getters and setters, in this case the text method.

    Using all this now is standard:

    use Modern::Perl qw/2014/; use lib 'D:/Perl/scripts'; # or wherever you have saved the modules use TextClass; my $person = TextClass->new( text => q/I'm CountZero/ ); $person->prettyprint;
    Output:
    So handsome: I'm CountZero Yeah, sure!
    Note, that a Role isn't a class: it cannot be instantiated on its own, it will not provide its own objects. Rather it is a bunch of subroutines that get directly included in your basic class without any intermediary object. So you do not do $text->PrettyPrint::prettyprint or $text->PrettyPrintObject->prettyprint

    Update: clarified about adding a Role module.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

      This is exactly what I was trying to perform. The only difference was that text was not build in type but my own class

      has 'text' => ( is => 'rw', isa => 'TextClass', );

      I found a way around that, and don't have the exact code to see what I was doing wrong in that exact moment. But now I know that I was doing this in proper way, but the error was somewhere else.

      Thank you

        If you want to use your own type, then have a look at MooseX::Types.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics