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
Buying a round for your friends
3 direct replies — Read more / Contribute
by ribasushi
on Feb 11, 2014 at 05:57
    Since I want my braindump from an hour ago to reach as far within the community as possible, I figured I will repost it here as well (given the core crowd of perlmonks does not really read such things). Note - *THIS IS NOT A PERSONAL FUNDING-DRIVE*. This is about figuring out how hopelessly stuck-up as humans we are collectively, in our corner of the proramming universe.

    Original text taken from here


    Given our community is a little... let's say cautious I feel the need to open with a disclaimer. I am in no way affiliated with Gittip, in the past, present and the foreseeable future. In fact I looked at their bugtracker for the first time this morning and am appalled that a site in production for 2 years can have so many outstanding basic conceptual issues.

    In any case this entry is about the underlying idea, so if you can manage to not get distracted by a shoddy implementation - read on (NSFW language as always :)

    It started yesterday when I looked here and asked Y U NO WANT BEER?!. While twitter did not manage to spark a conversation, IRC did (and boy, was that some conversation :) The chatter quickly evolved, climaxed and (painfully predictably) broke away for good. And also predictably it boiled down to a split into several distinct camps

    • Some genuinely believe it is not worth bothering with chump change, since "we lack the hipsters in our community" and without them any kind of funding drive will not have an impact
    • Some feel uncomfortable seeing their avatar among the current highest donors/receivers (after you look at the current top receivers you either instantly understand what the problem is, or you don't - there is no easy way to explain it)
    • Some genuinely believe they rather get patches as opposed to chump change

    I say FUCK THAT. And instead of explaining how and why you should do something you are not currently doing, I will instead explain why I am currently pledging $50 (possibly more in the future) per week, and distribute them among folks of my choosing.

    First of all: it is easy for me to do so (and yes, this part is important). Connect my twitter / github / bitbucket / whathaveyou account, connect a credit card: done.

    With that out of the way - let's take a simple example - Pumpkin Perl and the current Pumpkin (or Pumpking depends on what you like). At the time of writing Perl is #3 on the metacpan leaderboard, with 168 "backers". If these 168 decide to give our pumpkin $5/week each - that's roughly $3500 per month for him right there.

    THIS JUST IN, BREAKING NEWS: chump-change adds up.

    Now, am I confident he will use the cash to further my interests (that is keep Pumpkin Perl sane) in the foreseeable future? Yes, I am pretty confident, given track record and all that. But the more important question is - does it matter if he actually does? Not in the slightest. I am not sharing some chump-change with expectations of extra commitments and future results.

    I am virtually buying my fellow colleagues a beer for EXCELLENT OUTSTANDING WORK *ALREADY COMPLETED*

    What I particularly like about Gittip is that it does not require any extra effort to keep doing what I decided to do. Yes, I could go broke by oversharing my extensive wealth, but so could anyone with a non-dumb phone and an appetite for extra game content. At least I'd know there is an actual person (that I might even like) on the other end ;)

    Will I feel cheated and sad if none of this goes anywhere? If the virtual beers do not motivate anyone, and if the Perl-portion of the Gittip community remains unseen and insignificant? Not really. $50 is the cost of a decent-but-not-spectacular dinner for two where I live. If this is cash that ended up being thrown away - shrug, it could have been a shitty dinner anyhow. And if I *do* feel bad about it - this means I am a petty shithead and I deserve to feel like that anyway :)

    So to recap:

    • It is easy
    • It doesn't cost me much of anything
    • It can make a real tangible difference on the other end
    • It sends a clear continuous "Thank you!" message
    • Makes Perl as a whole look good, without compromise of my values
    • No hipsters required (though of course welcome)

    What's not to like?

    Cheers

Experiences with deployment solutions
4 direct replies — Read more / Contribute
by McA
on Feb 11, 2014 at 01:34

    Hi all,

    this is not really a Perl related question but I would like to address the Perl community with it.

    There is rex as a Perl based deployment tool which seems interesting as all is implemented in Perl and someone like me could get the feeling to be able to put hands on when needed. On the other hand there are well known and famous tool sets like Chef and Puppet written in a language not known to me.

    So, I would like to hear whether some monks have experience with these distribution tools and whether using them seems worth it (I know, a really vague question).

    Thank you in advance.

    Best regards
    McA

