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
Marketing and branding for The Perl Foundation (TPF) poll
1 direct reply — Read more / Contribute
by Lady_Aleena
on Aug 07, 2020 at 21:51

    I came across the Marketing and branding for The Perl Foundation (TPF) poll, and thought you all might want to participate in helping the TPF come up with a marketing plan.

    My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena
Asking for help
3 direct replies — Read more / Contribute
by stevieb
on Aug 01, 2020 at 18:43

    Although I'm sure this post will be reaped, and I know why, but I'm asking anyways.

    I am very desperate for work. Things haven't been going well since we (wife and I) were evacuated and forced to move because of forest fire. Two months after I moved everything from my haven up north, I lost my job. Was able to acquire the odd contract here and there, but nothing stable. After the pandemic, nothing.

    I am at risk of literally losing everything, and my sanity is already half-way there.

    It's not like me to beg, but I am begging anyone, anywhere for work.

    My Perl experience speaks for itself. Most of you know I have a hefty background in global network engineering, as well as four years as a Solution Architect for an Identity and Access Management firm. I've also worked for what is now the largest online gaming corporation as their Global Network & Systems Engineer.

    If you've got a job, or even just a quick one-off contract that I could perform for you, please do let me know.

    If it matters, I've also got a few very good prototypes for the indoor grower (not specific to, but definitely geared towards cannabis growers) that no other company has done, but ran out of money to push it further. Funding towards this would help out as well, with the understanding that your due diligence will be honoured.

    I need something desperately.

    The Perl Jobs site hasn't had anything since late June, and all other jobs are being fought for at a scale I've never seen. I suspect that as my resume states a couple of 10 year gigs, folks grasp my age, and see that I'm not a young cookie out of college.

    Anything. I have no shame. I'm in a fight for our lives.

