Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Meditations

( #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
Conflict in Teams
2 direct replies — Read more / Contribute
by eyepopslikeamosquito
on Jun 12, 2017 at 09:29

    Following on from Working Solo and in a Team, this meditation focuses on conflict in teams.

    Vulnerability and Trust

    I'm a genius and always the smartest person in the room. I also am the greatest expert on every topic ever as soon as I've thought about it for at least five seconds, none of my subordinates could possible know more about anything than me so I should always be micromanaging them and telling them exactly what to do in every situation, and if you think what I said blatantly makes no sense that's just because you are so simple compared to my vast intellect. Well, if we failed in our goals it's obviously the fault of all my various subordinates and not me, because after all, I'm awesome!

    -- perldigious describes a dysfunctional manager he once worked for

    Vulnerability and trust are crucial to good teamwork. Everyone in the team needs to be vulnerable. Everyone. To freely admit: "I don't know the answer", "I need help", "I stuffed up, sorry". Sadly, just one team member with a toxic attitude, like perldigious's dysfunctional manager above, destroys teamwork.

    Reinforcing points made in Psychological Safety, Patrick Lencioni, in a talk on Team Dysfunctions, gives some real-world examples of teams becoming dysfunctional when just one team member could not be vulnerable. And it's worst of all when that one non-vulnerable team member happens to be the team leader.

    How to get everyone in the team to be vulnerable and acknowledge their weaknesses? According to Patrick, there is only one way: The leader must go first!

    Why is vulnerability and trust so important?

    Conflict

    Without trust, conflict is politics. With trust, conflict is the pursuit of truth.

    -- Patrick Lencioni in The Five Dysfunctions of a Team

    Conflict is normal. Conflict is expected. Part of the human condition. Handling conflict effectively is the primary reason why trust is so important in teams. Without trust, conflict tends to become personal or political; with trust, conflict is the pursuit of truth, finding the best solution.

    It's vital for the team to not hold back, to disagree passionately when required. To be honest to each other. And respectful. Is arguing a "waste of time"? No! No argument means no commitment! Of course, the arguments must be focused on finding the best solution, never personal or political.

    Disagree and Commit

    Intel has a saying: Disagree and Commit. Curiously, without disagreement it's difficult to get commitment and cohesion. In general, when people have a chance to express their point of view and have its pros and cons heard and appreciated, they are more likely to accept and support a differing approach.

    In contrast, conflict that persists after the group has made a well-examined decision is often harmful. At a certain point in a project, the potential benefit of changing approaches is less than the disruption caused by changing direction. At that stage, commitment is required. Early disagreement is welcome, but then the team must unite behind a shared goal.

    -- Disagree and Commit: The Risk of Conflict to Teams

    Have Backbone; Disagree and Commit. Leaders are obligated to respectfully challenge decisions when they disagree, even when doing so is uncomfortable or exhausting. Leaders have conviction and are tenacious. They do not compromise for the sake of social cohesion. Once a decision is determined, they commit wholly.

    -- Amazon 13th Principle

    Though Intel and Amazon share the same "Disagree and Commit" slogan, they appear to have a different emphasis. Intel emphasize teamwork and cohesion (when people have a chance to express their point of view and have its pros and cons heard and appreciated, they are more likely to accept and support a differing approach) while Amazon focus on faster decision making ("I know we disagree on this but will you gamble with me on it? Disagree and commit?") and innovation (for more innovation, you need disagreement, not consensus).

    Accountability

    Peer-to-peer accountability is the best kind of accountability. When people don't commit, they don't hold each other accountable. Leaders must be willing to hold people accountable, not just on quantitative issues (KPIs), but behavioral ones too.

    References

Is what you want available?
6 direct replies — Read more / Contribute
by Lady_Aleena
on Jun 08, 2017 at 18:07

    As some of you may know, I am trying to become a better Perl writer. Part if it is finding where I wrote something that can be done better by someone else and using the better way.

    One time I needed to do a numeric comparison of months written as text. So I wrote a module to get the munth numbers needed. After I wrote it, I found to my dismay, I had not needed to write it. Date::Calc had a subroutine called Decode_Month that was much better than what I wrote. I am so embarrassed I did not think to look in Date::Calc first before I wrote my silly little module. Date::Calc is far better at date manipulation than anything I could write. So, I dropped the use of my module for Date::Calc. It was a learning experience I took forward to the rest of my code.

    Another part of becoming better is rewriting and renaming the modules I have written. To find names for my modules, I have been crawling CPAN to find what name spaces already exist.

    I was looking for a new name for my Util::Number module. I crawled CPAN and found "Number" is a top name space. Then I found Number::Format. I sighed thinking my little Util::Number's days were numbered. Number::Format has a subroutine called round and so did Util::Number. Both do the same thing. Number::Format has a subroutine called format_number that puts commas in numbers and rounds numbers together, just like commify and my pretty_number. I thought commify and pretty_number were not going to be able to match format_number's power.

    So, I installed Number::Format and was going to discontinue using my Util::Number. Why? Using Number::Format in code that I need help with, you can install it from CPAN without any trouble. Using Util::Number in code that I need help with, you would have to guess at what it does unless I also put Util::Number in the node with my problem code.

    So, I was changing over my code from pretty_number to format_number and making sure it returned what I wanted. Then I got a big surprise. format_number has limitations commify and pretty_number do not have. format_number can not put commas into very big numbers. It outputs an error about the big number and suggests using Math::BigFloat.

    format_number

    perl -e 'use Number::Format qw(format_number); print format_number(123 +45678987654321)."\n";'

    returns...

    round() overflow. Try smaller precision or use Math::BigFloat at -e li +ne 1.

    commify

    perl -e 'use Util::Number qw(commify); print commify(12345678987654321 +)."\n";'

    returns...

    12,345,678,987,654,321

    In the change over from commify and pretty_number to format_number, I got another surprise. format_number does not do ordinal numbers either. I fed it an ordianal number in Happy unbirthday redux! and other birthday stuff, and it returned the following error.

    Argument "16725th" isn't numeric in numeric comparison (<=>) at /home/ +me/perl5/lib/perl5/Number/Format.pm line 599.

    So, I went back to commify in my code and got...

    Happy 16,725th unbirthday, Aleena! You have 32 days until your next bi +rthday on July 10, 2017.

    This was all so surprising to me. Here I was ready to use a module readily available on CPAN instead of my own silly little module, but the CPAN module could not do what mine does. I was thinking "But it's is so much better than mine. It's got all those bells and whistles. And it's on CPAN!"

    This is not a rant against Number::Format. It is on CPAN and is better written than my little Util::Number. I will use Number::Format in code when I need help. Number::Format also has options I do not currently have, so I will be using it whenever one of those options is needed. Util::Number may become a fallback module when Number::Format will not work for what I am doing currently. Util::Number will not be going to CPAN since I did not write commify or round, I just put them together in pretty_number.

    Util::Number

    I am trying to make my modules more useful with better names and code. I am also trying to get better by using what is already available. However, sometimes, what is available is a little less than what is wanted. That does not mean I will stop searching.

    Afterward...

    I cracked opened my now disused month module just to look at it. Then I saw the hash of arrays. What do I do with hashes of arrays of similar data? I randomize it of course. So my Util::MonthNumber is now Random::Month... 8)

    Random::Month

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena
Perl Shields/Badges
3 direct replies — Read more / Contribute
by choroba
on Jun 08, 2017 at 08:43
    I've used the Kwalitee and CPAN shields/badges in some of my GitHub/CPAN repositories for years. Recently, though, it seems the badges stopped working—for example, see Syntax::Construct: kwalitee doesn't display at all (but I can view the image directly), the CPAN badge shows the current version as ?.?.?.

    My speculation is it's caused by some changes to CPAN and its infrastructure at the Perl Toolchain Summit this May.

    Does anyone have any idea whom to ask?

    See Re: VERSION section in POD for a previous mention of the shields in the Monastery.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