Parameter Pattern Matching in Perl
No replies — Read more | Post response
by withering
on Feb 10, 2014 at 08:03

    Hello fellow monks.

    A few days ago I was working on type inference in both simply-typed lambda calculus and Hindley-Milner System. While I was trying to use hashtables to implement branches for getting rid of annoying 'if's, I realized that there's no quick ways to emulate pattern matching in ML or Haskell -- It is a fact that we could not easily do that due to the dynamic nature of Perl's type system. However, I managed to emulate some of the features I used in Erlang, ML, or perhaps Haskell and made a small CPAN module HOI::Match (where HOI means Higher-Order Imperative):

    HOI::Match

    With the module, I am able to write such a sum function:

    sub sum { HOI::Match::pmatch( "h :: r" => sub { my %args = @_; $args{h} + sum($args{r}) }, "nil" => sub { 0 } )->(@_) }

    (Note that the arguments in @_ may be FETCH several times so it is dangerous to rely on side effects of FETCH on arguments.)

    Any suggestion or criticism is welcomed. I am looking forward for your replies.

Bad conscience
19 direct replies — Read more / Contribute
by baxy77bax
on Feb 10, 2014 at 03:52
    Hi,

    Today a have a moral issue to share with you. Let say that you are coming from a country that has 25% unemployment rate (even higher for young people) and though government is saying programmers are easily employable (which is true) they are highly underpaid. Let say that you are in your late 40's and you work for this company where you are the only programmer around. Your boss knows it and though he values your work the free market allows his competitors to higher young highly motivated people that are willing to work for half what you make. You know that most of the base work is done and maintenance is the only thing you lately do. That does not require a lot of experience nor deeper understanding (my personal view) of how stuff works but just requires of your to follow latest trends. Let say that lately you noticed that company code (that you wrote) is being downloaded by your boss frequently. You try to figure out why but don't get a strait answer. What are you to assume especially if the company is not that big and you know cuts needs to be made.
    My question to you guys is: Would you be willing to do a dishonest thing in order to keep your job, like for instance, write unreadable code? I know people that do that and now they are using it as a bargaining leverage for negotiating raise or keeping the job. Also my question to you is . How often this happens? How often people write hard to maintain code just to keep others away? Is it something that is done frequently (in your experience) or not?
    Of course big companies do not allow you to do something like that but small ones do. What is your opinion on the subject.

    thnx

    baxy

Practical Proc::Daemon example
2 direct replies — Read more / Contribute
by jellisii2
on Feb 04, 2014 at 12:51

    I had a lot of trouble getting started with Proc::Daemon because some things weren't completely obvious to me. Here's a practical example that I wrote for practice.

'state' variables and unit testing
3 direct replies — Read more / Contribute
by vsespb
on Feb 01, 2014 at 12:43
    There is common pattern to cache result of heavy calculations.
    use strict; use warnings; use v5.10; our $_cached; sub somefunc { $_cached //= do { say "Heavy calculations"; 42+($ARGV[0]||0); }; } say somefunc(); say somefunc(); __END__ Heavy calculations 42 42
    since 5.10 there is "state" statement, making this pattern even more easy.
    use strict; use warnings; use v5.10; sub somefunc { state $var = do { say "Heavy calculations"; 42+($ARGV[0]||0); }; } say somefunc(); say somefunc(); __END__ Heavy calculations 42 42

    However I see one problem here: unit testing.

    With first example it's easy to test somefunc with several possible inputs.

    { local $_cached = undef; local @ARGV = (3); say somefunc(); } { local $_cached = undef; local @ARGV = (5); say somefunc(); }

    and with "state" it looks impossible? Once you call somefunc() from your test, it's result cached forever.

    Looks like a missing important feature, which can encourage people not using unit testing? What do you think?

Low-threshold function in Text::CSV_XS
7 direct replies — Read more / Contribute
by Tux
on Jan 24, 2014 at 12:09

    I had quite a long discussion with Lady_Aleena in the chatterbox, as I wanted to fully understand her wishes. She had a number of complaints about Text::CSV (and Text::CSV_XS) being to complicated for simple end-user tasks.

    We - as module authors - should always take remarks like that serious, even if the end user might not exactly be the target audience we had in mind when writing functionality.

    <cbstream> [Lady_Aleena] My problem is that modules like Text::CSV_XS +doesn't open the files for me too. <cbstream> [Lady_Aleena] Tux, I might use Text::CSV if it becomes a on +e liner.

    I've heard remarks like that before, but so far always ignored them, as the function/method to do so is so simple that including something like that in the module itself feels like bloat.

    Now that I understand what Lady_Aleena actually wants with her data - to directly create a hash of hashes from a CSV-like file, I tried to come up with a far more generic function. Having rfc7111 fragments now, that only makes more sense :)

    After a few iterations, I came up with a function that support all basic needs, yet still allows a lot of flexibility. Without going into the implementation, what I currently have done supports:

    my $AoA = csv2list (file => "file.csv"); my $AoA = csv2list (data => $io, sep_char => "|"); my $AoA = csv2list (file => "file.txt", sep_char => "|", fragment => " +col=3;5-6;0-*"); my $AoH = csv2list (file => "file.csv", headers => "auto"); my $AoH = csv2list (data => $io, sep_char => "|", headers=> [ "Name", "Hobby", "Age" ]);

    When I apply that to the code on Lady_Aleena's scratchpad, the difference would be somethink like

    la.txt: Jan|Birdwatching|7 LA|coding|25 Tux|skiing|52 code: my @gdr = qw( Name Hobby Age ); my %la = lady_aleena (file => "la.txt", headings => \@hdr); my $aoh = csv2list (file => "la.txt", sep_char => "|", headers => \@hd +r); my %hoh = map { $_->{Name} => $_ } @{$aoh}; result for both: { Jan => { Age => 7, Hobby => 'Birdwatching', Name => 'Jan' }, LA => { Age => 25, Hobby => 'coding', Name => 'LA' }, Tux => { Age => 52, Hobby => 'skiing', Name => 'Tux' } }

    I'll let this sink in a bit. Obviously a function like this has a lot of potential, but should it be auto-exported? And is it flexible enough as it is like this?


    Enjoy, Have FUN! H.Merijn