Split fake, an emulation of split
2 direct replies — Read more / Contribute
by bojinlund
on Jul 31, 2020 at 07:45


    I found an error in the documentation of split Function Split, bug or error in the documentation?.

    Had problems to understand the documentation of split. Decided to do an emulation of split to get a better understanding of split.

    Discovered that split does not behave like a normal subroutine Split does not behave like a subroutine.

    This is my try on an emulation of split. I hope this can help someone!

    Module Fake::Split

    The module implements split using the match operator m{}. It also includes utilities to debug the emulation.

    Used terms:
    Split divides a string in fields and separators. The /PATTERN/ matches the separators. The parts before, between and after a separator are the fields.
    sub splitF_match_pos

    sub splitF_match_pos returns a list with the position (pos) in the string for the start and end of matches. The list contains groups of pos with pos start and pos end of field, and a reference to an array. The array contains pos for start and end of separator and optional for each capture group, the start and end.

    sub splitF_case

    Identifies the patterns which needs special treatment in split.

    sub splitF_pos

    This routine handles split specific things. It uses the more generic splitF_match_pos.

    sub splitF_pos2txt

    The output is a textual presentation of the output from sub splitF_pos.

    sub splitF_pos2list

    Create a list of strings from the output of sub splitF_pos. The output is (should be) the same as that from split.

    sub splitF_test($;$$)

    Can be used to test the split emulation. See below!

    sub splitF($;$$)

    This is the emulation of split.

    If PATTERN, the first argument to split, is a match operator /STRING/ it must be replaced with qr/STRING/, a compiled regular expression.

    The syntax split /PATTERN/ and split are not supported

    My test of the module

    I have based my tests on the file t/op/split.t in the Perl source code distribution and on the examples in split.

    This script uses most of the /PATTERN/,EXPR,LIMIT combinations used in split.t. I had to change all /STRING/ to qr/STRING/. (I have not found any way to emulate split's way to delay the evaluation of its first argument).

    In the line is_deeply splitF_test(" ", "a b c"); returns splitF_test a suitable input to is_deeply.

    The output from splitF_test consists of two anonymous arrays, one with the output from the emulation and one from split, and a string with a dump of the argument /PATTERN/,EXPR,LIMIT

    My observations and questions

    The use of the Perl variable $#+

    It is important to use $#+ together with @- and @+. See my sub splitF_match_pos above.

    Inconsistency between m{} and split

    The need for this in sub splitF_pos2list

    if ( $field_start == $field_end && $sep_aref && $field_start == $sep_aref->[0] && $field_start == $sep_aref->[1] ) { info('SKIP intermediate field+separator, both are empty'); next; }
    indicates an undocumented inconsistency!?

    Arguments used together with Regexp Quote-Like Operators

    I have several times found limitations on what can be an argument to Regexp Quote Like Operators.

    One example is

    # while ( my $rv = $$str_ref =~ m{$pat_re}gc ) { does not work # but this works: my $str = $$str_ref; while ( my $rv = $str =~ m{$pat_re}gc ) {

    Are those limitations documented anywhere?

    A split function which behaves like a perl subroutine?

    The current split is a list operator with a lot of surprises and special cases.

    What about a parallel alternative, not so optimized implemented, which behaves like a normal subroutine. Perhaps a string study function with the arguments: pattern, reference to a string and returning a list with positions (not splitting the string in sub-strings). An optional parameter could be used to select special cases.

    A string study iterator is also useful.

dear Mom -
1 direct reply — Read more / Contribute
by perlfan
on Jul 26, 2020 at 22:25
    By far the most useful nodelet I've added to my PM layout is the CPAN nodelet. In today's installment of the cool module I TIL'd about is Mom - Moo objects minimally.

    I'm pretty outspoken about how ugly I think Moo, Moose, etc are and how we really just need to make these snausage factories more perlish. Util::H2O now has a friend on my list of steps in the right directionTM.

    I saw this interesting gem float by the nodelet, and the name alone was click bait enough for me to take a look. Congrats to the CPAN author for this brand spanking new module. It even uses parent.

    I'm not saying this is the way, but as I said before, it's thinking in the right direction.

Making $ Unicode-aware
3 direct replies — Read more / Contribute
by jo37
on Jul 26, 2020 at 14:31

    How bad is this idea:

    To my understanding, $ in a regex (without the m modifier) is equivalent to (?=\n?\z), i.e. "Match the end of the string (or before newline at the end of the string)". With Unicode, the meaning of "newline" may be extended to "Linebreak", aka \R.

    Wouldn't it be nice to make $ behave as (?=\R?\z) under some pragma or flag? (Without \z when the m flag is present, of course.)

    I believe this wouldn't even break much existing code. Invented for the "new" $ here.

    #!/usr/bin/perl use v5.14; use warnings; use utf8; use charnames qw(:full :short); use feature 'say'; for ("noeol", "nl\n", "cr\r", "cr_nl\r\n") { my $u_chomped = s/\R//r; say "$u_chomped:"; say 'matches $' if /^\p{word}*$/; say 'matches like $' if /^\p{word}*(?=\n?\z)/; say 'matches €' if /^\p{word}*(?=\R?\z)/; say 'matches \r$' if /^\p{word}*\r$/; say 'matches \r€' if /^\p{word}*\r(?=\R?\z)/; say 'matches \r?$' if /^\p{word}*\r?$/; say 'matches \r?€' if /^\p{word}*\r?(?=\R?\z)/; /^(.*)$/; say 'captured (.*)$' if $1 eq $u_chomped; /^(.*)(?=\R?\z)/; say 'captured (.*)€' if $1 eq $u_chomped; /^(.*).$/; say 'captured (.*).$' if $1 eq $u_chomped; /^(.*).(?=\R?\z)/; say 'captured (.*).€' if $1 eq $u_chomped; say "\n"; } __DATA__ noeol: matches $ matches like $ matches € matches \r?$ matches \r?€ captured (.*)$ captured (.*)€ nl: matches $ matches like $ matches € matches \r?$ matches \r?€ captured (.*)$ captured (.*)€ cr: matches € matches \r$ matches \r€ matches \r?$ matches \r?€ captured (.*).$ captured (.*).€ cr_nl: matches € matches \r$ matches \r€ matches \r?$ matches \r?€ captured (.*).$ captured (.*).€


computer security and Perl group
1 direct reply — Read more / Contribute
by Bpl
on Jul 22, 2020 at 18:25
    Hi monks, I would like to create a group of security practitioner only for developing some project related to perl security tools in our free time :) everyone who want to learn is welcome. the main subjects will be:
    - Penetration test - Reverse engineering - Cryptanalysis and Cryptography - EMsec and other Side channel attacks and countermeasures - firmware modding and other similar things. - wireless security testing
    Everything will be "ethical" and it will possible to write some articles also for ( related to security ). It would also be possible to create some libraries and post on CPAN together. for more information send me a message in private. Thanks. Edoardo M.
