Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery


( #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
Moo and command line scripts
1 direct reply — Read more / Contribute
by boftx
on Nov 08, 2019 at 20:02

    Hello fellow monks! It is good to once again tread these hallowed halls after all these moons of moons.

    I have been a fan of modulinos (thanks Brian D'Foy!) for a long time now because of the advantages for testability. I have also been a fan of Moo for several years. And of course, like many others, I have combined both techniques with Getopt::Long. I have also been using a standard set of command line options such as "--debug" and "--help", with "--debug" defaulting true so "--nodebug" is required to turn it off.

    In an effort to reduce boilerplate and a lot of copy-and-paste I wrote a simple Moo role to handle the basics for me. I have since refined it with a proper test suite and POD and it has now been released as MooX::Role::CliOptions. I would greatly appreciated any feedback from my brothers and sisters of the Monastery on any and all aspects.

    I am well aware that there are other ways of doing this, including a couple of other modules on CPAN. I hope that some will find this new Role to be easier to use in some respects, as well as being more "Moo-ish".

    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Mozilla IoT platform Perl wrapper
4 direct replies — Read more / Contribute
by stevieb
on Oct 31, 2019 at 18:35

    As many of you know, I've spent the last four plus years working on software that allows us Perl hackers to muck with the Raspberry Pi.

    Although the uptake is relatively small, it has been a very enjoyable experience for me providing this for the community, especially given that I've received welcome and helpful feedback, along with bug fixes and wonderful criticism throughout it all.

    Now, Mozilla is opening up their IoT Platform with both REST and WebSocket APIs for the masses. I've been following it for a little while to see where it goes.

    I've already thrown out the question on my Perl blog, but it means more to me to ask here on Perlmonks; would it be worth my time to ensure Perl has an interface to it?


equal treatment
1 direct reply — Read more / Contribute
by Anonymous Monk
on Oct 26, 2019 at 18:26

    I was writing a Perl version of a Python version of a Mac-centric Shell version of a BASIC program when there was a node about unequal treatment and I noticed that my finished perl and the original BASIC were both exactly 23 lines including the comment line added to each program and I could make an interesting node with a cute title that is a direct hyperlink to the source:


    # system 'clear'; print "Hello there. I'm a computer. What's your name? "; chomp($_ = <STDIN>); print "Hello ".$_.". You are welcome to computer land."; while () { print "What would you like to do today? 1) Say something random 2) Make a maze 3) Exit Enter your selection "; chomp($_ = <STDIN>); if (/1/) { system 'say', do { @_ = split /\n/, do{local(@ARGV,$/)="/usr/share/dict/words";<>}; $_[int rand@_] } } elsif (/2/) { print rand() < 0.5 ? '/' : '\\' for 1..3000 } elsif (/3/) { print "Bye"; exit } else { print "Try again." } }


    # import os import random import sys os.system("clear") print "Hello there. I'm a computer. What's your name?" G = raw_input() print "Hello " + G + ". You are welcome to computer land." while True: print "" print "What would you like to do today?" print "1) Say something random" print "2) Make a maze" print "3) Exit" print "Enter your selection" S = raw_input() if S == "1": F = open("/usr/share/dict/words").readlines() W = random.choice(F) os.system("say {}".format(W)) elif S == "2": for i in range(1, 3000): if random.random()>0.5: sys.stdout.write("/") else: sys.stdout.write("\\") elif S == "3": print "Bye." exit() else: print "Try again."


    # clear echo "Hello there. I'm a computer. What's your name?" read G echo "Hello $G. You are welcome to computer land." while true do echo "" echo "What would you like to do today?" echo "1) Say something random" echo "2) Make a maze" echo "3) Exit" echo "Enter your selection" read S if [ "$S" = "1" ]; then echo $( head -n $((7*RANDOM)) /usr/share/dict/words | tail -n 1 ) elif [ "$S" = "2" ]; then for i in {1..3000}; do if (($RANDOM>16384)); then printf '/'; else printf '\'; fi done elif [ "$S" = "3" ]; then echo "Bye." exit else echo "Try again." fi done


    REM 5 CLS 7 RANDOMIZE TIMER 10 PRINT "Hello there. I'm a computer. What is your name?" 20 INPUT G$ 30 PRINT "Hello "+G$+". You are welcome to computer land." 40 PRINT "What would you like to do today?" 50 PRINT "1) Make noises" 60 PRINT "2) Make a maze" 70 PRINT "3) Exit" 80 PRINT "Enter your selection:" 100 INPUT S$ 110 IF S$="1" GOTO 200 120 IF S$="2" GOTO 300 130 IF S$="3" GOTO 400 140 PRINT "Try again." 150 GOTO 40 200 SOUND 20+(RND*20000), RND*3 210 GOTO 200 300 SCREEN 1 310 IF RND>.5 THEN PRINT "/"; ELSE PRINT "\"; 320 GOTO 310 400 PRINT "Bye."
    Analysis of punctuation in each langage:
    cat | perl -ne '$_=join"",<STDIN>;@_=$_=~/[^A-Za-z0-9\s]/g;print@_'; echo""
    cat | perl -ne '$_=join"",<STDIN>;@_=$_=~/[^A-Za-z0-9\s]/g;print@_'; echo""
    cat | perl -ne '$_=join"",<STDIN>;@_=$_=~/[^A-Za-z0-9\s]/g;print@_'; echo""
    cat hello.bas | perl -ne '$_=join"",<STDIN>;@_=$_=~/[^A-Za-z0-9\s]/g;print@_'; echo""
    Last but not least:
    use Inline Python => <<'END'; # paste the py code here and run under perl! =) END

    I guess replace "say" with "print" ("echo" for shell) if $^O ne 'darwin'

The missing link between "you may need to install the module" and "distribution installed" application is running!
3 direct replies — Read more / Contribute
by Anonymous Monk
on Oct 24, 2019 at 07:57
    You may try a perl app and see Can't locate Foo/ in @INC (you may need to install the Foo::Bar module) (@INC contains: ...

    So you install the Foo::Bar module and try again and see Can't locate Bar/ in @INC (you may need to install the Bar::Baz module) (@INC contains: ...

    So you install the Bar::Baz module and the application runs.

    Module::Load::Conditional (core) can reduce the pain to:

    Install required modules Foo::Bar Bar::Baz from CPAN? (y)/n y
    Use 1. cpan or 2. cpanm 1/(2) 2
    Successfully installed Foo::Bar
    Successfully installed Bar::Baz
    Or select 'n' for something more than @INC:
    Install required perl modules:
    cpan Foo::Bar Bar::Baz 
    cpanm -v Foo::Bar Bar::Baz 
    Can't locate Foo::Bar Bar::Baz in @INC (@INC contains: ...
    Should perl be doing something like this on the core level?

    Should monks adopt this mess or fold it into a module so it becomes a best practice?

    How could this idea be improved?

    Thank you!

    #!/usr/bin/perl use strict; use warnings; #use Foo::Bar; #use Bar::Baz; use Module::Load::Conditional 'can_load'; BEGIN { my $modules = [ map {$_} qw[ IPC::Cmd Foo::Bar Bar::Baz ]]; my @install = do { local @_; for my $m (@$modules) { push @_, $m unless can_load(modules => {$m,undef}, autoload => 1)} @_ }; @install and do { print 'Install required modules ', join(' ', @install), ' from CPAN? (y)/n '; my $in = <STDIN>; chomp $in; $in ||= 'y'; my $cpanm = IPC::Cmd::can_run('cpanm'); if (lc $in eq 'y') { if ($cpanm) { print 'Use 1. cpan or 2. cpanm 1/(2) '; my $cpan = do { local $_ = <STDIN>; chomp $_; $_ ||= 2; $_ = 2 unless /^1|2$/; $_ }; if ($cpan == 2) { unless (system $cpanm, '-v', @install) { system 'perl', $0, @ARGV; exit } } } unless (system 'cpan', @install) { system 'perl', $0, @ARGV; exit } } else{ die "Install required perl modules:\n". join ' ', 'cpan', @install, "\n". ($cpanm ? join(' ', 'cpanm', @install) : '')."\n\n". "Can't locate ".join(' ',@install).' in @INC '. '(@INC contains: '.join(' ', @INC).") \n" } }; Bar::Baz->import('Something')}
use all core modules, pragmas and extensions
1 direct reply — Read more / Contribute
by Anonymous Monk
on Oct 23, 2019 at 10:55
    I wondered what would happen if one were to use all core modules. Here's what happened:

    19 core libs can not be simply used, without being fatal, so they're commented out (ymmv on versions ne 5.26.2).

    The perl interpreter grows to about 150 megabytes.

    A series of warnings is printed which may or may not have any value. This is why I'm sharing it here. In case the warnings indicate real issues, or interesting things to investigate.

    This 1-liner generates the ~650 line script, redirects stdout to the file "useallcore" and runs "perl useallcore" which prints the errors, and lines from ps about the perl process.

    perl -MExtUtils::Installed -MModule::Metadata -e '$not=q/_charnames|au +touse|blib|charnames|Devel::Peek|encoding|encoding::warnings|feature| +File::Spec::VMS|filetest|GDBM_File|if|O|ok|open|Pod::Simple::Debug|so +rt|Thread|threads/;$not={map{$_=>1}split/\|/,$not};print"#!/usr/bin/p +erl\n# Load all core Perl modules, pragmas and extensions\n# Exceptio +ns, to prevent errors:\n".(join "\n", map {"#$_"} sort {lc$a cmp lc$b +} keys %$not).")\n\n";@_=grep/\.pm/,(ExtUtils::Installed->files("Perl +"));for(@_){$m=Module::Metadata->new_from_file($_)->{module} or next; +push@m,$m}for(sort{lc$a cmp lc$b}@m){print $not->{$_}?"#":"","use $_; +\n"}print"\nprint `ps -v | grep \"\$\$\"`;\n"' > useallcore; perl use +allcore
If Perl 5 were to become Perl 7, what (backward-compatible) features would you want to see?
11 direct replies — Read more / Contribute
by haukex
on Oct 14, 2019 at 10:06

    Disclaimer: This post is entirely hypothetical. No decisions regarding Perl 5 have been made, or to my knowledge even been seriously discussed. It's entirely possible that Perl 5 will stay Perl 5 forever, or that the "5" will simply be dropped from the numbering (which would mean the next release of Perl is Perl 32), or something else happens.

    Now that Perl 6 has been renamed to Raku, that theoretically leaves open the possibility of Perl 5 upgrading to Perl 7. I've thought about what features would warrant a major version number change, and that's what I'm writing about here. My list is probably not complete, and I might update it if I think of more.

    First off, in my opinion, Perl should continue its tradition of being mostly backwards-compatible from release to release. If you want radical changes to the language, see Raku (and define your own slang) ;-)

    • Subroutine signatures need to come out of experimental
    • Smart matching should either be revamped, or removed entirely (Update: and if the latter, keep given as a topicalizer whose block can return a value)
    • Various other experiments should come out of experimental - e.g. refaliasing and declared_refs are IMHO pretty useful.
    • I'm not sure how this would be best implemented, but a "batteries included" Perl release would be nice. For example, one that includes Moo and other extremely common modules such as DBI. We might look to Strawberry Perl for an initial list.

    I imagine that, similar to Perl 6, a Perl 7 binary might be called perl7, with files being called .p7 or .pl7, .pm7, etc. Using this interpreter or this file extension would be the same as a use v7; (and turn on the corresponding feature bundle, etc.).

    Again, these are just hypothetical and unfinished thoughts of mine :-)

    Update: I accidentally created this post too early, sorry for all the additional edits. I'm done for now and further significant edits will be marked as such.