A Melancholy Monkday
10 direct replies — Read more / Contribute
by starX
on Jan 19, 2014 at 00:46

    The XP Nodelet informs me that I've been a member of the Monastery 10 years as of today, but it feels quite melancholy in the wake of the most recent Tiobe Index. Perl was ranked as the 9th most popular language in January 2013, but has fallen to 13th one year later.

    A look at their long term history reveals that perl has fallen from an average ranking of 4 when I first entered the Monastery, to an average of tenth now, and my own experience has confirmed this: most of the work I do in perl these days is prototyping for fuller development in other languages.

    What saddens me most is that I have learned a lot about software development from perl as a language, and as a community, and now it's beginning to feel that this world has increasingly little relevance for those who live outside of it.

Jumping ship from C++
8 direct replies — Read more / Contribute
by morelenmir
on Jan 08, 2014 at 00:44

    I taught myself C++ and have used it off and on as the interest took me - as an amateur mind you, no damned professionalism here - for the last 18 years. And then I decided perl was a good idea!

    I wondered how many of you other chaps had made the same change over the years and what pushed you? For me I can identify the three primary factors - (lack of) strings, (the inherent complexities of) templates and the proliferation of commercial sub-dialects like MFC or (absolutely worst of all) .NET.

A basic 'worker' threading example.
3 direct replies — Read more / Contribute
by Preceptor
on Dec 29, 2013 at 07:15

    This post is aimed at the people who have heard of Perl threading, and think it intriguing - but haven't really gotten to grips with how it's done. I'm going to put together a ... template, if you like, for a very basic style of threading.

    Parallel code is somewhat hazardous for the unwary - because you're 'splitting' your program, and making different parts run at different speeds, you can end up with some incredibly frustrating and hard to track bugs. Every thread is a race condition waiting to happen. So all the bad habits you've picked up when coding in Perl, may well come and bite you if you 'thread it'.

    The simplest thing to thread is what's known as an 'Embarassingly Parallel' problem. It's a type of problem where there are multiple tasks, but no dependencies, communication or synchronisation needed.

    When 'doing' parallel code, you start to think in terms of scalability and efficiency - every thread start has an overhead. So does every communication between threads. However the most 'expensive' task is synchronising all your threads - they all have to wait until the slowest thread 'catches up'.

    Thankfully - an 'embarassingly parallel' problem has none of these things.

    An example I might use is pinging 1000 servers. You want to ping each of them, but you don't need to do so in any particular order. However, if a server is offline, then a 'ping' will wait for a timeout, making the process a lot slower.

    The only thing you have to worry about is if you ping them 'all at once' you might end up sending a lot of data across the network.

    This is a near perfect example of a type of problem I encounter regularly, and so I give it as example code.

    Perl actually has quite a good way of 'spotting' embarassingly parallel stuff - the 'foreach' loop is often a good sign.

    If you're doing the same thing on every item in a list, then there's a good chance that they might be suitable for parallelisation. You may not gain a large advantage from doing it though - the real advantage of threading is in making use of multiple system resources - processors, network sockets, etc. It's not the only way of achieving that result though, and it will - as a result - 'hog' more of a system's resource when it runs. (but hopefully for less time)

    To break down the task:

    • We create some 'worker' threads, that do a very simple 'run a command' operation (in this case, ping).
    • We define a list of servers (read from a file), and use the Thread::Queue module to handle queuing.
    • We wait for thread completion, and collate errors.

    Which looks a bit like this:

    #!/usr/bin/perl use strict; use warnings; use threads; use Thread::Queue; my $nthreads = 5; my $process_q = Thread::Queue -> new(); my $failed_q = Thread::Queue -> new(); #this is a subroutine, but that runs 'as a thread'. #when it starts, it inherits the program state 'as is'. E.g. #the variable declarations above all apply - but changes to #values within the program are 'thread local' unless the #variable is defined as 'shared'. #Behind the scenes - Thread::Queue are 'shared' arrays. sub worker { #NB - this will sit a loop indefinitely, until you close the queue. #using $process_q -> end #we do this once we've queued all the things we want to process #and the sub completes and exits neatly. #however if you _don't_ end it, this will sit waiting forever. while ( my $server = $process_q -> dequeue() ) { chomp ( $server ); print threads -> self() -> tid(). ": pinging $server\n"; my $result = `/bin/ping -c 1 $server`; if ( $? ) { $failed_q -> enqueue ( $server ) } print $result; } } #insert tasks into thread queue. open ( my $input_fh, "<", "server_list" ) or die $!; $process_q -> enqueue ( <$input_fh> ); close ( $input_fh ); #we 'end' process_q - when we do, no more items may be inserted, #and 'dequeue' returns 'undefined' when the queue is emptied. #this means our worker threads (in their 'while' loop) will then exit. $process_q -> end(); #start some threads for ( 1..$nthreads ) { threads -> create ( \&worker ); } #Wait for threads to all finish processing. foreach my $thr ( threads -> list() ) { $thr -> join(); } #collate results. ('synchronise' operation) while ( my $server = $failed_q -> dequeue_nb() ) { print "$server failed to ping\n"; }

    Now, this _is_ a very simple model of a 'threaded' task - and it will only suit situations where there are no dependencies on the results.