Split does not behave like a subroutine
3 direct replies — Read more / Contribute
by bojinlund
on Jul 18, 2020 at 02:00

    I have tried to understand the documentation of the Perl function split. Doing this I have realized that after more that 30 years usage of Perl I have still not understood some basic properties of Perl. Here follows some of "my new findings" and questions.

    Perl subroutine

    From Perl documentation:

    The Perl model for function call and return values is simple: all functions are passed as parameters one single FLAT LIST of scalars, and all functions likewise return to their caller one single FLAT LIST of scalars.
    A LIST value is an unnamed list of temporary scalar values that may be passed around within a program from any list-generating function to any function or construct that provides a list context.

    LIST, list value constructor and list value

    A list value can be created by using a list value constructor. It is a number of arguments separated by Comma Operators.

    Comma Operator:

    "In list context, it's just the list argument separator, and inserts both its arguments into the list. These arguments are evaluated from left to right."


    • In the documentation often list is used for both list value and list value constructor. This make it difficult to understand the documentation.
    • Sometimes there are contradictions. What applies to a list (list value), perhaps does not apply to a list (list value constructor)


    A Perl list (= list value) is a sequence of scalar values. A list is not a scalar. Not even the empty list is a scalar.

    This means that all list values are flat!?

    Probably is the flattening a part of the comma operator and done for all lists (= list value)

    "The null list is represented by (). Interpolating it in a list has no effect. Thus ((),(),()) is equivalent to (). Similarly, interpolating an array with no elements is the same as if no array had been interpolated at that point."


    • A list value is always flat.
    • The arguments to a list value constructor can be none flat.
    • The list concept and for all flattening should be described more clearly in the Perl documentation.

    Positional arguments and parameters

    It took me a long time to understand that my problem was, a subroutine returning an empty list, in the parameter list in the call to a subroutine.

    Here I use: In a subroutine call the arguments are passed/bound to the parameters (formal argument) in the subroutine definition. The arguments for a call are evaluated, and the resulting values are passed to the corresponding parameters.

    I have always though, that the commas in a call to a subroutine, separate the argument list in sequence of values each corresponding to a parameter. call('P1', 'P2', 'P3').

    There can be Positional parameters in a subroutine definition. But not all of the Positional arguments becomes a Positional parameter!?

    "Any arguments passed in show up in the array @_." This can be false!? A Positional argument can be flattened away.

    use strict; use warnings; use 5.010; use Data::Dump qw(dump dd ddx); sub p2 { 'P2' } sub nop1 { } sub nop2 { return } sub test { say dump @_ } test( 'P1', 'P2', 'P3' ); test( 'P1', p2, 'P3' ); test( 'P1', nop1, 'P3' ); test( 'P1', nop2, 'P3' ); __DATA__ Output: ("P1", "P2", "P3") ("P1", "P2", "P3") ("P1", "P3") ("P1", "P3")


    • The risk to lose a Positional argument should be explicit clarified
    • In conservative programming, there should be no subroutine calls in the argument list!?

    Split does not behave like a subroutine

    In perlfun it is stated: "Here are Perl's functions (including things that look like functions, like some keywords and named operators) arranged by category"

    What is split? A keyword, named operator or ... .

    It is also stated:

    Any function in the list below may be used either with or without parentheses around its arguments. (The syntax descriptions omit the parentheses.) If you use parentheses, the simple but occasionally surprising rule is this: It looks like a function, therefore it is a function.

    However split does not behave like a Perl subroutine. So the statement "therefore it is a function" does not mean that split behaves like a Perl subroutine.

    The evaluation of the first argument to split is delayed. This is different from normal subroutines. Is this indicated by the slashes in /PATTERN/?

    This script shows that an array can not be used in the arguments to split. It is also different from normal subroutines.

    use strict; use warnings; use 5.010; my $pat = ':'; my $str = 'O:K'; my $pat_ref = \$pat; my $str_ref = \$str; my @par = ( $pat, $str ); my $rv = split $pat, $str; # OK $rv = split $pat, $$str_ref; # OK $rv = split $$pat_ref, $$str_ref; # OK $rv = split( $par[0], $par[1] ); # OK # W1: Use of uninitialized value $_ in split $rv = split @par; # NOK W1 $rv = split(@par); # NOK W1 $rv = split( @par[ 0, 1 ] ); # NOK W1 $rv = split( ( @par[ 0, 1 ] ) ); # NOK W1 $rv = split( map { $_ } @par ); # NOK W1 $rv = split( ( map { $_ } @par ) ); # NOK W1


    • Split look like a subroutine but does not behave like one.
    • The differences between split and a normal subroutine should be clarified.
    • The meaning of the slashes in /PATTERN/ should be explained.

    Is this a bug?

    #!/usr/bin/perl -w use strict; use warnings; use 5.010; use Data::Dump qw(dump dd ddx); ddx (1,'a', ()); ddx scalar (1,'a'); ddx scalar (1,'a', ()); my $var = (1,'a', ()); ddx $var; __DATA__ output: Useless use of a constant ("a") in void context at li +ne 11. Useless use of a constant ("a") in void context at li +ne 12. # (1, "a") # "a" # undef # undef

    I had expected this

    # undef # undef
    to be
    # "a" # "a"