Quote about thinking of those who come after you.
2 direct replies — Read more / Contribute
by sbutton
on Oct 09, 2019 at 06:34
    Hi, I half remember a quote from way back along the lines of "When coding think about those who come after you, in case they do". I think it was from Tom Christiansen. Whenever I use it most people just look at me blankly, but that's perhaps part of the charm. Occasionally someone gets it. But after much searching, I can't find the original quote. Anyone got a link to it?
"Nonliteral literal" is just an expression.
1 direct reply — Read more / Contribute
by rir
on Sep 24, 2019 at 00:40
    With AoAs something like:
    my $ar = [ [ 'HEAD_goes_here', 'BODY_here' ], [ 'FOOT', 'FOOT', 'FOOT', 'FOOT' ] ];
    written as a template with the literals as documentation. After the not-finding and the not-thinking, I wrote a sub to walk AoAs and extract the references to the scalar elements. Doing it by hand, one might write:
    my $scalars_flattened = [ \$ar->[0][0], \$ar->[0][1], \$ar->[1][0], \$ar->[1][1], \$ar->[1][2], \$ar->[1][3] ];
    Its gist:
    my @flat = @{$_[0]}; while ( List::Util::any { 'ARRAY' eq ref $_ } @flat ) { @flat = map { 'ARRAY' eq ref $_ ? \(@$_) : \$_ } @flat; @flat = map { 'REF' eq ref $_ ? $$_ : $_ } @flat; }
    Fortunately only in testing did I find the less helpfully shaped templates like:
    $ar = [ 'HEAD', 'BODY', [ 'FOOT', 'FOOT', 'FOOT', 'FOOT'], ];
    I would die if I had one like that.

    Be well,

