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
[Perl 6]: Small discoveries VI, die
1 direct reply — Read more / Contribute
by holli
on Oct 19, 2017 at 18:41
    In Perl 6, die still prints an error to STDERR and exits (unless caught), however adding a newline to the end of the error message will produce a stack trace.

    The idiom for printing an error message and stopping the program in Perl 6 is:
    note "Error Message" and exit 42; # or some other number (except 0)


    holli

    You can lead your users to water, but alas, you cannot drown them.
[Perl 6]: Small discoveries V, True / False / FileNotFound
1 direct reply — Read more / Contribute
by holli
on Oct 19, 2017 at 13:54
    Omg, I love this. Did you ever have a clear, slick little function that needs to return a boolean, and you also want to communicate an error condition? You basically have the choice of returning two values, reversing the consuming condition (meaning an empty return value be considered true), or using a string reference as an argument to the function.

    Witness Perl 6:
    sub slick() { if do-stuff { return "SomeValue"; } else { return "Some error message" but False; } } if my $result = slick { process( $result ); } else { log-error( $result ); }


    holli

    You can lead your users to water, but alas, you cannot drown them.
Be prepared for CSV injections in spreadsheet
3 direct replies — Read more / Contribute
by Tux
on Oct 18, 2017 at 07:34

    Read this article to get an idea of how dangerous it can be to blindly accept macro's in spreadsheets. Be it MS Excel or Google spreadsheets, they all suffer.

    You cannot blame CSV for it. CSV is just passive data.

    Once you load or open a CSV file into something dangerous as a spreadsheet program that allows formula's to be execcuted on open, all bets are off. Or are they?

    The upcoming Text::CSV_XS has added a new feature to optional take actions when a field contains a leading =, which to most spreadsheet programs indicates a formula.

    On both parsing and generating CSV, you will be able to specify what you want to do (where "formula" does not go beyond the fact that the field starts with a =):

    • Do nothing special (default behavior) and leave the text as-is
    • Die whenever a formula is seen
    • Croak when a formula is seen
    • Give a warning where a formula is seen
    • Replace all formulas with an empty string
    • Remove all formulas (replace with undef

    Code speaks loader than words ...

    I'm pretty pleased with the diagnostics

    $ cat formula.csv a,b,c 1,=2+3,4 6,,7,=8+9, $ perl -MCSV -e'$_ = dcsv (in => "formula.csv", bom => 1, formula => " +diag")' Field 2 (column: 'b') in record 1 contains formula '=2+3' Field 4 in record 2 contains formula '=8+9'

    Expect this to be available by next week.


    Enjoy, Have FUN! H.Merijn
Perl6 discoveries ó floating-point
2 direct replies — Read more / Contribute
by Grimy
on Oct 18, 2017 at 06:59
    Anonymous Monk brought up a really interesting discovery here. Unfortunately, that thread got derailed, so Iím making a separate one, as suggested by Your Mother. One of the first things I found while testing is this really interesting tidbit:
    $ perl6 -e 'say 0.99999999999999999000001' 1.000000000000000073886090 $ perl6 -e 'say 0.99999999999999999000001 > 1' True
    But then I realized I was using an outdated Rakudo (2017.04). So I updated to 2017.09, and now those print 1 and False, respectively. Thereís still some interesting behavior in 2017.09, though:
    $ perl6 -e 'say 0.7777777777777777777770' 0.77777777777777785672697 $ perl6 -e 'say 0.7777777777777777777771' 0.777777777777777767909129
    Note that the second number printed is strictly smaller than the first one, even though the second source number is strictly larger than the first one, spelled in the same fashion and to the same number of significant digits! However, comparison and subtraction still return exact results:
    $ perl6 -e 'say 0.7777777777777777777771 > 0.7777777777777777777770' True $ perl6 -e 'say 0.7777777777777777777771 - 0.7777777777777777777770' 1e-22
    Okay, thatís probably because one is a Num and the other is a Rat, so letís convert everything to Num explicitly:
    $ perl6 -e 'say Num(0.7777777777777777777770)' + 0.777777777777778 $ perl6 -e 'say Num(0.7777777777777777777771)' 0.777777777777778 $ perl6 -e 'say Num(0.7777777777777777777770) > Num(0.7777777777777777 +777771)' True $ perl6 -e 'say Num(0.7777777777777777777770) - Num(0.7777777777777777 +777771)' 1.11022302462516e-16
    Huh. Now they print the same, but theyíre still different numbers when compared. Note that the sign of the difference got switched:
    $ perl6 -e 'my $a = 0.7777777777777777777770; my $b = 0.77777777777777 +77777771; say $a <=> $b; say Num($a) <=> Num($b)' + Less More
    Also interesting is that many Nums donít survive a round-trip to Str:
    $ perl6 -e 'my $a = Num(1/9); say $a == Num(Str($a))' False
    Can anyone point me to the Perl6 specs/docs/whatever that explain those behaviors?
Parsing HTML/XML with Regular Expressions
8 direct replies — Read more / Contribute
by haukex
on Oct 16, 2017 at 07:48

    Your employer/interviewer/professor/teacher has given you a task with the following specification:

    Given an XHTML file, find all the <div> tags with the class attribute "data"1 and extract their id attribute as well as their text content, or an empty string if they have no content. The text content is to be stripped of all non-word characters (\W) and tags, text from nested tags is to be included in the output. There may be other divs, other tags, and other attributes present anywhere, but divs with the class data are guaranteed to have an id attribute and not be nested inside each other. The output of your script is to be a single comma-separated list of the form id=text, id=text, .... You are to write your code first, and then you will be given a test file, guaranteed to be valid and standards-conforming, for which the expected output of your program is "Zero=, One=Monday, Two=Tuesday, Three=Wednesday, Four=Thursday, Five=Friday, Six=Saturday, Seven=Sunday"2.

    Updates - Clarifications:
    1 The class attribute should be exactly the string data (that is, ignoring the special treatment given to CSS classes). Examples below updated accordingly.
    2 Your solution should be generic enough to support any arbitrary strings for the id and text content, and be easily modifiable to change the expected class attribute.

    Ok, you think, I know Perl is a powerful text processing language and regexes are great! And you write your code and it works well for the test cases you came up with. ... But did you think of everything? Here's the test file you end up getting:

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"[ <!ATTLIST html xmlns:xsi CDATA #FIXED "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation CDATA #IMPLIED > ]> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/1999/xhtml http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" + /> <title>Hello, World</title> <script type="text/javascript"> //<![CDATA[ console.log(' <div class="data" id="Hello">World</div> '); //]]> </script> </head> <body> <div class="data" id="Zero" /> <div class="data" id="One">Monday</div><div class="data" id="Two">Tues +day</div> <div id="Three" class='data'>Wednes<div id="day">day</div></div> <div class="data" id='Four'><b>Thursday</b></div> <div class="data" id="Five"> Friday </div> <div class = "data" id = "Six" > <div > Satur </div > day </div > <div title=" class='data' id='Foo'>Bar" id="Seven" class="data">&#xA0;Sunda&#121;</div> <div class="data otherclass" id="aaa">bbb</div> <div class="otherclass" id="ccc">ddd</div> <p class="data">eee</p> <p id="fff">ggg</p> <!-- <div class="data" id="Quz">Baz</div> --> <p><![CDATA[ <div class="data" id="Bye">Bye</div> ]]></p> </body> </html>

    Fun, right? While the above happens to be XHTML, the same problems (and more) of course apply to XML, and HTML also quickly gets much worse - just to name one example, did you know about SGML shorthand markup? The following is perfectly valid HTML 4.01 (and even browsers may have trouble with it): <p<a href="/">foo</> (source)

    If you're now thinking to yourself, "I've been working with this XML for a few years now and have never seen its format change", then imagine this scenario. The third party providing the XML hasn't touched their code, but decides to upgrade their OS libraries, including the one that writes the XML. Suddenly, you can no longer rely on the order of attributes, whitespace, etc., and your regex starts failing, and your bosses are on your back because they are losing money because their feeds are interrupted. Now take that thought a step further, and imagine you start working for a company where the person who wrote that regex is long gone, and you get to maintain it...

    So I hope it is clear: Please, don't try to parse arbitrary XML/HTML with regexes! (...just for fun) Do yourself and the future maintainers of your code a favor and just use one of the many modules that are available.

    I encourage everyone to try and write a parser using your favorite module, be it:

    Honorable mentions: Grimy for a regex solution and RonW for a regex-based parser :-)

    I'll kick things off with Mojo::DOM (compacted somewhat, with potential for a lot more golfing or verboseness):

    Update 2017-10-18: Thank you very much to everyone who has replied and posted their solutions so far, keep em coming! :-)