On Backwards Compatibility and Bareword Filehandles
4 direct replies — Read more / Contribute
by jcb
on Jul 17, 2020 at 00:33

    While participating in some of the recent discussions about plans for Perl 7 and the longer-term future of Perl, I found a solution that I wish to offer here.

    A Ground Rule

    First, I want to get what should be obvious as a ground rule: removing features from Perl requires significant justification, and style is never enough to remove a feature. The rationale for this rule is simple: Perl has long held to TIMTOWTDI and style varies. If we allow the precedent of removing features from the language because the pumpking thinks they are ugly, the next pumpking will have different tastes, and the next-next different tastes still — the result will be a disaster reminiscent of Fahrenheit 451. (In that story, banning all books grew out of lots of little bits of censorship.)

    "There are some things you should learn to live without, even in Perl 5 land." is not an appropriate attitude to take, and that quote is from the Perl 7 announcement.

    What is significant justification?

    This is a good question. I believe that reasonable people can agree that style is not enough, particularly with a language that touts TIMTOWTDI as Perl does, but what is good enough?

    I will argue that significant improvements to the interpreter can justify at least some changes. Significant improvements in compatibility can justify broader use of UTF-8 (as long as there is some pragma for treating strings as uninterpreted octet strings; handling binary data is one of Perl's strengths). Rolling pragmas like use strict; into defaults is reasonable, as long no strict continues to exist. (At least some useful metaprogramming requires no strict 'refs'; to install subs from templates.)

    Indirect Object syntax and Bareword Filehandles

    The proposal to remove these has caused much rancor, with justifications that only support removing either presented for removing both and flames producing far more heat than light.

    The indirect object (IO) syntax seems to be a generalization of an older Input/Output (I/O) syntax that allowed print FILEHANDLE EXPR instead of requiring the use of select to change the default output handle. This was generalized with the introduction of IO::Handle and can also be used to write code (particularly object constructors) that reads much like English: new Foo::Object (ARGS); kill $object with => 'fire'.

    The IO syntax is not without its problems, however. The historical similarity to the I/O syntax creates some parse conflicts and it is not possible to call a constructor named open in IO syntax because of these parse conflicts, but I offer a solution in three parts:

    Regularized I/O

    The solution starts by regularizing all I/O handles into =IO objects and eliminating the *foo{IO} GV slot. This is entirely reasonable in a major release and can be done while breaking relatively little code. This allows resolving the IO|I/O parse conflict at last — it is always an IO method call, with a small amount of new magic for open:

    Lexical Bareword Filehandles

    Perl 5 allows open my $foo, ... (lexical) and open FOO, ... (traditional) for opening files. Notably, neither of these uses the IO syntax; they parse as open( my $foo, ...) and open( FOO, ...). I propose generalizing this to also allow open our $foo, ... (to explicitly open a global filehandle; remember TIMTOWTDI) and open state $foo, ... (a conditional open iff the lexical state variable $foo is currently undef or a closed handle). Update: As haukex points out, this generalization was so obvious that it has already been done.

    The parser has enough information to take one step farther, as the title of this section suggests, and make bareword filehandles lexical variables. The open keyword (when parsed as the builtin; distinguishable by the absence of "::" in the bareword and the presence of a comma following the bareword) functions as a lexical filehandle declaration. The parser raises an error if the new I/O variable would shadow any other bareword known to the parser, so these filehandles cannot conflict with sub names or package names. The new I/O variable carries an invisible sigil, so:

    open FILE, '<', $file or die "..."; while (<FILE>) { print if m/interesting/; handle(FILE, 'that') if m/that/; } close FILE;

    parses as if: (with the invisible I/O sigil represented as {I/O})

    open my {I/O}FILE, '<', $file or die "..."; while (<{I/O}FILE>) { print if m/interesting/; handle({I/O}FILE, 'that') if m/that/; } close {I/O}FILE;

    which in turn is equivalent to:

    open my {I/O}FILE, '<', $file or die "..."; while (defined($_ = {I/O}FILE->readline)) { print $_ if $_ =~ m/interesting/; handle({I/O}FILE, 'that') if $_ =~ m/that/; } {I/O}FILE->close;

    with sub handle like:

    sub handle { my $fh = shift; my $what = shift; ... }

    As you can see, this provides an elegant solution for passing filehandles to subroutines while also bringing the typo protection afforded by declaring variables to bareword filehandles and solving most of the other problems. The {I/O}FILE variable only exists within the block where it was declared, so there is no risk of action at a distance and programs that relied on that action will fail to compile. The {I/O}FILE variable actually simply contains an =IO object like any other, but the interpreter may be able to optimize with the knowledge that it will always contain an =IO object; there is no way to assign to an I/O variable other than open.

    One more small cleanup

    All this leaves an edge case that can finally be fixed: using open as a class method. The parser can recognize barewords containing "::" as PACKAGE tokens; a PACKAGE token in the slot for a named operator or sub name is interpreted as a fully qualified sub name, but BAREWORD PACKAGE EXPR is a class method call on PACKAGE. Always; even if BAREWORD is "open".

    Thanks and Discussion

    I would like to thank my fellow monks with whom I have had much discussion on related topics, particularly haukex, LanX, chromatic, and WaywardCode, along with any others I have forgotten to mention here. Lastly, I would like to thank you for reading this and invite you to discuss below.

Expression form of map or grep
7 direct replies — Read more / Contribute
by Lady_Aleena
on Jul 10, 2020 at 15:47

    As you might know, I have been using Perl::Critic on my code over the last several days. After I finished checking my code on the gentle setting, I kicked it up a notch and used stern. Well, Perl::Critic set on stern gave me screens full of problems, and the biggest one is I use the expression form of map and grep. I looked around the web to find out why.

    Here is my opinion that could be very wrong.

    All of the examples I found of the expression form of map and grep would lead to inevitable problems, and I can see why the writers of those examples would jump on using the block form for both. However, the one thing all of the examples had in common is the disuse of parentheses. I feel that if the expression form of a map or grep is used with parentheses, it is contained within them.

    The map below would lead to problems, since there is nothing containing the expression or on which list(s) the map is being applied.

    my @colors = qw(red yellow green cyan blue magenta); my @grey_scale = qw(white grey black); my @list = map "$_ beads", @colors, @grey_scale;

    However, I do not think this needs a block form to contain the map and list if parentheses are used.

    my @list = map( "$_ beads", @colors ), @grey_scale;

    Now the map is contained within parentheses, and @grey_scale does not get beads mapped to it. However, if one must use the block form, parentheses would still be needed to contain the mapped items.

    my @list = ( map { "$_ beads" } @colors ), @grey_scale;

    I think the expression form with parentheses is easier on the eyes, but it is just my opinion. I can understand using the block form if the map were more complex, however, I think I would write a separate subroutine instead of loading the block with more than two or three modifications and use the expression form.

    Converting from expression to block form is also problematic as it is not always as simple as the above would suggest, especially with grep. I have also found the expression form of grep to be easier to use, in one case (I can not remember the specifics) I could not get the block form of grep to work.

    If I use sort with map and/or grep on the same list, I will wrestle the block forms until I get the results I want, because in that case, it is easier on my eyes than trying to mix expression forms with the block of sort.

    I know I can ignore Perl::Critic's results on this and other issues, however, I do want code that is more acceptable by the community. So, I am trying to decide if I want to start wrestling with Perl on this or not. (I ran Perl::Critic on all of my modules, and it found 330 lines where I used the expression forms of map and grep, so this is fairly big to me.)

    I hope I am not too wrong about this.

    My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena
RFC: Version::Easy
3 direct replies — Read more / Contribute
by LanX
on Jul 10, 2020 at 13:28
    Following the discussion in Why eval $version? I'd like to propose the following approach.


    use Version::Easy; $VERSION = 'v1.2.3'; # v-str # or... $VERSION = '1.002003'; # float $VERSION = 'v1.2.3_4'; # v-str + alpha $VERSION = '1.002003_4'; # float + alpha

    please note that:

    • Version::Easy adds magic to $VERSION
    • it's also declaring $VERSION in the caller's package, so no our needed
    • all formats like floats or v-strings with optional "_alpha" allowed
    • no boilerplate eval or tr/// needed
    • version is used internally, which is the same mechanism applied by use
    • syntax check at runtime
    • toolchain modules with static parser find "$VERSION" as usual
    • $VERSION is a tied scalar,
    • in STORE the version number is checked for correct syntax
    • in FETCH a version object is returned
    • the version object is overloading all necessary operators
    • for older versions of Perl the implementation could adapt dynamically to sane defaults
    • if the performance impact is too heavy for normal runs, it's possible to limit the costly parts only to run inside the test suite.

    Doesn't this solve most (or all) problems???

    Please comment! Where does this fail? :)

    use strict; use warnings; # -------------------------------------------------- package Version::Easy; use Data::Dump qw/pp dd/; use version; sub import { my $pkg = (caller)[0]; my $version; tie $version, 'Version::Easy::Tie'; no strict 'refs'; *{${pkg}."::VERSION"} = \$version; } # -------------------------------------------------- package Version::Easy::Tie; require Tie::Scalar; our @ISA = qw(Tie::StdScalar); use version qw/is_lax/; sub STORE { my ($self,$value)= @_; warn "IN:\t\t",$value; if ( is_lax($value) ) { $$self = version->parse($value); } else { warn "corrupt VERSION format $value"; } } # BUG? perldoc Tie::Scalar says no TIESCALAR needed sub TIESCALAR { my $class = shift; my $version; return bless \$version, $class; } 1; # -------------------------------------------------- # --- fake already required for 'use' demo BEGIN { $INC{'Version/'} = 1; } # -------------------------------------------------- # # DEMO # # package TST; use Version::Easy; # --------- test v-str $VERSION = 'v1.2.3'; warn "Str:\t" ,$VERSION; warn "Float:\t" ,$VERSION->numify; warn "V-str:\t" ,$VERSION->normal; my $v1 = $VERSION; # --------- test float $VERSION = '1.002003'; warn "Str:\t" ,$VERSION; warn "Float:\t" ,$VERSION->numify; warn "V-str:\t" ,$VERSION->normal; my $v2 = $VERSION; warn "Are both Version equal?:", $v1 == $v2; warn "v-str bigger?:", $v1 > 'v1.2.2'; warn "v-str smaller?:", $v1 < 'v1.2.4'; warn "v-str not smaller?:", $v1 < 'v1.2.2'; # # --------------------------------------------------

    -*- mode: compilation; default-directory: "d:/exp/" -*- Compilation started at Fri Jul 10 19:13:58 C:/Perl_524/bin\perl.exe d:/exp/ IN: v1.2.3 at d:/exp/ line 29. Str: v1.2.3 at d:/exp/ line 69. Float: 1.002003 at d:/exp/ line 70. V-str: v1.2.3 at d:/exp/ line 71. IN: 1.002003 at d:/exp/ line 29. Str: 1.002003 at d:/exp/ line 78. Float: 1.002003 at d:/exp/ line 79. V-str: v1.2.3 at d:/exp/ line 80. Are both Version equal?:1 at d:/exp/ line 84. v-str bigger?:1 at d:/exp/ line 86. v-str smaller?:1 at d:/exp/ line 87. v-str not smaller?: at d:/exp/ line 88. Compilation finished at Fri Jul 10 19:13:58

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