Language design: direct attribute access and postponed mutators (Perl Vs Python)
5 direct replies — Read more / Contribute
by LanX
on Sep 15, 2019 at 13:42
    Dear monastery,

    In my never ending desire to study different language designs I had a closer look into Python's OO model ...

    ... and I was very surprised to see that there attributes are accessed directly.

    object.attribute = 10

    is very common "pythonic" code.

    Doing something like object->{attribute}=10 is not only very uncommon in Perl but also heavily frowned upon.

    This is only partly because Perl's inner implementation is not necessarily a blessed hash and because in Perl methods and attributes have separated namespaces. (In python much like JS they are inside the same hash)

    The main issue is that at the moment of object design you can't know how the nature of getting and setting attributes may evolve in the future...

    ... for instance you may later want to restrict allowed values to a range of values and the setter to act like a guard which can potentially report errors.

    Could it be that the python community is totally ignorant of this issue?

    Seems not, for this case they reserve a backdoor mechanism called property where a simple attribute value is replaced by another object with dedicated get, set, delete accessors. And to facilitate using it they provide a @property decorator as syntactic sugar. "@Decorators" are the python equivalent of ":attributes" (For deeper insights please see this SO discussion)

    This reminds me a lot to the :lvalue technique once discussed for Perl.

    We can easily define a getter mechanism for a attribute with

    sub attribute :lvalue { return $value }

    And returning a tied value could be used to extend it with a proper setter.

    sub attribute :lvalue { return $tied_value }

    This help provide a object->attribute = 10 interface, were the Store and Fetch of the tied value would act as getter and setters.

    I remember seeing this discussed by Damian - not sure if here or in his OO book.

    IIRC he dismissed this technique for being to slow.


    • Could it be possible that the python solution is much faster?
    • If yes why?
    • are there better options in Perl to upgrade the easier interface?
    • Update: is Variable::Magic an option?

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

    PS: this is a meditation seeking for insights... fanboys please spare me with "just use moose propaganda", I'll ignore it.

