Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Term::ANSIColor is awesome, but.. (need help)

by mascip (Pilgrim)
on Mar 30, 2014 at 13:17 UTC ( #1080285=perlquestion: print w/ replies, xml ) Need Help??
mascip has asked for the wisdom of the Perl Monks concerning the following question:

Hi there :-)

I've just used Term::ANSIColor in an app for the first time, and found it really awesome. I didn't have to change anything at all in my code: I just declared the colors on some variables.

my $name = colored('Jon', 'red');
and almost all the rest worked as if nothing had been changed, but now my terminal outputs are much more readable.

My problem starts when some commands do string comparison:

do_something() if $name eq 'Jon';
This breaks because $name is not just Jon now, it's red Jon.

One workaraound is to use colorstrip():

do_something() if colorstrip($name) eq 'Jon';
That works, but it means I have to make this change everywhere in the code, which is a pain. Especially when these variables get sent to various objects who do all the hard work.

Is there any way to make this work? Some way of saying: "You're being compared? Wait, I'll colorstrip you first".

If that was included in the Term::ANSIColor module, that would be even better. That's why I just wrote to the module author, to come and read this message.

Any idea how to take advantage of Perl's flexibility and perform this trick?

Comment on Term::ANSIColor is awesome, but.. (need help)
Select or Download Code
Replies are listed 'Best First'.
Re: Ter::ANSIColor is awesome, but.. (need help)
by Corion (Pope) on Mar 30, 2014 at 13:32 UTC

    Separate the program logic and the output.

    Within your program, always keep $name eq 'Jon', and have a routine, output_name(), which does

    print colored($name,'red');

    or a function visual_name, which returns the value, ready for printing as name:

    sub visual_name { my( $name )= @_; colored( $name, 'red' ); };

      Thank you Corion.
      That makes sense, but it doesn't exactly solve my problem. I don't want to make this change in every part of the code where I'm displaying something.

      I guess, most of my print statements are in the same file in fact, apart from exceptions. (Edit: In fact I just realized that I would really like these exceptions to be colourized...)

      I'll try this tomorrow. But I'm still wondering if there is a better way...

        The starting point of my reasoning is:

        There is only one place where I declare the variables that I want to colorize. If I could colorize them then and nowhere else, that would be much simpler.

Re: Term::ANSIColor is awesome, but.. (need help) (overload and override)
by tye (Sage) on Mar 30, 2014 at 19:24 UTC

    Change the module to produce objects with stringification overloaded to return the original string (w/o color escapes). Override the output functions you use (like 'print'), to do something like:

    sub ... { local( $Term::ANSIColor::InOutput ) = 1; return CORE::...( @_ ); }

    and have the stringification include the color escapes if $InOutput is true.

    - tye        

      I had the very same idea but I was thinking of using a global variable. A class variable - or a class attribute - is much better. Thank you!

      And a good thing is that it should also work for exceptions, if I also create a die_color() function.

      1. If I implement this, is it worth sharing it on CPAN?

      2. Is it "bad practice"?

      3. Is there a better way?

      I really like the idea of a string declared with a color, but who behaves just like a normal string in the program. Only the display is colored.

        I would really like to hear people's feedback: Is this String::Colored module a good / bad idea ?

        Additional idea given by a Monger:

        local *CORE::GLOBAL::print = \&String::Colored::sing;
        That's if I want to not need to change anything in my current code, while adding colors. Any warnings against the dangers of this trick would be very welcome :-)

Re: Term::ANSIColor is awesome, but.. (need help)
by Discipulus (Parson) on Mar 31, 2014 at 07:22 UTC
    Hello, in the case you choice to separate completely the coloring logic you can use this useful script. You'll find a nice implementation.


    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      It also ended on CPAN, as cet.

      Because my aim is String variables with a color, I think I'll go for Term::ANSIColor::colored(). Thanks for sharing this module :-)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1080285]
Approved by hdb
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2016-04-30 09:16 GMT
Find Nodes?
    Voting Booth?
    :nehw tseb si esrever ni gnitirW

    Results (441 votes). Check out past polls.