RFC: Distributed/replicated TIEHASH and shared state algorithm with Corosync
1 direct reply — Read more / Contribute
by dave_car
on Dec 28, 2013 at 14:00

    (updated for clarity)

    I've been working on a Closed Process Group/Virtual Synchrony algorithm to provide a shared state/initial state transfer implementation in Perl. It is not yet a fully fledged module, but prior to that any input anyone may have on the best way to develop it would be welcome.

    As an example of what it can do I've made a networked multi-master tied hash example. Basically, run a "server" instance on each node in a cluster and (UNIX domain socket) clients can see all the data which other nodes have entered.

    Hashes are kept strictly in sync with each other and the data is resilient until all nodes in the cluster have failed (quorum can be added of course).

    For example nodes 1 and 2 could concurrently access a shared hash:

    
    node1: printf "> %s", $a{'hello'}
    node1: >
    
    node2: $a{'hello'} = "world"
    node2: printf "> %s", $a{'hello'}
    node2: > world
    
    node1: printf "> %s", $a{'hello'}
    node1: > world
    
    

    Also there's a more dynamic example which emulates Hypervisor nodes managing VM resources - automatically reallocting VMs when an HV goes out of service or comes back in.

    Any application which requires nodes in a cluster to have a timely view of the whole cluster state could benefit from this approach.

    POD docs are available in the demo scripts over at https://github.com/davidcoles/bogart

    If anyone is working on anything similar or might find this work useful then please feel free to get in touch!

simple as math
2 direct replies — Read more / Contribute
by LanX
on Dec 24, 2013 at 15:33

     

           y   =   ln ( x/m – s a )  / 

        y r²  =   ln ( x/m – s a )

        eyr²  =   x/m – s a

    m eyr²  =   x – m s a

    m erry  =   x – m a s

     

    Cheers Rolf

    PS: Not my creation : )