The wave of unfamiliarness
No replies — Read more | Post response
by stevieb
on Sep 09, 2019 at 16:03

    I would like to apologize to all of my fellow Monks, friends, newbies and others here on Perlmonks.

    I've been on a severe roller coaster over the past few years, and it seems things have just kept up pressing without much of a break. Recently, I've been belligerent, argumentative, evasive and just not in-tune with how I normally behave.

    This is my favourite place on the Internet, and it has been for many years.

    I've been lacking in my responsiveness and dedication, and I'm not going to hide behind excuses. I am sorry if I've offended anyone.

    Apparently, last month I hit 10 years of having an actual account. Before that, I was here lurking for nine years or so.

    I love this place, and have much more to bring forth, while I continue to learn as I always have.

    Your patience has been welcoming, and I appreciate all of the kind feedback as always.

    I'm hoping, within a week or so, to get published here my dedicated Raspberry Pi test platform that also contains certain security monitoring aspects for my home. I know some have been interested in security systems, so I decided to use my hardware CI platform to monitor some windows, doors, laser trip wires and PIRs that send me photos/videos via text if any are breached so that I could test my OLED display software, serial and I2C modules, and other things that are now so common to me they may as well be within my dedicated Unit Test Suite.

    I also have a few other things up my sleeve, but I've got about a month of going through my bugs/issues to get as many out of the way as possible before I begin another weird venture.

    Cheers all, and thanks.


RFC: new module WebService::Discord::Webhook
1 direct reply — Read more / Contribute
by hornpipe2
on Sep 03, 2019 at 12:34
    I originally posted this to Reddit, which directed me here.

    First, the Github link:

    The Discord chat service allows server ops to create "webhook"s for their server. These are special secret URLs that allow an external client to post notifications into chat by making certain HTTP requests.

    (For those unfamiliar with Discord, think "Slack, if it chugged a 12 pack of Mountain Dew".)

    I created this Perl module as a way to help interact with Discord webhooks. The various functions of Webhooks are wrapped in Perl functions that execute with HTTP::Tiny, and data structures with JSON::PP. I tried to focus on ease of use and documentation.

    I would appreciate it if anyone could provide feedback or check the code and see if it looks sensible. I do plan to submit this to CPAN and it would be my first module there, so I want to make sure I get it right!

    EDIT: also on PrePAN now:

    EDIT2: Nobody had complaints except the names... no news is good news, I guess. It's on CPAN now.