RFC -- Evolving Perl: a Decision Theory Approach to the Challenges of Perl 7
4 direct replies — Read more / Contribute
by thechartist
on Jul 07, 2020 at 14:16

    The announcement of Perl 7 has created a lot of activity in the various techology communities I follow. It has also lead to a lot of discussion and debate among a number of subsets of the Perl community.

    Last week we had a discussion on "software quality" in the Perl Programmers Facebook group. "Quality" is a term that is not defined whenever it pops up. I pointed out that "quality" for a typical "real world" programming problem can be seen as a Multiple Criteria Decision Analysis, or a Multiple Objective Optimization Problem, that attempts to balance the following:

    1. Validate that inputs are appropriately transformed into the correct/desired outputs.
    2. Handle errors, exceptions, etc.
    3. Does so in a computationally efficient manner (ie. time and space efficiency). The algorithm doesn't need to be provably optimal, but it should be suitable for the *known* needs of the application at the time of writing.
    4. Delivered in a verifiable/testable form as quickly as possible.
    5. Comprehensible to other team members.
    6. Able to be relatively easy to change, if application specification changes.

    I'm sure there are other objectives I omitted. I think it should be obvious that:

    1. these dimensions need to be traded off against one another and
    2. these criteria aren't all equally weighted. Context determines what criteria are most important in a particular time.

    From a formal point of view, there are generally no unique/optimal solutions, only sets of satisfactory ones (Multiple Criteria Decision Analysis).

    Some of the themes of the p5p messages after the announcement included:

    1. What is the new contract with Perl users re: backward compatibility?
    2. What should be done in newer versions of Perl to attract new users?
    3. What should be done to ease the implementation of new features, and reduce the complexity of the Perl interpreter, toolchain, etc.
    4. What can be done to facilitate a better process for the community to make better decisions?

    The conclusions I've come to (as a former Perl hater, now Perl convert) is:

    1. Perl as a technology, scales from small one-liner throw away scripts, to massive code bases that span decades. There aren't many other languages that can boast about that.
    2. Perl, as a community, has learned a lot of lessons in producing reliable software. These lessons become part of Perl culture, and produce better developers.

    In terms of point 4 above (Perl community process), I'd like to suggest borrowing some methods from the operations research/decision analysis communities (Tools for Decision Analysis).

    The criteria I see the Perl community attempting to balance are:

    1. Perl interpreter complexity. Certain things need to be changed to improve computational efficiency, ease maintainence, and enhance the language.
    2. CPAN backward compatibility. Too much breakage with CPAN, and we have a new language with no code base.
    3. Increasing use of Perl in newer areas (ie. attracting new users, especially newer developers who can hack on the toolchain).
    4. Teaching the language, and good software development practice generally.

    An approach worth considering can be seen in the Ada community. Initially standardized in 1983, each revision (1995, 2005, 2012) has been accompanied by a Rationale document, that describes the changes and the reasons for them. Most of the changes have been addiitions or extensions to the language.

    Any rationale for future versions of Perl will be a bit more challenging, in that some practices will need to be revised. To explain and defend such changes, an explicit, pairwise comparison of what criteria are improved, and how they are traded off vs. other objectives, needs to be considered.

    I personally would like to see Perl more involved in so-called "data science." My use case for Perl is statistical natural language processing to assist in the meta-analysis or evidence synthesis of research in health care specifically, but in applied science more generally. I believe those tools could be helpful in exploring the CPAN code base to collect empirical data on what features of Perl are most used, and which could be dropped with minimal loss.

    If I'm thinking about this correctly, the problem the Perl community faces is one known in the Prolog and logic programming communities as inductive specification recovery. If I were to translate the informal problem facing the Perl community into a formal statement, I'd say we are attempting to discover (induct) the Perl grammar that simultaneously:

    1. Reduces CPAN Breakages
    2. Reduces Perl interpreter code complexity

    Damian Conway has shown how hard this path is via human effort Three Little Words.

    To calculate these things require some metrics. I think the CPAN breakage is reasonably easy to calculate. But the interpreter complexity metric is something that should be given some considerable thought.

    With an explicit decision model, I believe we can use statistical methods from reliability theory and machine learning to develop software that will ease the burden of transitioning Perl to a more sustainable future.