RFC: Syntax::Construct
7 direct replies — Read more / Contribute
by choroba
on Dec 23, 2013 at 17:45

    The Problem

    When you want to use say in your script, you can tell Perl

    use v5.10;

    I do not like this style, though, because it does not tell me what feature of 5.10 I need to run the script. A slightly better approach is to add a comment:

    use v5.10; # say

    This is still not much convenient for the author, though: He has to go through several perldeltas to find the first version where the feature appeared. I fined the feature pragma much nicer:

    use feature 'say';

    Unfortunately, not all new syntactic constructs are introduced through the feature pragma. For example, the defined-or operator (//) cannot be introduced in any other way then

    use v5.10; # //

    (You can use a higher version, just to confuse the reader more.)

    The Solution

    I read through the deltas and wrote Syntax::Construct. It allows you to put the following into your script:
    use Syntax::Construct qw( // ... );

    And similarly for many features I was able to find in the documentation (see the POD section of the pm file for the full list). Comments or pull requests greatly appreciated.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
One line dynamic run-parts warpper
2 direct replies — Read more / Contribute
by bhildred
on Dec 16, 2013 at 10:36

    I was pondering a hook that runs one script at an event (in git) and bemoaning that I had several scripts that I wanted to run for this hook and that there were other hooks that were similar but had different numbers of options and that run-parts had terrible syntax, and thought this would be so much easier in perl, so ...

    #!/usr/bin/perl use warnings; use strict; system 'run-parts',$0.'.d', map {-a=>$_} @ARGV;

    I'm thinking about removing the use statements to make it faster, but I haven't bothered yet.

Autoboxing ... "Yes We Can" ( or how I learned to love TIMTOWTDI ;)
7 direct replies — Read more / Contribute
by LanX
on Dec 13, 2013 at 13:30
    Perl is like one of these old text adventures, you keep collecting things from perldoc and suddenly you can open secret doors ...

    There has always been much discussion (well flames) about a language idiom called "autoboxing"² missing in Perl.

    I just stumbled over a way of emulating it in Perl by using "method" references.

    The idiom

    Write an anonymous sub like a method, i.e. take $_[0] as $self.

    Then call thing->$method_ref(args) and thing doesn't need to be blessed.

    DB<158> %h=(); DB<159> ref $h{a}{b}[2]{c} # not an object => "" DB<160> $cycle = sub { $_[0]++; $_[0] %= $_[1] } DB<161> $h{a}{b}[2]{c}->$cycle(3); \%h => { a => { b => [undef, undef, { c => 1 }] } } DB<162> $h{a}{b}[2]{c}->$cycle(3); \%h => { a => { b => [undef, undef, { c => 2 }] } } DB<163> $h{a}{b}[2]{c}->$cycle(3); \%h => { a => { b => [undef, undef, { c => 0 }] } }

    The documentation
    See perlop:

    The Arrow Operator

    ...

    Otherwise, the right side is a method name or a simple scalar variable containing either the method name or a subroutine reference, and the left side must be either an object (a blessed reference) or a class name (that is, a package name). See perlobj.

    I used this technique in the past to either

    • speed up method calls (no lookup necessary) and/or
    • to realize 100% private methods (lexical scoping)
    IIRC it's explained in detail somewhere in the "perloo*" group of perldocs...

    The reasoning

    See wikipedia, in short autoboxing allows to use a method call syntax on "things" which aren't blessed objects, like

    DB<100> $a=5 => 5 DB<101> $a->inc Can't call method "inc" without a package or object reference

    The general idea is to combine the flexibility of method call syntax, avoiding the overhead to create a real object.

    For instance a (contrived) example is JS which has the primitive type "string" and the class¹ "String". This allows to write

    'literal string'.match(/string/)

    One way Perl could profit from such a syntax are nested data structures, where often manipulations result in ugly unDRYness and lots of nested punctuation.

    A simple example: ¹

    push @newelements, @{ $a{blossom}{caterpillar}{$loopvalue}[CONSTANT] +{Iforgot} }

    in JS you can not only avoid the sigil, you can also _chain_ method calls

    a["blossom"]["caterpillar"][loopvalue][CONSTANT]["Iforgot"].push(ele +ments).shift()

    The alternatives

    There are more reasons to like autoboxing, there were attempts to overload -> to allow this in autobox but this is considered to be a too fragile hack.

    Attempts to include this syntax as a language feature were regularly rejected / ignored / postponed.

    IIRC does Perl6 intend to have it right away from the start.

    And now ->$RFC

    I was urged in the CB to write a meditation ASAP, so pardon me for typos, broken links and untested code³ which will need updates.

    Being aware of fundamentalists hating this coding style I'm now counting the seconds till the outrage starts... =)

    Others may want to add some other use cases ...

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    Footnotes

    1) yes I know that push was extended "recently" to allow $arr_refs but 5.10 is still relevant

    ²) aka "boxing" aka "wrapper-classes" see also: wikipedia

    ³) and euphoria induced by coffee abuse


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!
  • 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
  • Outside of code tags, you may need to use entities for some characters:
            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.