Orbital starters
2 direct replies — Read more / Contribute
by holyghost
on Oct 10, 2017 at 04:50
    I started out on some code for making molecular orbitals, here'sthe beginning for atomic oribtals :
    package orbital2::TimeD; sub new { my ($class,$d) = shift; my $td = $d; bless $self, $class; return $self; } package orbital2::TimeDelta; sub TimeDelta { my ($class) = shift; bless $self, $class; return $self; } sub Tick { my ($class) = shift; my ($seconds, $interval, $milliseconds) = shift; ### 2 args my $hope = undef; bless $self, $class; } sub TickCalculate { my ($self) = shift; return my $self->hope = $self->$seconds / $self->interval } package orbital2::TimeF; sub new { my ($class,$f) = shift; my $tf = $f; bless $self, $class; } package orbital2::TimeP; sub new { my ($class,$p) = shift; my $tp = $p; }
[Perl6] Small 6 discoveries V, Sigils
1 direct reply — Read more / Contribute
by holli
on Oct 08, 2017 at 19:02
    Some people like sigils. Some people don't. In Perl 6 you don't have to use them (as much).
    my $x = 1; say $x; my \y = 1; say y; my @x = 1, 2; say @x; my \y = @ = 1, 2; say y; # also works with signatures sub foo(\x) { say x }; foo(1);
    However you can't use sigilless attributes
    class ThisExplodes { has \.y; #doesnt work has \y; #neiter does this }
    You can use this for example to distinguish normal variables from ones in closures, or lexicals from function arguments or whatever. Or maybe you event want to get rid of all sigils where possible.

    The choice is yours.


    Addendum
    Sigilless variables do not create containers and are always immutable after initialization. They are therefore not a simple replacement with different visuals.

    Edit: Fixed typo as hinted by NetWallah


    holli

    You can lead your users to water, but alas, you cannot drown them.
[OT] Slashdot is 20
2 direct replies — Read more / Contribute
by 1nickt
on Oct 05, 2017 at 14:45

    If you are of a certain age and have been developing for the web for long enough, you will recognize a lot of the details in CmdrTaco's meditation on the beginnings of Slashdot on its 20th birthday, from watching the output of tailing your Apache referrers log in amazement, to the Kai's Power Tools drop shadow on the logos. Good times! (Too bad he doesn't mention that the whole thing was built in Perl.)


    The way forward always starts with a minimal test.
[Perl6] Perl 6 discoveries IV, hash access
2 direct replies — Read more / Contribute
by holli
on Oct 04, 2017 at 19:41
    Perl 6 has different ways to access hash elements:
    use v6; my %hash = :a<A>, :b<B>; say %hash{'a'}; # says A say %hash<b>; # say B
    This however leads inevitably to
    #most likely not what you want, but prints an undefined warning say %hash<$somekey>;
    which is a hard to spot bug since these: <> do not interpolate. That did just cost me quite a while.

    Edit: Renamed as per advice


    holli

    You can lead your users to water, but alas, you cannot drown them.
Paragraph grep: request for testing, comments and feedbacks
2 direct replies — Read more / Contribute
by siberia-man
on Oct 04, 2017 at 14:30
    Hello Monks, I came here for your critics, feedbacks and proposals for improvements. I have developped the simple script for grepping paragraphs (block of text lines delimited by the specific separator (blank lines, by default).

    The common use case is parsing of java log entries that can be extended onto multiple lines:
    paragrep -Pp '^\d+/\d+/\d+ \d+:\d+:\d+' PATTERN FILENAME
    Another use case is filtering sections from ini files matching particular strings:
    paragrep -Pp '^\[' PATTERN FILENAME
    For now I am going to improve searching patterns and add support for -a/--and and -o/--or options to control matches. Using this message I ask you to test the script and point me on possible leaks in performance and efficiency.

    The original and actual code is hosted on github (It's not permitted to post external links but you can search for ildar-shaimordanov/perl-utils)
    Here is the latest (to the moment of creating this message) version of the script: Thank you
Lesson Learned: not all 32b perls are created equal
1 direct reply — Read more / Contribute
by pryrt
on Sep 30, 2017 at 11:22

    Given the pretty CPAN Testers Christmas Tree, especially in the *BSD columns, I learned that not all 32-bit perls are created equal. After some more debug, I was able to show that it was those 32-bit perls with $Config{ivsize}==4 (32bit integers; aka perl -V:ivsize) that were failing, but those with $Config{ivsize}==8 (64bit integers in 32bit perl) would pass.

    I had assumed (without looking) that the default ivsize on the 32bit perl was 4 bytes (32 bits), so thought that I had already tested and verified my IV weren't overflowing (or, if they were, they were promoting to NV). After seeing the problem, I discovered that when using left-shift, it would go from IV to NV... but it didn't. However, *=2 did promote the way I expected:

    <berrybrew use perl-5.12.3_32> C:\Users\Peter>perl -MDevel::Peek -lE "$iv=1<<30; for(1..3) { Dump $iv +; $iv<<=1; }" SV = IV(0x68fc28) at 0x68fc2c REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1073741824 SV = IV(0x68fc28) at 0x68fc2c REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 2147483648 SV = IV(0x68fc28) at 0x68fc2c REFCNT = 1 FLAGS = (IOK,pIOK) IV = 0 <berrybrew use perl-5.12.3_32> C:\Users\Peter>perl -MDevel::Peek -lE "$iv=1<<30; for(1..3) { Dump $iv +; $iv*=2; }" SV = IV(0x24dfbe0) at 0x24dfbe4 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1073741824 SV = IV(0x24dfbe0) at 0x24dfbe4 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 2147483648 SV = PVNV(0x7ea464) at 0x24dfbe4 REFCNT = 1 FLAGS = (NOK,pNOK) IV = -2147483648 NV = 4294967296 PV = 0 <berrybrew use perl-5.12.3_32> C:\Users\Peter>perl -V:ivsize ivsize='4';

    Conclusion: when doing a testing suite across versions, it's not always enough to just have a "32bit perl"; especially if you are dependent on integer sizes, also check that your test suite includes multiple ivsize values.

[Perl6] Small discoveries I, __DATA__
2 direct replies — Read more / Contribute
by holli
on Sep 27, 2017 at 10:38
    Perl6 knows no __DATA__ construct. One can however, use the =finish pod marker and the $=finish variable for similar effect.
    use v6; say $=finish; # says "foo" =finish foo
    Edit: Renamed as per advice


    holli

    You can lead your users to water, but alas, you cannot drown them.
[RFC] File::Replace
2 direct replies — Read more / Contribute
by haukex
on Sep 20, 2017 at 05:50

    Many of you are probably aware of the pattern of opening a temporary file, reading from the original file and writing the modified contents to the temporary file, and then renameing the temporary file over the original file, which is often an atomic operation (depending on OS & FS). I recently wrote a module to encapsulate this behavior, and here is one of three interfaces that are available in File::Replace. There are several options to configure the behavior, including the ability to specify PerlIO layers, what happens if the file doesn't exist yet, etc.

    use File::Replace 'replace2'; my ($infh,$outfh) = replace2($filename); while (<$infh>) { # write whatever you like to $outfh here print $outfh "X: $_"; } close $infh; # closing both handles will close $outfh; # trigger the replace

    Since I hope this is something that you might find useful, I would be happy about any feedback you might have!

    To give a practical example, here is an update of my code from this node. As you can see I was able to get rid of eight lines of fairly complicated code, while keeping the main loop entirely unchanged. The module also adds some more robustness, as it incorporates a few more checks on whether operations were successful or not.

Encoding Decoding on multiple formats RFC
2 direct replies — Read more / Contribute
by thanos1983
on Sep 19, 2017 at 06:44

    Hello fellow Monks,

    I am looking for your advice on updating and my implemented module for encoding and decoding multiple formats. I wrote the module and tried to include as many formats I could. I know that there other formats that I have not added but in my case during the encoding decoding process has to be also converted to hex and vise versa, where I found problems with more formats that I have not included on my sample of code.

    The whole idea behind the module, I am working for a telecommunication company and part of my daily job is to correct problems. The languages can vary globally since it is a live network with live customers and the format is in hex on a variety of encoding patterns. I had some cases that I had to create small scripts to process the packages before and after the nodes so I can observe encoding corruptions or not. Sample of previous questions that I was working that are similar with the module (Chinese to Hex and Hex to Chinese, Arabic to Hex and Hex to Arabic). After seeing my self that I need more and more encodings for more and more languages I end up saying that I need to write a simple module to do that for me instead of creating more or less the same code again and again.

    So having said that, sample of code as the user would use the module based on the encodings that can be handled:

    The actual module, that I still have not found a good name to apply. Any ideas for naming please feel free to propose.

    The module by it self is extremely simple, but at the same time on my position and for my colleagues is extremely useful. Any suggestions on code or any other improvement please feel free to suggest.

    Hope this tiny module will help others also.

    BR, Thanos

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Kindness and support for Meredith
No replies — Read more | Post response
by stevieb
on Sep 18, 2017 at 11:47

    This isn't about Perl; it's about the community.

    Early last week, I wrote in CB about a tremendously disturbing event that took place with my family.

    In response, several Monks reached out to offer condolences and offers of help.

    In my near absence from here since then, a bunch of Monks got together, and 1nickt reached out a few times to say that a group of Monks wanted to do something. Initially, I was advised that the offer could be in the form of finance for travel etc. After I carefully deliberated this kind gesture and discussed with my wife, I decided that I wouldn't feel comfortable taking any funds directly, so I let Nick know that it would be preferred to send flowers or donate to a charity instead.

    I was advised by Nick that a beautiful arrangement had been sent on behalf of the Monks, and any left over funds plus any more funds that may trickle in would be donated to some form of preventing violence charity. I advised Nick that I was too busy to deal with it, so I asked if he'd spearhead the decision of which one.

    I want to express my (and my wife's) deepest gratitude for such an overwhelmingly kind gesture by everyone involved; those who provided funding, as well as those who reached out to offer emotional support. I'd like to thank Nick directly as well for taking the time to organize everything he did.

    This goes to show that this is a great place of caring, not just another forum to get help with questions.

    Perlmonks is the only group I let in on what had happened, as it's the only online forum where I feel so comfortable, and people here came through with flying colours... the manner was absolutely unexpected; stunning actually.

    Thank you very much everyone, it's kind of hard to put into words, so instead, I'll just try to get back into the groove and give back the best way I can; by continuing to help those who need it here.

    Cheers,

    -stevieb


Add your Meditation
Title:
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.