OT: Stupid User Interfaces
3 direct replies — Read more / Contribute
by afoken
on May 30, 2017 at 19:29

    Just a little rant ...

    I came home quite late, after a long day. Some excavator or a poor guy with a spade has cut a major power line. The power network company has fixed that, at least provisionally, so power was already back when I came home. What could be wrong?

    The microwave oven happily told me it was 7:15 am. Oh well. Press the clock button. Oops, that was the timer, better press the other button with a very similar clock symbol. "12h" on the display. No, I'm in Europe, I want 24 h. Turn the wheel button. Wrong. Now I'm adjusting hours in the 12 h system. Press the clock button a few more times, jumping past minutes, back to "12h", then to "24h", then again minutes. Oops. Well, give the clock button a few more cycles. "24h". Yes! Now, rotate the wheel button. "1:", "2:", "3:", ..., "11:". Ok, turn it in reverse: "10:", "9:", ... "23:". OK. Push the wheel button. "BEEEP! Stupid user!". Oops. Push the clock button again. I wonder how many push cycles are left. Adjust the minutes. ":00", ":01", ... ":23". Push the wheel - no "BEEEP!" - ok, I'm tired. Press the clock button once more. Done.

    Home office ISDN system phone: It displays its name and its firmware version. WTF? Maybe power did not come back cleanly? Unplug the combined ISDN and power jack, and fiddle it back in. Nope, does not help. Load the configuration program, adjust a minor setting, write back the configuration, to clean up NVRAM / EEPROM. Also does not help. Maybe the PBX lost its clock? Sure it did. It has no RTC, or at least no battery backup. But thanks to ISDN, it will adjust its clock when I call some external number and establish a connection with someone else. So I called a free hotline, and waited for their answering system. Yepp, it talks to me. Hung up. The PBX should now have adjusted its clock. But wait: The stupid phone still shows name and version, not date and time. Well, let's flash the firmware. It's just a few more mouse clicks. "Firmware is already at 2.3e. Do you still want to update the firmware?" Sure. About a minute later, the phone goes through a little disco mode, slowly flashing almost all LEDs, then comes back with name and version, and is still stuck there. Grrrrrrr! Where is my password for the support forum? It must be something simple. RTFM before posting nonsense. Yeah, right: That stupid phone refuses to switch to date and time until it has fetched the current date and time from the PBX. And the PBX does not have current date and time, despide having made a successful external call. Did some internal calls from and to the office phone. No help. So, dig through the three manuals of the PBX, and yes, there is a way to adjust the PBX's clock manually. Just dial a magic 20+ digit code, put in date and time at the right positions, and it will adjust its clock. So, let's start. Error at the fifth digit or so, PBX beeps "STUPID USER" and refuses any more configuration until I hang up. But hey, I've a smart office phone, I'll enter the magic code before picking up the handset, as I can correct errors there. Well, nice idea, but the phone dials dumb, whereas the PBX expects some delays in the code. Again, it beeps "STUPID USER" and expects me to hang up. And lo and behold, somehow the phone has managed to get date and time from the uncooperative PBX and shows date and time instead of name and version, as if nothing has happened. Why doesn't that *$%§%! phone simply display "Date and time not set in PBX"? And why doesn't that PBX contain a sub-1$ RTC chip and a similarily cheap CR2032?

    Answering machine. No. Not today. It has a display. It blinks "St" = Stellen (adjust time). It has << (rewind) and >> (forward) buttons, and it has + and - buttons. And a set button. + and - do not work for adjusting time, you have to use << and >>. OK, but that stupid machine insists on speaking every single number. "Adjusting time. [Silence] 1 hour. [Silence] 2 hours. [Silence] 3 hours." It's 23:45 or so. Holding down the buttons changes the increment from 1 to 5 after some ages. After some more ages, about at sunrise, I would be finished. No, it will have to wait.

    Other mains-powered clocks have adjusted fine, thanks to DCF77. The clocks in my sat receivers have automatically adjusted to the time broadcasted via satellite. No problem.

    Computers, including firewall? All fine. A nice reboot mail from the server, all subsystems happy, VMs have stopped. Push a few start buttons, and they all come back. No problems. Perhaps I should automate the VM startup, too. But then again, the uptime of the server is usually in the range of 100 to 300 days, interrupted only by hardware upgrades or mans with spades. I don't really have to automate, but I could. Maybe someday. RTCs on PC systems have a battery backup. I think the firewall does not, but as all my systems, it adjusts via NTP thanks to pool.ntp.org.


    It seems that today is the official bad user interface day:

    At work, a client wants another prompt for the user interface of the product we've developed. Currently, to switch from simple mode to advanced mode, you have to press the "settings" button, then either enter a code or at least confirm that you are qualified for advanced mode, and then you have to press yet another button to stay in advanced mode. Now, when you press the "settings" button, you first shall have to confirm that you really wanted to press the "settings" button. Aaaaaah!

    OK, to be fair, at the same time, the last button press to stay in advance mode should no longer be required. But still: How often should a user confirm a completely harmless switch from simple to advanced mode? Should the product prompt for social security number of the user and his manager and five fingerprints from each of the two before switching modes?

    And I won't write any more about Qt, QML and the state of its documentation than PITA. Or perhaps just a few sentences more. When do people learn that documentation is the most important part of software? Code examples are good, they can avoid a lot of prose. But examples are stupid if they show only the documented detail, stripped from all required surroundings. How do I use a complex object that requires a lot of setup? Like this:

    simpleObject { id: "foo" magicStuff: complexObject { id: "bar" ... //<-- literally! All setup omitted from the exa +mple. } }

    And not a line more. All setup omitted, you are expected to guess what you may need to set up, and how. You have to dig through the inheritance, and hope for some clues in an unrelated part of the documentation. Or you have to search for the source code. Trace the source code. Find out what hapens in the complex object, and what it expects to have been set up. "If it was easy to use our code, you wouldn't get paid so much!"

    Documentation is the user interface to 3rd party code, and in case of Qt/QML, it sucks. Yes, there is worse documentation. But I spend half a day digging through heaps of this crap and did not get one step further.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Code plagiarism and clueless newbs
3 direct replies — Read more / Contribute
by 1nickt
on May 30, 2017 at 08:38

    I imagine many of us have been irritated by the increase in lame questions from Clueless Newbs attempting to get their homework done for free. Well, according to the New York Times, there's a plagiarism plague:

    College students have flooded into computer science courses across the country, recognizing them as an entree to coveted jobs at companies like Facebook and Google, not to mention the big prize: a start-up worth millions.

    The exploding interest in these courses, though, has coincided with an undesirable side effect: a spate of high-tech collegiate plagiarism. Students have been caught borrowing computer code from their friends or cribbing it from the internet.

    ( See "As Computer Coding Classes Swell, So Does Plagiarism", NYT 2017-05-29 )

    So the next time you are about to jump in and answer a Clueless Newb's question because it will show off your skillz, consider choosing the admittedly less satisfying option and point them instead to beginners' doc. You will be better serving not only the questioner, but also Truth and Justice.


    The way forward always starts with a minimal test.
How easy it is to make mistakes
5 direct replies — Read more / Contribute
by tobyink
on May 23, 2017 at 06:54

    So, I don't use CGI a lot much these days. But I recently wrote a little joke module and decided to make a little HTML form interface for it. Plack would be a sensible way of doing the interface, but this was just a silly little thing and I was feeling lazy, so I coded it up using CGI instead. I'd used Moo rather than Moose so speed shouldn't have been an issue.

    I uploaded it to the server and visited the page and it just showed me my Perl source code. Hmmm…

    Create .htacccess and add the following lines:

    Options +ExecCGI AddHandler cgi-script .cgi .pl

    Visit the page again… still showing the source code. Hmmm…

    Scratch head for five minutes. Open up httpd.conf, add:

    <Directory /path/to/my/vhost/> AllowOverride all </Directory>

    Visit the page again… still showing the source code. Hmmm…

    SSH into the server and run ./myscript.cgi from the command line.

    "uniq" is not exported by the List::Util module

    Okay, I must have an old version of it. Upgrade.

    Visit the page again… still showing the source code. Hmmm…

    Stop using List::Util entirely.

    sub uniq { my %seen; grep !$seen{$_}++, @_; }

    Visit the page again… still showing the source code. Hmmm…

    Scratch head for ten minutes. Rename to ./myscript.pl.

    Visit the page again… still showing the source code. Hmmm…

    Create the following file and mark it as executable:

    #!/bin/sh echo "Content-Type: text/plain"; echo ""; echo "Hello world";

    Visit my new page… also showing the source code. Hmmm…

    Scratch head some more.

    Consider buying anti-headlice shampoo.

    Finally… FINALLY… after about TWO HOURS I figure out the problem! It was…

Perl as interactive Shell?
7 direct replies — Read more / Contribute
by LanX
on May 12, 2017 at 10:51
    Hi

    what are the fundamental obstacles hindering Perl to be used instead of Bash and or PowerShell?

    For instance I'm aware of easy piping with | and redirection >

    but this could be handled by reversing the direction and aliasing some builtin commands to Perl subs

    for instance ls | grep '.txt'|less could easily be less grep {/.txt/} ls

    with less and ls implemented as subs (see also Shell )

    What else?

    Insights?

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

    °) see also Shell and aliases in perldebug like | for paging

RFC: Test::Contract - extensible object-oriented runtime check series
1 direct reply — Read more / Contribute
by Dallaylaen
on May 07, 2017 at 10:17

    Hello dear esteemed monks,

    More than once I felt an urge to insert a set of Test::More's checks into my application code, for instance when loading a plug-in or validating a complex piece of data. However, Test::More/Test::Builder is best suited to only run inside test scripts.

    So I came up with a module to fill the gap. And I'm going to release it to CPAN soon, unless some huge problem is detected.

    The idea is as follows:

    • A contract is an object representing a series of checks/assertions. It has some control methods as well as the checks themselves. A counterpart method exists for every of Test::More's checks.
    • The most basic check is refute($condition, $message) which may be viewed as an inverted ok(). It is assumed that a passing test does not need attention, while a failing one begs for an explanation.
    • New checks may be added quite easily, appearing as both contract's methods and individual functions that run just fine under Test::More.
    • And these checks can be tested (who shaves the barber?) fairly easily using the contract_is ($contract, "11000101") assertion.
    • Prototyped exception-proof contract { BLOCK; } sugar exists to reduce the bolierplate. Such blocks may be nested.

    What usage I can see this far:

    • loading user-supplied code;
    • validating complex pieces of data;
    • checking that multiple implementations (XS vs PP, different backends etc) behave exactly the same;
    • maybe some use exists for development using traits/mixins (aka Moose::Role);
    • maybe some assertion modules may be armed with a refute($what_went_wrong, $why_we_care) call.

    Some details (this is basically a copy-and-paste of the project's README):

    CONCLUSION

    As stated above, this module is going to be released to CPAN, but maybe I'm missing something very obvious here...

    My previous submission on the topic: RFC: Test::Refute - extensible unified assertion & testing tool.

    The project link again: https://github.com/dallaylaen/perl-test-contract.

    Thank you, and hope you enjoyed the reading!

Confession of a hard headed Monk
2 direct replies — Read more / Contribute
by Lady_Aleena
on May 05, 2017 at 23:43

    Over the last few days, I've been doing a project that is forcing me take a new harder look at everything I've written: code and markup. One of the items which came up in my audit was a little subroutine which takes a number (usually scalar(@list)) and returns how many columns the list would be in according to exponential calculations. The default behavior of this subroutine is to return a word number not an integer. When I looked at it again, a voice in the back of my head told me the subroutine should return the integer by default because integers are more useful. I also had the sinking feeling someone here probably pointed that out to me, and I ignored it. I wanted what I wanted, and no one was going to make me change my mind at the time. I had to change my own mind and pay the price for it later.

    So, this is my confession. I am a doofus. I am hard headed and obstinate when it comes to attaining my short term goals. I crawled into my shell to avoid any good advice about coding for the future.

    So here is my old sub...

    use Lingua::EN::Inflect qw(NUMWORDS); sub get_columns { my ($max_cols, $amount, $number) = @_; if ($amount <= $max_cols ** 2) { for my $num (1..$max_cols) { if ($amount >= $num ** 2 && $amount < ($num + 1) ** 2) { return $number && $number =~ /^[yt1]/ ? $num : NUMWORDS($num); } } } else { return $number && $number =~ /^[yt1]/ ? $max_cols : NUMWORDS($max_ +cols); } }

    And the new more useful sub...

    use Lingua::EN::Inflect qw(NUMWORDS); sub get_columns { my ($max_cols, $amount, $word) = @_; if ($amount <= $max_cols ** 2) { for my $num (1..$max_cols) { if ($amount >= $num ** 2 && $amount < ($num + 1) ** 2) { return $word && $word =~ /^[yt1]/ ? NUMWORDS($num) : $num; ############################################# Delete to + get rid of Lingua::EN::Inflect } } } else { return $word && $word =~ /^[yt1]/ ? $NUMWORDS($max_cols) : $max_co +ls; ################################################### Delete +to get rid of Lingua::EN::Inflect } }

    I feel bad for only now realizing returning a integer by default would be more useful than returning a number word. I think I spoke aloud when I called myself a doofus for returning a number word by default.

    I've been doing a lot of rethinks lately. Some of my "utility" scripts seem useless in a broader sense.

    The great advice I got from Monks long ago is finally settling into my head. I hope I am better with future advice, but that is to be seen.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena
Assigning to Hash Values (updated)
No replies — Read more | Post response
by haukex
on Apr 28, 2017 at 12:49

    The thread "Randomly reassign hash keys" got me thinking about this one. The values doc says:

    Note that the values are not copied, which means modifying them will modify the contents of the hash.

    This means that $_++ for values %hash; will modify the original hash values, and the following (based on this AM post) will assign to the values of the hash:

    sub { @_[0..$#_] = qw/r s t/ }->(values %hash);

    The above work because both the foreach loop variable and the elements of @_ are aliases to the original scalars. The slice in the second example is necessary, since @_ = ... would clobber the array and remove the aliasing, instead of assigning to its elements.

    However, values itself is not lvalue, meaning that values(%hash) = qw/a b c/; won't work. Neither will (values(%hash))[0] = 'a';.

    Here's my "invention", which I present as a curiosity rather than a suggested solution. It makes use of Lvalue subroutines and Prototypes. The parens on the left are necessary for the sub to be called in list context.

    sub lvalues (\%) : lvalue { values %{$_[0]} } (lvalues %hash) = qw/i j k/; # works!

    Since the order of the values returned by values is random, this probably isn't particularly useful other than in the context of the thread I mentioned above:

    (lvalues %hash) = shuffle values %hash;

    Updates 1&2: However, note that repeated calls to (lvalues %hash) = values %hash; will only "randomize" the values once, and on older Perls the order won't be very "random" at all apparently not randomize at all, I would guess because the order of the returned values is not randomized between the calls to values. Some interesting reading on the topic: Re^2: setting PERL_PERTURB_KEYS & PERL_HASH_SEED in a perl file and Re^2: Curious: are anon-hashes in random order?

    Minor updates for clarification.

Big thank you to the Perl community.
4 direct replies — Read more / Contribute
by Anonymous Monk
on Apr 24, 2017 at 06:21

    Revered Monks and dwellers of this venerated place,

    I've been here for approximately two months now and I have no words to express my gratitude. The level of information shared here is amazing. The knowledge of the monks just blows my mind. Answers given here are of very high quality and I've come to realize that PerlMonks is the best place to learn Perl

    Just wanted to take a moment to extend a heartfelt "Thank You" to all you knowledgeable and helpful folks here. Spending a few minutes here is far more enriching and fulfilling. The suggestions and advice given by you Monks has literally shaved off hours of time. I started with Perl due to its practicality and immediacy with which it naturally lends itself to real life problem solving, but now, I have started falling in love with this amazing language, all thanks to you folks.

    This language deserves so much more attention and respect than it gets. All this talk of "Perl is Dead" now simply makes me wonder what the hell is going wrong with folks. This language will never die, because 1) its a pragmatic, practical and amazing language and 2)PerlMonks.

parallel programming and MCE - hubris and the frame
2 direct replies — Read more / Contribute
by Discipulus
on Apr 10, 2017 at 07:00

    Introduction

    Discipulus will never be a master: he likes too many things to become a master in one of them. He likes Perl. Here at the monastery he looks at tchnologies shown by monks, often like Linus watching russian names reading Dostoyevsky..

    He looks at Perl parallel programming with a big interest: he suspects parallel programming will be one of major battlefield for next generations of programmers. He'd like these programmer to be Perl ones.

    He has his cell carpeted of good examples of parallel programming. He also knows it is important to choose right masters to learn and follows with a big attention all parallel programming examples by, among others, BrowserUk and zentara.

    Then it happened that marioroy joined the monastery: his work, MCE - Many-Core Engine for Perl hit Discipulus's curiosity strongly: perhaps with such tool even he can, simply and safely produce some decent parrallel Perl program? Infact he's a bit lazy and many working examples are difficult to adapt without falling into horrible pitfalls.

    So Discipulus, taken his curage in his hands, has gone knocking at BrowserUk's and zentara's doors to ask their opinion...

    (please note that I confuse parallel programming terminology, still. So when I say multithread you can read parallel: the dialogue is interesting beside my grossolane errors.

    The Dialogue

    Discipulus:I follow your posts about parallel multithreading programming since ever and I follow them as a pupil (discipulus in latin..) follow his masters. I say this withut any flattery intention. As you stated somewhere (iirc) multithreading in Perl is difficult to realize but is possible to do as you shown many many times.
    What i will be glad to hear from you is an opinion about Perl MCE by marioroy available at http://search.cpan.org/~marioroy/MCE-1.827/ and visible in many posts by marioroy here in the monastery.

    BrowserUk: I mostly don't recommend MCE, (though I have suggested people consider it a few times), simply because I don't us it personally.

    zentara: I havn't the time to test MCE out. Besides I would rather do it manually, since I have total control of the code, as in Reusable threads demo.

    Discipulus:Now I know you do not need such a thing like MCE to produce good multithread perl programs. but what about us? If i have the need or the curiousity to start write a threaded application i will follow your footsteps: i go to library, i search one of miles of your working complete examples, the closest to my need and i will expand it as my needs. But MCE seems a safe a clean alternative to have a multithread program without writing it from scratch.

    zentara:Another thing, Don't confuse forks and threads. MCE is based on forks, from what I can gather, not threads. It gets more confusing because on MS Windows, all processes are threads, not forks.

    BrowserUk:I don't use it personally be a) for the most part I don't need it; b) I have a very strong aversion to frameworks. But please note, I saying that I do not generally actively recommend MCE to people, I am not saying that I recommend against it.

    Discipulus:MCE is an alternative if you accept the overhead of using a framework: but this is very common in programming: was possible to write webpages without CGI some years ago, writing a server too but CGI was a cheap overhead in front of many pitfalls possible doing all by hand. The same for DBI..
    Is MCE something valuable in such perpsective? Is MCE a safer way to do parallel programming in perl, if you accept the minimal overhed and his learning curve?
    Fast is fast, i rerun many bechmarks proposed at PM by marioroy and i can confirm. But is solid rock? this is behaind my capabilities to tell. It introduce other pitfalls?
    I suspect MCE was highly undervaluated by the perl community and i think multithread is a key field for programmers of next generations: i'd like to see perl kicking competitors in the future.

    BrowserUk:If you have an application for multi-tasking that MCE has a widget for, and especially if you can attract the attentions of MarioRoy to construct and refine some examples for your purpose (and perhaps tweak it internally to address any shortcomings your application throws up) then you could do a lot worse. From a cursory inspection, the code seems well designed, constructed and documented, and the author seems to have the time and energy to support you.
    Beyond that I really don't have a lot to add.

    zentara:As far as the threads controversy goes, these are my thoughts.

    0. Threads tend to blow up unexpectedly, so don't use them for anything where you demand certainty and stability. Also many modules are not thread-safe,i.e. Tk

    1. Only use threads if you need to share data in realtime between threads in an easy manner, with threads::shared. Otherwise forking a new process is more efficient because you do not have to copy the parent thread's code into the spawned thread, and the process totally frees it's memory when finished.

    2. If you are going to use workers, the MCE module looks alright, although it reminds me of Parallel Fork Manager. If I was to chose the one foolproof way of doing the task of many workers sharing data in realtime, I would use Parallel::Fork::Manager along with SYSV Shared Memory segments. (zentara unfold a perchment with a wonderful example.. )

    Discipulus: the answer you gave me was somehow expected and somehow unwanted: I know you have no need for such framework because you can write down the right way a multithread perl program using perl and it's basic tools.
    But i've learn to not ask questions if i'm not prepared to receive back every answer :=)
    I also understand your avversion to frameworks in general: why be constrained into a frame when my puissance can spread out free and untouched? this is a declination of the hubrys in it's positive, perlish sense.
    But hubrys without solid rock foundations is foolishness and is where frameworks are valid options: I pay some of my freedom to the frame but i'm almost sure i'm not shooting on my own feets.
    In this perspective i consider MCE a true gem: can MCE open the way to multithread Perl programming to many,many more peoples? I think this is it's virtue and this merit i suspect was underestimated.
    I suspect and hope MCE can help perl programmers to afford such complex thing as multithread programming is.
    If so we must spend some energy to push MCE forward and suggesting it as a way to start, safely, to do multithreaded perl programs.

    (saying the above I not mean MCE is the only way to do it right with Perl parallel programming. As always TIMTOWTDT and any author can choose among many.)

    Note that I've ask both monks the permission to reproduce parts of our mails: if i've put something in wrong order, if something sounds not to be the real opinion of such monks it is my complete fault and i'll correct

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
How to lay out POD documentation for multi-faceted apps
1 direct reply — Read more / Contribute
by stevieb
on Apr 02, 2017 at 18:31

    Take Test::BrewBuild for instance.

    There are three included binaries (well, scripts) that accompany the various modules that make up the distribution, but it may not be clear to a user which one to read first.

    When you search CPAN for the distribution, it automatically loads the POD file for the main API module, in which I redirect users to read another doc if they are not looking to use the API directly.

    What type of approaches do I have here. Should I hijack the main module's POD with the main binary's POD, and redirect to the other ones from there?

    What have others done in these situations, and as an end-user, what would you like to be presented with on a first glance after clicking on a search result?

    update: note that the first entry in the Changes file in the link above has been rectified, as I updated berrybrew late last week. Updating berrybrew rids one of the win10 issue. /update

My Perl-ish Neo-Gavinist Manifesto
3 direct replies — Read more / Contribute
by InfiniteSilence
on Apr 01, 2017 at 16:04

    A few people sent me messages via the Message Inbox that I could see under the 'Chatterbox' heading. More than once I admit to not using this messaging feature (even when I saw messages in there for me) because I sort of hate looking at that screen.

    Clicking on it shows what I can best describe as one of the most confounding utilities on this or any other website I frequent. And it is the reason for this meditation.

    When I normally look upon it I am immediately confronted with what appear to be checkboxes selected for me. This is not helpful. It says, 'Showing messages ' and then appears a 'From' and a 'To' checkbox immediately following. It is not obvious if I am supposed to select something else and under what circumstances I would have to do so (this feels particularly pressing when there are no messages for some reason). When I experiment and click on the 'From' checkbox it does not automatically de-select the 'To' one. After some thinking about it I realize that it would show both messages from and to me. It would have been far easier to have something that allowed me to see 'All Messages' even if offering such an option would be redundant.

    The next line has yet another checkbox next to 'not' in parenthesis with yet more options: Inbox, Archive, Deleted, all with parenthesis but some with what appear to be counts. There is yet another line that reads, 'constrain by content' which is apparently some way of saying, 'filter by,' followed by the ability to additionally filter by a user box which is not even a drop down list of user identities (minimally it could contain the users who have sent me something). This text is all in the English language which means it is to be read from left to right. When my eyes dart to the beginning of a line I should never have to guess what is going to be on that line. Think about it -- when reading a book every line you read tells you, using context clues, what you are about to read next. Webpages are no different.

    Now, I know what a few of you are thinking. The Perlmonks site doesn't use JavaScript. But that is not what I am saying. What I am saying is that this form could be improved without JavaScript. It mashes things together and makes no attempt to differentiate; it presents the user with form boxes pre-filled in; the word 'constrain' is used when filter would be more clear; the buttons appear at random; some form fields do not even have labels on them; and there is even a radio option for "Don't Send At All" selected by default which probably could be done away with entirely.

    For years I would develop forms just like this one. I would say that if the user did not understand my interface it was because they were too stupid to understand it. I was wrong.

    Gavin in Gavin-ish

    The term 'Gavin-ish' does not exist. I made it up. It is a term derived from the name Gavin, for Andy Gavin, co-creator of and developer of the successful Crash Bandicoot and Jax and Daxter video games for the old Sony Playstation 2. I do not think Andy is a Perl hacker at all. One of his posts called scripting languages 'toy' languages. Andy was a Lisp enthusiast who, in his own words, forced his game developers to use his Lisp engine to develop games. His website has an entire series on this. You might be wondering why in the world I would promote such a person here on this forum. Because I think some of the things he said about producing games are relevant for developing software as a whole. It certainly changed my outlook quite a bit. Here is the excerpt from his writing that I found most compelling:

    "...This is because games are all about gameplay, and good gameplay only comes from constant experimentation with and extensive reworking of the code that controls the game's objects."

    Take away the word 'game' and replace it with 'UI experience.'

    For years I avoided learning anything but very basic HTML/CSS/JavaScript because part of me resented the UI as a whole. I normally worked on the command line or in Emacs. I had to do a lot of figuring things out -- why should my end users not have to do the same? Well, if there are any benefits whatsoever to getting older one of them must be growing tired of wasted effort. Walking on proverbial eggshells every time you work with an interface is a sign that it is poorly designed. The whole point of a UI is to help the user avoid making mistakes. Organization of like things, spacing, grouping, color, and other tools all help make the user aware of what is to be done. None of those things require JavaScript.

    Manfest-o

    So in my quest to be a better coder I've started subscribing to this Neo-Gavin-ist philosphy (Neo because Andy is a Lisp and perhaps now a Ruby coder and not a Perl one). I now believe that UI design is about clarity and exhibiting both thoughtfulness and an assurance that a user's actions will result in proper/predictable outcomes.

    Consideration for things like spacing and grouping are not optional and must be used judiciously; size, color, emphasis, and even font choices are all relevant. Useless things should be removed (for instance, empty parenthesis...?) to enhance clarity. Rework of this type and kind Andy used to make some truly revolutionary games despite seemingly fantastic obstacles (memory constraints, unhelpful equipment vendor, etc.) and the same should be the goal for any UI.

    Granted, most of us are not making games. True, this type of rework takes time unless you have tools that do a lot of the heavy lifting for you. But doing nothing is just that and has a predictable and undesirable result. We can do better.

    Join my movement. Agree that UIs must subscribe to the philosophy of constant experimentation and rework for improvement irrespective of whether the underlying language is Perl or some other. Then develop better UIs, toolkits in Perl to make it easier to crank them out, and share your comments on this here.

    Celebrate Intellectual Diversity

Improve pipe open?
1 direct reply — Read more / Contribute
by afoken
on Apr 01, 2017 at 11:17

    A small meditation started by Ssh and qx


    Intro

    Let's face it: qx is evil, as soon as you want to reliably pass arguments to a program. And it's not necessarily perl's fault. Blame the default shell. Luckily, perl has multi-argument pipe open since 5.8.0:

    open(my $pipe,'-|','/usr/local/bin/foo','bar','baz','1&2>3') or die "C +an't start foo: $!"; my @output=<$pipe>; close $pipe or die "Broken pipe: $!";

    It's so easy. Granted, it takes two more lines than qx, but we got rid of the default shell. And that two extra lines could easily be wrapped in a function:

    my @output=safe_qx('/usr/local/bin/foo','bar','baz','1&2>3');

    But, of course, that would be too easy to be true. Why can't we have nice things?

    Three-argument pipe open gets the nasty default shell back into play:

    > perl -E 'open my $pipe,"-|","pstree --ascii --arguments --long $$ 1> +&2" or die $!;' perl -E open my $pipe,"-|","pstree --ascii --arguments --long $$ 1>&2" + or die $!; `-sh -c pstree --ascii --arguments --long 22176 1>&2 `-pstree --ascii --arguments --long 22176 >

    Now what? We could resort to my favorite part of perlipc, "Safe pipe opens". 15 to 28 lines of code just to safely start an external program, and all of that only because perl wants to be clever instead of being safe.


    How to fix it

    Let's make multi-argument pipe open clever.

    system and exec have the indirect-object-as-executable-name hack to prevent the default shell mess. Applying that to open might be possible, but still looks quite hacky:

    open $list[0] my $pipe,'-|',@list or die "Can't open pipe: $!";

    No! Just no!

    So, do we really need to specify the executable twice? We usually don't want to lie to the target program about it's name. It might be useful to make a shell think that it's a login shell, but then again, that can also be done by passing an extra argument. No, we don't want to lie to our child process. If backwards compatibility was not a problem, we could simply disable the shell logic for any pipe open with more than two arguments. But for backwards compatibility, we can't do that. We need is a flag to disable the shell logic.

    My first idea was to just double the dash in the MODE argument:

    ModeActionUsage of default shell
    -|Read from child's STDOUTenabled for three argument open,
    disabled for more than three arguments passed to open
    (legacy mode)
    |-Write to child's STDIN
    --|Read from child's STDOUTdisabled
    |--Write to child's STDIN

    But we still can do better: A single bit is sufficient for a flag. + is already used in MODE, but not in combination with the pipe symbol. So let's use + instead of - to disable the default shell:

    ModeActionUsage of default shell
    -|Read from child's STDOUTenabled for three argument open,
    disabled for more than three arguments passed to open
    (legacy mode)
    |-Write to child's STDIN
    +|Read from child's STDOUTdisabled
    |+Write to child's STDIN

    Yes, I'm aware that the difference between "+" and "-" in ASCII is two bits.


    Update:

    For a better mnemonic (ls -f uses "*" to indicate an executable file), we could use "*" instead of "-" to disable the default shell and specify the executable file in the third argument:

    ModeActionUsage of default shell
    -|Read from child's STDOUTenabled for three argument open,
    disabled for more than three arguments passed to open
    (legacy mode)
    |-Write to child's STDIN
    *|Read from child's STDOUTdisabled
    |*Write to child's STDIN

    Thanks to huck and hippo for finding two missing quotes.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

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.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (7)
    As of 2017-07-20 15:34 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?
      I came, I saw, I ...
























      Results (305 votes). Check out past polls.