Amicable divorce
7 direct replies — Read more / Contribute
by ribasushi
on Jul 06, 2020 at 00:53

    ( this is a re-post of recent thoughts from the perl5-porters mailing list. Further interesting points articulated in an adjacent thread. )

    An incredibly unlikely combination of recent events have placed Perl (the language) at an exceedingly rare crossroads. Various "factions" have openly stated their worldviews, but war has not broken out just yet.

    While there is a ton of nuance, the two main "philosophies" at odds are roughly:

    • Software-as-a-solution (SAAS), where code is targeted at solving a specific problem, in a dynamic world. When the problem inevitably changes as the world around it continuously moves along, it is only fair and even prudent to continuously modify the existing solution to said problem.
    • Software-as-a-tool (SAAT), where code is targeted at *other* professionals, to combine it with an increasing array of other tools to then solve a specific problem. A hammer from 50 years ago looks strikingly identical to a hammer you can buy today, and it better look like a hammer after 2038, or else...

    The series of mega-threads all boil down to a profound misunderstanding within the p5p list itself of the magnitude of the clash-of-values between these sub-communities.

    I strongly believe, that if a more honest conversation takes places not over the "how" but the "what", a massive amount of effort will be saved on all sides.


    • Instead of dancing around the issue of having nice things with cpan: let's admit the need for 2 CPANs: one to cater to folks excited by the prospect of perl 7 and one for people who will never write anything above 'use 5.0XX' within their code.
    • Begin a discussion acknowledging the amount of "better bash" tooling investment outside of the handful of companies named as stakeholders, and have an honest conversation what is the expectation for "system perl" and "system perlng" in the mid-to-long-term.

    Everything else discussed so far is dressing to obscure the substance: "Perl" and "perl" are *both* about ready to file for divorce. This is an incredibly rare chance for an Unionsupplösningen or a Velvet Divorce. Please, do not squander it.