Fun with implicit type conversions
3 direct replies — Read more / Contribute
by haj
on Aug 29, 2019 at 11:34
    Recently, jdporter closed one of his comments with the following snippet: $orry - not $orry

    This is a valid Perl expression. So, I wondered, what is its value? My first thought was "easy: that's just $orry converted to a number", but as ever so often, my first thought is wrong. If $orry = 0, then the value is -1. If $orry is a string, then the value is 0. Unless the string is empty, in which case the value is -1. And unless the string starts with a number, where the result is that number, even if the number is 0. And then, there are references, typeglobs, tied scalars, and objects, which may even overload stuff.

    Here's a collection of expressions for $orry, and results of $orry - not $orry.

    $orry : $orry - not $orry 42 : 42 -1 : -1 0 : -1 undef : -1 "" : -1 0e0 : -1 "0e0" : 0 "a123" : 0 "-.2e2e" : -20 "nancy boy" : NaN "infidelity" : Inf *STDOUT : 0 [] : 94269931603432 File::Temp->new : 94269935380840 URI->new(q( : 0

    The implicit conversions of scalars into numeric / boolean / string context are amazing, and sometimes scary. Fortunately, use warnings; detects most of the surprising ones.

    Update:: syphilis contributed the strings "nancy boy" and "infidelity" which are indeed amusing additions. I inserted them after the strings starting with numbers. In the case of 'nancy boy' my text "string starts with a number" looks silly because NaN claims to be not a number.

Help with my crap
5 direct replies — Read more / Contribute
by stevieb
on Aug 22, 2019 at 20:59

    Esteemed Monks and fellow travelers,

    I'm in a position where I've got a tad bit too much to handle, so I'm putting out a request.

    For years, I've supported Perl in ways that nearly defied logic relative to my real life. Came from nothing, did something, blah blah blah.

    Many have done that. What I appreciate is the attentive use and comprehensive addition to Perl that so many Monks and others have contributed to my favourite language over the last near-20-years.

    Now, I'm not as dynamic. I'm not as fluid and liquid to bounce from one thing to the other by the minute. I can't maintain my library of software myself anymore.

    For that, and for many other reasons, I'm hoping to liquidate or at least get help with some of my Open Source Software projects.

    I'm STEVEB on the CPAN, and my repo stash is here. Take a look and let me know if there's anything you'd like to grab or take part in.

    berrybrew, as well as a few CPAN dists I favour I'd like to oversee, but mostly, take a look and let me know if you want to overtake anything.

    License retention, DVCS experience (repos stay in a freely-available and accessible location), and a proven love for Perl are absolute requirements. I put my love into what I've done. I would hope someone would take my silly code and keep it something that's usable.

    One last statement... don't take job offers seriously without doing extreme and exceptional due diligence. I got fucked up the ass while I had head injuries. Sickening, yep, fucking angering, yep, don't accept any job if you don't get paid in advance. This world is a different place anymore. I am just too tired to be raped without appreciation.

    Street-smart linguistic troublemaker who didn't see a fabricated theft coming right at him. I'm ashamed.


Truth and Falsehood
4 direct replies — Read more / Contribute
by haukex
on Aug 17, 2019 at 05:19

    Truth and Falsehood

    In Perl, the following values are false in boolean context:

    • The number zero (0)
    • The string "0"
    • The empty string ""
    • undef

    All other values are true.

    Boolean context is a scalar context. Therefore the following things, when evaluated in boolean/scalar context, are also false:

    • An empty array, which evaluates to the number of elements it contains, i.e. zero (0).
    • An empty hash, which evaluates to a false value when it is empty.
    • The empty list (), which evaluates to undef.

    A true value negated by ! or not, plus many of Perl's builtins/operators, return a special false value: When evaluated as a string it is treated as "", but as a number, it is treated as 0, without causing any warnings.

    When the Perl documentation says that a operator or function returns "a false value" or "a true value" (or more simply, "false" or "true"), it may return any of the above values.

What modules should be added to the corelist?
7 direct replies — Read more / Contribute
by Anonymous Monk
on Aug 16, 2019 at 09:17

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 scrutinizing the Monastery: (6)
    As of 2019-11-15 23:07 GMT
    Find Nodes?
      Voting Booth?
      Strict and warnings: which comes first?

      Results (85 votes). Check out past polls.