Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid


( #480=superdoc: print w/ replies, xml ) Need Help??

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
Mind the meta!
3 direct replies — Read more / Contribute
by Anonymous Monk
on Mar 01, 2016 at 11:08

    I was a little surprised that in a recent thread no one seemed to flinch at code that was essentially the equivalent of $logged_in = $expect_pass=~/$FORM{pass}/i;.

    If you happen to be wondering "Why is that bad?" - Because $FORM{pass} most likely comes from an HTML form (or at the very least could contain user input), and its contents will be interpolated into and interpreted as a regular expression, leaving the user free to input ".*", which of course matches anything, and so the user is always logged in!

    One solution is to use /\Q$FORM{pass}\E/, which causes characters that would normally be special in a regular expression to be escaped - see quotemeta. In addition, the regex should probably be anchored, to prevent partial matches: /^\Q$FORM{pass}\E$/. Of course, in this example the much easier solution is to just use $expect_pass eq $FORM{pass} instead of a regex!

    I feel like \Q...\E is forgotten too often when interpolating variables into regexes, and it seems to be often overlooked here on PerlMonks when people post code like the above. In fact, I see it forgotten often enough that I think instead \Q...\E should be everyone's default thought when interpolating variables into regular expressions, only to be left off when one has a good reason to (like dynamically building regexes - but of course doing that with unchecked user input is dangerous!).

    So please, mind the meta(characters) and remember \Q...\E!

It's so easy to become complacent.
3 direct replies — Read more / Contribute
by BrowserUk
on Feb 22, 2016 at 11:03

    For the last few weeks I've been forced into using Lua, because it is the embedded language in the simulation software I'm using.

    I've had brief causes to use it a few times in the past for simple things; but this time I'm having to make far more extensive forays into it. And it has highlighted just how spoilt I've been using Perl for most of my scripting needs for the last 13 years. Even just the trivial things, like the fact that Perl detects and reports syntax and even some semantic errors, up front when the script is first loaded.

    Having just had a Lua script run for almost 5 days before trapping out at the eleventh hour with an utterly trivial and inconsequential typo, I've once again had my respect for Perl (5) renewed by the experience.

    Which makes the current state of the community all the more depressing.

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Humane Tasking Initiative / FlowgencyTM
2 direct replies — Read more / Contribute
by flowdy
on Feb 20, 2016 at 08:11

    There is a plenty of software tools of that kind to be discovered online. Either free or for charge, implemented as a webservice or installed locally, command line or graphical, large enterprise-scale project management or simple todo listers for individual use. Lots and lots of stuff like that.

    Because my mid-of-scale, yet another but the better ;) project is written in Perl, I advertise it here in the PerlMonks community. Learn more, and if you are interested, be welcome to test the online demo installation at my Humane Tasking Initiative site. Or read on, clone or fork my FlowgencyTM code repository at GitHub.

    Contributions, questions and comments are welcome. Please understand that the tool must remain far from supporting staff performance monitoring. Technically, it can easily be abused like that, like a kitchen knife can be abused for murder. This is why I envision the software project be embedded in an initiative, and why local usage with full own data souvereignty is focussed in development.

    To those who find that concept of time overhead I recommend TaskWarrior instead. Between that project and mine can be found a remarkable number of similarities, no wonder because TaskWarrior is my primary source of inspiration. I guess admittingly that the development of Taskwarrior is more stable than the development of FlowgencyTM (by the way, this is a working title subject to change in the future), because I am the initiator and main developer, the only one as yet, whose full-time job deserves priority.

Autoload versus auto-generating accessors
6 direct replies — Read more / Contribute
by goldenblue
on Feb 11, 2016 at 10:54

    after reading through PerlMonks Sections I decided this post should go here...

    I have been using Autoload extensively for my getters and setters, and refrained from "auto-writing" them, basically because I didn't like how it looked in the code.

    I also stumbled across some code that uses a baseclass with a makeattr-method it uses as "initializer", to write these accessors, which I also find pretty cool...

    Now I was wondering, which method do others prefer?

    So I would like to open a discussion:

      what are the advantages and drawbacks of each method, or do you see a third alternative? And which do you prefer?

    Maybe someone with a higher level would like to make this into a poll?