Breathing life into the (Emacs) cperl-mode
2 direct replies — Read more / Contribute
by haj
on Jul 02, 2020 at 11:29
    This also appeared on

    If you are an Emacs user, you might know or even use cperl-mode. I am using it, more or less since my first days with Perl. Back then, newsgroups were a thing, and Ilya Zakharevich recommended it occasionally. In older times cperl-mode was shipped with Perl, today it is part of Emacs.

    If you use cperl-mode, you might also have had a look at the code and noticed that it hasn't seen much love in the last decade or so. Perl, on the other hand, evolves. Version 5.32, for example, brings a new infix operator, and some future version might bring Cor. Wouldn't it be nice if cperl-mode understood these new keywords?

    I'm on my way to get familiar with emacs-lisp, ERT, and other stuff to see what I can do. Ideas, contributions, comments, bug requests and criticism is welcome - There's a GitHub repository to get started.

RFC: Destructuring Assignment (aka Unpacking aka Type Patterns) in pure Perl
3 direct replies — Read more / Contribute
by LanX
on Jul 02, 2020 at 09:41

    At yesterday online meeting of Germany PM we had a discussion about Destructuring Assignment aka unpacking aka Type Patterns which is available in languages like JS (ES6) and Haskell.

    I claimed it shouldn't be to difficult to do this in pure Perl, this is what I got so far.

    NB: This is a proof of concept !

    Neither syntactic sugar nor performance are at it's limits.

    (you know "release often ... yadda yadda" ;-)

    Grabbing of (almost greedy) lists @arr and %hsh not implemented yet.

    Comments welcome.

    use strict; use warnings; use Data::Dump qw/pp dd/; use Scalar::Util qw/reftype/; use autovivification; use Test::More; use constant DBG => 0; my @rules; sub parse_arr (\@$) { my ( $arr, $path ) = @_; for ( my $i=0; $i <= @$arr; $i++ ) { my $item = $arr->[$i]; parse( $item, "${path}[$i]"); } } sub parse_hsh (\%$) { my ( $hsh, $path ) = @_; while ( my ($key,$val) = each %$hsh ) { parse( $val, "${path}{$key}"); } } sub parse { my ( $item, $path ) = @_; $path //= ''; my $type = ref $item; return unless $type; if ( $type eq "GRAB") { push @rules, [ $item->{ref} , $path ]; } elsif ( $type eq "ARRAY" ) { parse_arr( @$item, $path ) } elsif ( $type eq "HASH" ) { parse_hsh( %$item, $path ) } else { warn "Unknown $type"; } } sub assign (++){ my ($pattern,$in) =@_; @rules = (); parse($pattern); warn pp @rules if DBG; no autovivification; for my $rule (@rules) { my ($ref,$path) = @$rule; my $code = "\$in->$path"; $$ref = eval($code); } } sub set (\[@$%]) { bless {ref => $_[0]}, "GRAB"; } my @pattern = ( 1,2,3, set my $y , [ 5,6, set my $z ] ); my $src = [ 1,2,3, 42 , [5,6, 666] ]; assign @pattern => $src; is_deeply ( [$z,$y], [666, 42], "AoA grabbing different levels" ); assign { u => [undef, set( my $u )], v => set my $v } => { u => [1,123] , v => "VVV"} ; is_deeply ( [$u,$v], [123,"VVV"], "HoA grabbing different levels" ); done_testing;

    C:/Perl_524/bin\perl.exe d:/exp/ ok 1 - AoA grabbing different levels ok 2 - HoA grabbing different levels 1..2

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Modernizing the Postmodern Language?
6 direct replies — Read more / Contribute
by WaywardCode
on Jun 29, 2020 at 12:44

    Fellow Monks,

    Today I re-read the 1999 talk: "Perl, the first postmodern computer language." I couldn't help but laugh to see that--as of this writing--the #1 advertised post on the right side-panel is the Perl 7 announcement, with the tag-line Perl 5 with modern defaults.

    Do we want our postmodern language modernized? It may not be the sound of one hand clapping, but still worthy of some meditation, I think. I recently noted that Perl 5.30 will run almost all of the Perl 1 test suite unmodified (the rare failures are on subroutines called with do whatever();). If I understand the Perl 7 plan correctly, Perl 7 will run approximately zero percent of the Perl 1 test suite due to mandating strict and dropping bareword filehandles. Does that matter? I guess not, but it feels like a loss to me.

    The virtues extolled in the talk were (1) incorporating what rules (2) leaving out what sucks and (3) letting the duct work show. To uphold those virtues, it seems to me that newer Perls should look around and incorporate things that both (1) rule and (2) aren't already in Perl. Perl should primarily accrete, and occasionally mutate. So, Monks, should it concern me that one of the two motivations given for Perl 7 is the ability to remove syntax? Should it concern me that SawyerX's Guac project (youtube) calls the regularized, easily-parsable subset of Perl "Standard Perl"? Despite the don't-worry-disclaimers, if the pumpking can call a language without autoquoting or heredocs Standard, that speaks volumes to me about where his head is at. Perhaps I am overreacting.

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.