CSV headers. Feedback wanted
4 direct replies — Read more / Contribute
by Tux
on Feb 10, 2016 at 08:18

    Given small CSV data files or big(ger) CSV data files with a filter so that all of the data fits into memory, the Text::CSV_XS' csv function will most likely accomodate the common usage:

    use Text::CSV_XS qw( csv ); my $aoa = csv (in => "file.csv");

    This function also supports the common attributes for new:

    my $aoa = csv (in => "file.csv", sep_char => ";");

    or even with shortcuts and aliasses:

    my $aoa = csv (in => "file.csv", sep => ";");

    If there is lots to process inside each row, not all rows would fit into memory, or the callback structure and options for csv will obscure the code, reverting to the low level interface is the only way to go:

    use autodie; use Text::CSV_XS; my $csv = Text::CSV_XS->new ( binary => 1, auto_diag => 1, sep_char => ";", }); open my $fh, "<", "file.csv"; while (my $row = $csv->getline ($fh)) { # do something with the row } close $fh;

    Quite often a CSV data source has got one header line that holds the column names, which is easy to ask for in the csv funtion:

    # Default: return a list of lists (rows) my $aoa = csv (in => "file.csv"); # Using the header line: return a list of hashes (records) my $aoh = csv (in => "file.csv", headers => "auto");

    Or in low-level

    open my $fh, "<", "file.csv"; my @hdr = @{$csv->getline ($fh)}; $csv->column_names (@hdr); while (my $row = $csv->getline_hr ($fh)) { ...

    This week I was confronted with a set of CSV files where the separator character was changing based on the content of the file. Oh, the horror! If the CSV file was expected to contain amounts, the program that did the export chose to use a ; separator and in other cases it used the default ,. IMHO the person that decided to do this should be fired without even blinking the eye.

    This implied that on opening the CSV data stream, I - as a consumer - had to know in advance what this specific file would be like. Which made me come up with a new thought:

    "If a CSV stream is supposed to have a header line that definess the column names, it is (very) unlikely that the column names will contain unpleasant characters like embedded newlines, semi-colons, or comma's. Remember, these are column names, not data rows. Not that it is prohibited to have header fields that have comma's or other non-word characters, but let us assume that it is uncommon enough to warrant support for easy of use."

    So I wanted to convert this:

    open my $fh, "<", "file.csv"; my @hdr = @{$csv->getline ($fh)}; $csv->column_names (@hdr); while (my $row = $csv->getline_hr ($fh)) {

    where the $csv instance has to know what the separator is, to

    open my $fh, "<", "file.csv"; my @hdr = $csv->header ($fh); $csv->column_names (@hdr); while (my $row = $csv->getline_hr ($fh)) {

    which will do the same, but also detect and set the separator.

    where the new header method will read the first line of the already opened stream, detect the separator based on a default list of allowed separators, use the detected sparator to set sep_char for given $csv instance and use it to parse the line and return the result as a list.

    As this came to me as common practice, before you parse the rest of your CSV, I came up with a local method (not (yet) in Text::CSV_XS) that does this for me:

    sub Text::CSV_XS::header { my ($csv, $fh, $seps) = @_; my $hdr = lc <$fh> or return; foreach my $sep (@{$seps || [ ";", "," ]}) { index $hdr, $sep < 0 and next; $csv->sep_char ($sep); last; } open my $h, "<", \$hdr; my $row = $csv->getline ($h); close $h; @{$row // []}; } # Text::CSV_XS::header

    it even has some documentation :)

    =head2 $csv->header ($fh) Return the CSV header and set C<sep_char>. my @hdr = $csv->header ($fh); my @hdr = $csv->header ($fh, [ ";", ",", "|", "\t" ]); Assuming that the file opened for parsing has a header, and the header does not contain problematic characters like embedded newlines, read the first line from the open handle, auto-detect whether the header separates the column names with a character from the allowed separator list. That list defaults to C<[ ";", "," ]> and can be overruled with an optional second argument. If any of the allowed separators matches (checks are done in order), set C<sep_char> to that sequence for the current CSV_XS instance and use it to parse the first line and return it as an array where all fields are mapped to lower case: my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 }); open my $fh, "<:encoding(iso-8859-1)", "file.csv"; my @hdr = $csv->header ($fh) or die "file.csv has no header line\n"; # $csv now has the correct sep_char while (my $row = $csv->getline ($fh)) { ... }

    After two days of intensive use, I thought this might be useful to add to Text::CSV_XS so we all can profit, but I want to get it right from the start, so I ask for feedback (already got some from our local PM group)

    Let the bikeshedding commence ...

    • Is this functionality useful enough to add at all
    • is $csv->header a useful method name (remember we also have low level methods to deal with hashes, like $csv->column_names)
    • Is the proposed API sufficient
    • Do you see any shortcomings

    Things I envision in this function is to also auto-detect encoding when the line includes a BOM and set it to the stream using binmode or have some option to allow this new method to not only return the headers, but use them to set the column names:

    #--- my $data = "foo,bar\r\n1,baz\r\n"; open my $fh, "<", \$data; my @hdr = $csv->header ($fh); # ("foo", "bar") while (my $row = $csv->getline ($fh)) { # $row = [ "1", "baz" ] #--- my $data = "foo;bar\r\n1;baz\r\n"; open my $fh, "<", \$data; my @hdr = $csv->header ($fh); # ("foo", "bar") $csv->column_names (@hdr); while (my $row = $csv->getline_hr ($fh)) { # $row = { foo => "1", bar => "baz" } #--- my $data = "foo|bar\r\n1|baz\r\n"; open my $fh, "<", \$data; $csv->column_names ($csv->header ($fh, [ ";", ",", "|" ])); while (my $row = $csv->getline_hr ($fh)) { # $row = { foo => "1", bar => "baz" }

    Enjoy, Have FUN! H.Merijn
How to ask better questions using Test::More and sample data
1 direct reply — Read more / Contribute
by neilwatson
on Feb 08, 2016 at 15:24

    I encourage wisdom seekers to present sample data and use Test::More in the example code of their question. Let's look at some examples.

    How do I make the regex match?

    #!/usr/bin/perl use strict; use warnings; use Test::More; my $data = "Some string here"; my $regex = qr/ fancy regex here /mxis; like( $data, $regex, "Matching my regex" ); done_testing;

    Your code fails, but readers can read this code and run it and make changes that will make it pass.

    Why does my sub return an error?

    #!/usr/bin/perl use strict; use warnings; use Test::More; sub mysub { return; } ok( mysub(), "Should return true" ); done_testing;

    Presenting larger sample data as if you were reading a file line by line.

    Use __DATA__.

    #!/usr/bin/perl use strict; use warnings; use Test::More; my $wanted_matches = 2; my $actual_matches = 0; my $regex = qr/ fancy regex here /mxis; while ( my $line = <DATA> ) { chomp $line; if ( $line =~ $regex ){ $actual_matches++; } } ok( $wanted_matches == $actual_matches, "Correct number of matches" ); done_testing; __DATA__ line one..... line two..... .... line ten.....

    Neil Watson

Role Composition versus Inheritance
1 direct reply — Read more / Contribute
by choroba
on Feb 07, 2016 at 15:37
    I use Moo in my latest toy project. When experimenting with Moo::Role, I discovered the rules of interaction of role composition and inheritance are not specified in detail, and the current behaviour surprised me a bit.

    In the examples below, I'll use Role::Tiny, as that's what Moo::Role uses under the hood, and it also contains all the important documentation.

    The basic rule of role composition is the following:

    If a method is already defined on a class, that method will not be composed in from the role.

    Let's see an example:

    #! /usr/bin/perl use warnings; use strict; use feature qw{ say }; { package MyRole; use Role::Tiny; sub where { 'Role' } sub role { 'yes' } } { package MyClass; sub new { bless {}, shift } sub where { 'Class' } } { package MyComposed; use Role::Tiny::With; with 'MyRole'; sub new { bless {}, shift } sub where { 'Composed' } } my $c = 'MyComposed'->new; say $c->$_ for qw( where role );


    Composed yes

    The "yes" shows the role was composed into the class, but the "where" method still comes from the original class. So far, so good.

    What do you think should happen, if the class doesn't implement the method, but inherits it from a parent?

    { package MyHeir; use parent -norequire => 'MyClass'; use Role::Tiny::With; with 'MyRole'; } my $h = 'MyHeir'->new; say $h->$_ for qw( where role );

    For me, the output was surprising:

    Role yes

    The same happens when you apply the role to an instance of a class:

    my $o = 'MyClass'->new; 'Role::Tiny'->apply_roles_to_object($o, 'MyRole'); say $o->$_ for qw( where role );

    We started with an object of a class that implemented the where method, but the resulting object uses the role's method. Maybe because a new class is created for the object inheriting from the original one, and the role is then applied to it, as with MyHeir above?

    In fact, I needed that behaviour. As it's not documented explicitely, though, I decided to program defensively, require the where method, and use the around modifier for better readability and clearer specification of the intent:

    { package MyAround; use Role::Tiny; requires 'where'; around where => sub { 'Around' }; sub role { 'yes' } } my $o2 = 'MyClass'->new; 'Role::Tiny'->apply_roles_to_object($o2, 'MyAround'); say $o2->$_ for qw( where role );

    Even if the composition rules changed, my object would still get the where method from the role.

    Update: I proposed a documentation fix that was later accepted.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Focussing Haskell into Perl 6
1 direct reply — Read more / Contribute
by drforr
on Feb 03, 2016 at 06:42
    On the bus ride out to Charleroi I caught a stray brainwave about how to properly notate at least some of Haskell's Lens library, so I wrote up some notes on it. This is going to be slightly spooky, but not much more than the previously-existing ability to bind one data structure to another. I don't know if this is in the spirit of the Haskell library, as it relies heavily on types and type transformations, but I gather that types don't perform quite the role they do in Perl 6. We could conceivably make the lens type-aware so that a lot of mechanism could go away, but the code below has the general idea. The 'lens' library is essentially a metaphor for focussing in on your data, in roughly the following sense:
    my $lens =; $a =< $lens >= $b; # Think of $a "passing through" $lens into $b. $a = 'foo bar'; is-deeply $b, [ 'foo', 'bar' ]; $b.[1] = 'moo'; is $a, 'foo moo';
    Lenses can be chained:
    my $lens2 ='-'); $a =< $lens >=< $lens2 >= $b; $a = 'foo-bar baz-qux'; is-deeply $b, [ [ 'foo', 'bar' ], [ 'baz', 'qux' ] ];
    If that behavior is a little too magical, use the '<<' and/or '>>', and then the changes only go in one direction, or none at all (but they'll still happen on binding.)
    $a << $lens >= $b; $a = 'foo bar'; is-deeply $b, [ 'foo', 'bar' ]; # ok 1 $b.[0] = 'moo'; is-deeply $b, [ 'moo', 'bar' ]; is $a, 'foo bar'; # ok + 2, ok 3
    If you're having trouble coming up with a use for this, envision database work, where you have a transform (like, say, converting timestamps) you need to do on the way in and out of the database:
    my $lens ='Mmm dd, yyy'); $created-date =< $lens >= $created-date-mySQL; is $created-date, 'Feb 3, 2016'; is $created-date-mySQL, '2016-02-03T09:50+02:00';
    Put this anywhere in your method, and you can rest assured that the mySQL date will be formatted correctly when it gets saved. With sufficient black magic, it might even work like:
    $post.<created-date> =< >= $params.<created>;
    so you could drop that into your Dancer'ish Controller, or maybe even directly in your database Model, once there's an ORM thing for Perl 6.
Introducing Scheme In Perl 6
1 direct reply — Read more / Contribute
by drforr
on Jan 26, 2016 at 02:52
    Where it is right now:
    use Inline::Guile; my $g =; say $g.run_i('(+ 3 7)'); # 10 say $g.run_s('"boo"'); # 'boo'
    Where it will go soon:
    say $'(+ 3 7)'); say $'"boo"');
    After Slang::Guile has been written:
    use Slang::Guile; guile-sub car( $x ) { car $x } guile-sub cdr( $x ) { cdr $x } use Test; is car <a b c>, 'a'; is-deeply [ cdr <a b c> ], ['b', 'c'];
    I've already figured out how to write the helper code for most of this. Writing the C glue code at compile time using Perl 6 will let me share constants between C, Guile and Perl 6. Two problems I can foresee with this are that strings will need to be surrounded with dynwind-protect so that they don't leak from the Guile interpreter, and I don't think the NativeCall array types support arbitrarily-recursive arrays, I.E. CArrayInt is just a flat array of entries. I can solve this by passing back a typed array of int32s like so:
    (3 "a" (7 9) "after") => ( INTEGER, 3, STRING, "a", START-LIST, Nil, INTEGER, 7, INTEGER, 9, EN +D-LIST, Nil, STRING, "after" )
    so that everything is returned in a homogeneous data structure, and it's up to the Perl 6 layer to unswizzle this back to:
    is-deeply \${'(3 "a" (7 9) "after")}), [ 3, "a", [ 7, 9 ], "after" ];
    Hopefully I'll have time around FOSDEM to put this all together.
hard versus soft reference to ARRAY's
3 direct replies — Read more / Contribute
by teun-arno
on Jan 24, 2016 at 16:56

    Was playing with splice and noticed that there is a difference between hardcoded ARRAY refenrences and softcoded ARRAY references. Hope this will help somebody in future!! See also : Please notice : I've changed the code from the above link.

    $dwarfs = [ qw(Doc Grumpy Happy Sleepy Sneezy Dopey Bashful) ]; print "@{$dwarfs}\n"; print "@dwarfs\n"; @removed = splice @{$dwarfs},3 ,2; $removed = [ @removed ]; #1. please notice : this makes a copy first +of @removed . # changes to @{$removed} will NOT affect @removed #$removed = \@removed ; #2. please notice : this is a hard reference + . # changes to @{$removed} will affect @removed. # let's examine the above : Just uncomment one of the above lines # it's you're choise which one to use. pop @{$removed} ; print "@removed\n";

    greetings Arno Teunisse

Bug in eval in pre-5.14
6 direct replies — Read more / Contribute
by choroba
on Jan 23, 2016 at 11:45
    For some reason, the following pattern is still used in code - I've seen it at a recent interview and in an accepted answer at Stack Overflow.
    eval { # code that could die }; if ($@) { # Poor man's catch!

    On pre-5.14 Perls, this is a bug. Sometimes, the code inside the eval could die, but the catch wouldn't be triggered, because the $@ could be clobbered - see perl5140delta for details. If you want to use modules from other people, there's no way how to prevent the bug. If the foreign code calls eval in an object's destructor, you're doomed.

    Fortunately, it's rather easy to improve the pattern:

    eval { # code that could die; 1 } or do {

    That way, you can really detect the failure in the "try" block, even if the exception could get lost.

    Here's a simple example that demonstrates the problem. Note that Try::Tiny doesn't provide more than the "or do" pattern:

    #!/usr/bin/perl use warnings; use strict; print $], "\n"; { package My::Obj; sub new { my $class = shift; bless {@_}, $class } sub DESTROY { my $self = shift; eval { 1 } if ! $self->{finished}; } } my $o1 = 'My::Obj'->new(finished => 1); undef $o1; # Exception overlooked. eval { my $o2 = 'My::Obj'->new; die "Exception!"; }; if ($@) { warn "Caught with \$\@: $@"; } # Exception details lost. eval { my $o2 = 'My::Obj'->new; die "Exception!"; 1 } or do { warn "Caught with or: $@"; }; # Same as above. use Try::Tiny; try { my $o3 = 'My::Obj'->new; die "Exception!"; } catch { warn "Caught with Try::Tiny: $_"; };

    In 5.20, I'm getting:

    5.020001 Caught with $@: Exception! at ./ line 25. Caught with or: Exception! at ./ line 34. Caught with Try::Tiny: Exception! at ./ line 44.

    But, in 5.12, the first exception gets overlooked. The second syntax at least notices something went wrong, but the exception is lost anyway.

    5.012005 Caught with or: at line 36. Caught with Try::Tiny: at line 46.
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
RFC: The lightning-rod operator
3 direct replies — Read more / Contribute
by martin
on Jan 22, 2016 at 11:32

    "It's not as if it's a particularly nice house," [Mr. Prosser] said.
    "I'm sorry, but I happen to like it."
    "You'll like the bypass."

    — Douglas Adams, The Hitch-Hikers Guide to the Galaxy

    The Stage

    Extending the Perl 5 language is not to be taken lightly. After more than two decades of stable releases, most basic design decisions have been settled and there is quite some evidence of the language being useful as it is.

    Still, if a new feature promises benefit, is documented well, can't easily be covered by a module, is implemented by someone, does not break backwards compatibility, nor the stability or efficiency of the compiler, and comes with an agreeable syntax, Perl 5 Porters might be inclined to accept it. This can happen. Occasionally.

    I'd like to find out what other Perl monks think about this new operator I have been fantasizing about.

About the CORE and the history of Module::Pluggable
2 direct replies — Read more / Contribute
by Discipulus
on Jan 18, 2016 at 06:54
    hello monks,

    The preamble to this post must be clear: i'm four year late and i do not want to criticize Perl devs who maintain and make perl a better thing with new releases, i want just to know what happened and why.

    The fact: i was lurking on the web with some vague perl learning intention when i came across Module::Pluggable in the official perl docs and I was intrigued by it.
    After a while, since i've closed the browser tab, I've gone for it in the modules (M) list the official docs and i was surprised to not find it there. I've lazyly asked in the chat with no luck.
    Put aside my lazyness i searched the possible motivation and i found this post that announced the module to be removed from core prior the 5.20 Perl release.

    Then, picking up a little of hubrys, i decided to know why it had to be removed, searching (as suggested by tye) the p5p archive and i found
    module deprecations for 5.18 by Ricardo Signes listing all candidates to be removed from 5.18.
    The post mention at the beginning that the original discussion was started by Sayer X at Taking CPANPLUS out of core

    Now i've read them all and i 've understood something: the goal was to remove CPANPLUS (i assume it is problematic or bugged or not so used..).
    A dependency scan of modules used by CPANPLUS was made and for these modules other core modules were searched using them to be sure nothing important would be removed. The list contains Module::Pluggable.

    While reading these long threads i read this good sentence by Steffen Muller I want to report (because i was in the 'many' count below..):
    I think in all of this, choice of words was a bit poor. "Deprecated" will read to many as "don't use, it's bad", whereas it just means "won't be in core in the future". Please make really, really, really sure this is clear to everyone.

    Understood this concept I still do not understand why to remove Module::Pluggable from core.

    My idea of the core may be wrong but i think it is convenient (from the users perspective, not the devs) to have many useful modules in it.
    It is not a problem installing from CPAN (Yes, even you can use CPAN) but i ever look to core modules as the minimal common factor every perl users can have.
    A Perl's program that uses only core modules has anyway a plus in my mind. Also in my limited perl playground i've enough machines to be tired to install too many CPAN modules if i can write down my scripts using core modules. This does not means that i reinvent every wheel i come across, so if i need something to process, let's say, hairy XML i'll install XML::Twig with no problem. But i dont install (as for a recent example) DateTime::Format:: Strptime just to do a one-time time string conversion.

    It sounds so ureasonable my opinion? Personally i'd like many others things in core: many *::tiny modules are candicates in my mind. Considering th above example of XML, would not be better to have XML::Twig (or similar good ones) in the core, istead of having all XML new comers been fooled for weeks by the XML::Simple siren?
    Probably i would like too many things in the core (Tk..) but why to remove unharmful modules? or is somehow Module::Pluggable risky and i've not found right infos?

    Incidentally i learned something useful: declare dependencies also for core modules because nothing is eternal!

    About Module::Pluggable i was intrigued by it and i was considering to add the plugin ability to one of my long running spare time projects. Also the module had very good reviews also from one of the author of the mentioned p5p posts (ok was 2007..). the module was also put into the Perl Advent Calendar (ok was in the 2004..). So why it was removed?


    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.
RFC: Text::Quote::Self - A context-based self-quoting facade for unsafe strings
1 direct reply — Read more / Contribute
by Dallaylaen
on Jan 18, 2016 at 04:19

    Hello fellow monks,

    Following up my own question in SOPW, I would like to release a module implementing the following concept.


    use Text::Quote::Self qw(quote_text); my $safe = quote_text($user_input); # create a magic string object $safe = Text::Quote::Self->new($user_input); # ditto say $safe; # input as is say $safe->as_uri; # uri-encoded $safe =~ s/foo/bar/; # changes original, permanently my $data = { text => $safe }; # elsewhere in the app say JSON::XS->new->allow_blessed->convert_blessed->encode($data); #text as is local $Text::Quote::Self::Style = "as_html"; say $data->{text}; # now with entities # or in a Template You were searching for <a href="/search?q=[% search_term.as_uri %]">[% search_term %]</a>.

    The concept

    Say we have an application that produces convoluted data structure which can be presented in multi[ple ways (who said MVC?). Now depending on the presentation, some strings may need to be escaped/quoted, e.g. if we form an HTML document, we'll have to use HTML entities for some characters; but if we send it via JSON, no quoting is needed.

    To encode such strings properly, we have to either know what presentation is to be used and pre-encode the strings in the data layer, or know which strings are safe and which aren't in the presentation layer. This breaks encapsulation of presentation and data, respectively.

    Now my proposed solution is to create an object with overloaded stringify operation and a set of quoting methods. The preferred method is then chosen based on a package variable. This allows to localize choice to a scope, e.g. set to HTML during template processing subroutine.

    The questions

    • is Text::Quote::Self a descriptive enough name? Is Text the right namespace?
    • is quote_text a descriptive enough name? How likely it is to infringe on a user's sub name?
    • I noticed that in my own project where this concept first appeared quote_text and decode_utf8 often come together. Would it be a good idea to add a switch to auto-encode non-utf strings during construction?
    • local $Foo::Bar looks oldish. Maybe an alternative based on guard objects should be used? Exporting the magic variable didn't work for me.

    Whatever is done so far is available on github.

RFC: Continuous Integration (CI) for your CPAN modules (for free!)
3 direct replies — Read more / Contribute
by stevieb
on Jan 15, 2016 at 11:31

    This guide will attempt to explain the basics of using a version control system (specifically GitHub), along with other free online tools to automate your builds and generate test coverage reports automatically on each update to your code.

    It'll be a work in progress for some time (very high level overview at this time), so feel free to leave comments for fixes/updates etc. This doc assumes that you already have module code you've written (eg: My::Module). There's a fair amount of detail lacking because I can't remember the exact steps for everything, but over the weekend, I'll re-run the entire process and fill in the large gaps here.

    First, head on over to GitHub, and sign up for a free account, and create a repository (eg: my-module).

    Now, install git, and clone your newly created (empty) repo to the local machine:

    git clone

    From the directory above your actual module code, copy the contents of the module's top level dir into the new empty repo dir:

    cp -R My-Module/* my-module

    Add these files to git, and perform your first check-in:

    cd my-module git add . git commit -am "initial import" git push

    You now have revision control for every change you make going forward to your module.

    Next, head over to Travis-CI, and sign up for an account with your GitHub username. After signed in, 'sync' your account to github, and in your repositories screen, you'll see an on/off toggle for your new repository. Enable it.

    Now go to Coveralls and perform the same task you did for Travis.

    At this point, everything should be enabled and ready for use. To proceed, you'll need to set up a .travis.yml file in your distribution's root directory. Here's one that I use in all of my modules. It's configured to run the build on perl versions 5.8 through 5.22, and it'll also perform test coverage in prep for sending to Coveralls.

    language: perl perl: - "5.22" - "5.20" - "5.18" - "5.16" - "5.14" - "5.12" - "5.10" - "5.8" os: - linux before_install: - git clone git:// ~/travis-perl-helpe +rs - source ~/travis-perl-helpers/init - build-perl - perl -V - build-dist - cd $BUILD_DIR install: - cpan-install Devel::Cover - cpan-install --deps - cpan-install --coverage before_script: - coverage-setup script: - PERL5OPT=-MDevel::Cover=-coverage,statement,branch,condition,path, +subroutine prove -lrv t - cover after_success: - cover -report coveralls - coverage-report matrix: include: - perl: 5.20 env: COVERAGE=1

    Note that Travis doesn't do testing on Windows, so I always advise having a Windows machine/VM handy, and run your test suite on there to ensure it runs cross-platform (if necessary) before upload to CPAN.

    Perform a change in your code, then commit and push it to GitHub. Now go to your Travis page (mine's for example), and your build should be running or just about to start.

    If all builds succeed, head on over to your Coveralls page (eg:, and you should see a page with your repos listed, with the coverage details of your unit tests.

    Click on the repository, and at the top of the page, click "Badge URLs". Copy the entire text that contains the HTML link. You'll need this, along with a Travis link for your repo to add to your POD documentation.

    *Note*: I can't remember where I got my own Travis link from, but yours will be the same as mine, simply replace the name of my repo with yours. See the example below...

    Now, in your POD, add a tiny bit of markup and paste in your new links. I put mine in the NAME section so it's visible immediately to visitors to my modules on CPAN:

    =head1 NAME Devel::Examine::Subs - Get info about, search/replace and inject code +into Perl files and subs. =for html <a href=""><img src="h +ttps://"/> <a href=' +h=master'><img src=' +-subs/badge.svg?branch=master&service=github' alt='Coverage Status' / +></a>

    This will result in two images in the NAME section of your POD when users view your module on CPAN. One will show the build success or fail, the other the percentage of test coverage you have.

    Here's an example of what this looks like. You can click through both images and get to the full details of both the build process, and the coverage results.


    • - only does line testing, so I always use Devel::Cover in conjunction to get even more detailed coverage

Add your Meditation
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others chanting in the Monastery: (3)
    As of 2016-08-27 10:50 GMT
    Find Nodes?
      Voting Booth?
      The best thing I ever won in a lottery was:

      Results (379 votes). Check out past polls.