Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
Don't ask to ask, just ask
 
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
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

Brainfunk. With Regex.
2 direct replies — Read more / Contribute
by oiskuu
on Dec 10, 2013 at 14:06
    Greetings

    my teacher assigned us a brainfuck interpreter[1]. Here's what I've arrived at.

    For timing and testing I have used 392quine.b. This, and some other bf programs found here.

    I'd say this regex based interpreter is fairly legible and uncomplicated (*cough*), though couple of snags remain.
    First and foremost, the unfortunate "recursion" limit is encountered when long (but non-recursing) code is run:
    $ perl -w bf.pl <(perl bf.pl < bf.pl) Complex regular subexpression recursion limit (32766) exceeded at bf +.pl line 5, <> chunk 1. ...
    It should output whatever it was fed (bf.pl itself), but goes apeshit midway through. The workaround is to use (?:(?:__)*)*; however, I find this just too disgraceful. In this thread, ikegami hints at possible upcoming fix. Well, that was four years ago, and it sure isn't fixed in v5.18.1, let alone v5.12.3. I wonder if this is solved in more recent perls?

    Finally, there may well be some important optimizations I've missed or somesuch. Suggestions are welcome, of course.

sourcefilter with complete parser?
2 direct replies — Read more / Contribute
by LanX
on Dec 10, 2013 at 11:44
    Hi

    Sourcefilter are notorious because only Perl can parse Perl, so attempts to manipulate embedded Perl code is doomed.

    BUT

    Did anyone ever attempt to parse and translate a different language with easily defined consistently specified syntax?

    Like JS or LISP or a pedantic Perl sub dialect?¹

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    ¹) or Perl6, Ruby or Python provided that they have such a pedantic syntax (?).

    updates

  • maybe better forget I mentioned Ruby -> how-to-parse-ruby

  • corrected typo hdb++
sort +*, @array
3 direct replies — Read more / Contribute
by raiph
on Dec 08, 2013 at 19:18
    »»» This post is about the immature Perl 6, not the rock solid Perl 5 «««

    I often share small things about P6. This is perhaps the smallest yet...

    So I just encountered this series of recent blog posts by someone exploring P6. Anyhoo, this meditation isn't about what he's written but the P6 feature brought to my attention by a comment added to his 5th post which shows something like this:

    say sort +*, @array;

    Apparently this is akin to a schwartzian transform (which a 4 year old PM post by Moritz suggests is implemented more efficiently than an actual schwartzian transform).

    Update At least two monks failed to see a strong (or any) connection between say sort +*, @array and the ST. In summary the * is a single arg "key extractor" closure, and the P6 sort builtin automatically turns @sorted = sort +*, @array in to something like the P5 code:

    @sorted = map $_->[0], sort { $a->[1] <=> $b->[1] } map [ $_, +$_ ], @array;

    /Update

    Perhaps everyone else already knew this, but I didn't and, weeell... I think it's amazingly short and it came directly on the heels of another tiny triumph of P6 brevity.

    Of course, the main point of the transform is speed, and as the author of the quoted blog mentions in one of his posts, P6 is still slooow (even if it has gotten something like an order of magnitude faster this year for many tasks). But a secondary point of the transform is that it's a nice idiom and I think this is another example of the wide array of nice P6 idioms.

Can you use string as a HASH ref while "strict refs" in use?
2 direct replies — Read more / Contribute
by choroba
on Dec 05, 2013 at 19:04
    At work, I was given a code to add functionality. You can probably imagine - a CGI script that shows a list, some of whose elements might be selected. The part responsible for handling the selected elements confused me (simplified):
    for my $id (@selected) { $list{$id}{selected} = 1; } for my $key (keys %list) { print qq(<li name="$key"); print ' class="selected"' if $list{$key}{selected}; print ">$list{$key}\n"; }

    Wait, what's going on? We test for $list{$key}{selected}, so $list{$key} is a hash reference. Then, we print $list{$key} - but in the output, we do not get any HASH(0x2561a68), but the correct goods' names. I asked a coworker, and she told me this part of the script was "dark magic"; she had debugged it once and still remembered the value was coming out even if it should not. I played a bit with the script to remember I have already seen a similar behaviour: of course, the script does not use strict! Try yourself:

    #!/usr/bin/perl # Script part 1. use warnings; use strict; my $code = << '__CODE__'; %list = ( scalar => 'Plain', ref => 'Overwritten' ); $list{ref}{selected} = 1; for my $key (keys %list) { print "$key: $list{$key}"; print " - Selected" if $list{$key}{selected}; print "\n"; } __CODE__ { no strict; my %list; eval $code; print "Wow: $Overwritten{selected}\n"; }

    The last print explains what happens: Perl sees you are trying to use $list{ref} as a hash reference, while its value is the string "Overwritten". It therefore creates a hash of that name for you (even more funny if the string contains spaces).

    So far, so good. Lesson learnt: the people who tell you "use strict" know what they say. I tried to explain to the coworkers what the problem was, but those not familiar with Perl were not able to understand.

    But then, I thought to myself: Is it possible to make the code work even under strict? tie and overload would probably be useful, as I remembered from Programming Perl. And after several minutes, I was able to run the code under strict. You can test your skills before revealing my solution:

    Just for completness, this is the "common" behaviour I expected at the beginning:

    # Script part 3. { my %list; eval "$code;1" or die $@; }

    Note: The three last code examples should be kept in one file.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Parsing a Tree to a Table.
6 direct replies — Read more / Contribute
by choroba
on Dec 04, 2013 at 20:54
    Recently, I noticed an interesting question on StackOverflow. It reminded me of my solution to the task "Visualize a Tree" on Rosetta Code.

    I tried to solve the task. If you want to see me solving the task, watch a YouTube screencast. If you just want to see the solution (almost identical to the one in the video), check below.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Homework Golf
9 direct replies — Read more / Contribute
by McD
on Dec 03, 2013 at 20:56

    My second grader came home today with a bizzare homework problem:

    Using a simple substitution cipher, where A=1, B=2, etc., define the value of a word to be the sum of its letters.

    So far, so good.

    But the assignment was to come up with a word ... worth exactly 65 points.

    Really? C'mon, that's work for a computer, not a human.

    Specifically, work for Perl. More specifically, a one-liner.

    Which means it's good for a little golf! Here's my offering, finding 65-point words in the unix dictionary, in 93 bytes:

    #23456789_123456789_123456789_123456789_123456789_123456789_123456789_ +123456789_123456789_123 perl -nle '$t=0;for $n (0..(length()-1)){$t+=(ord(lc substr($_,$n,1))- +96)}print if $t == 65;' /usr/share/dict/words

    Update: Huge thanks to everyone who participated! I learned something new from each and every entry, which was at once rewarding and humbling. May I never stumble across any of this in production code! :-)

RFC - Module::Cooker - UPDATE
5 direct replies — Read more / Contribute
by boftx
on Dec 02, 2013 at 00:39

    Update: Version 0.1_1 has been released to CPAN for testing. Documentation is fairly complete, but more love is needed. The executable should work as described in its POD. Help with a test suite for the executable would be greatly appreciated. I expect it to pass on all versions of Perl greater than or equal to 5.8.8, and will not be surprised if it passes 5.6.1. The alpha release can be found at https://github.com/boftx/Module-Cooker/tree/v0.1_1.

    I come to you today asking for a peer review of what I hope will be a useful module to those who need a simple way to create a skeleton CPAN module. The code is NOT complete by any means, but it will pass the basic tests and a module created created with it will pass its tests, as well. I hope to have it completely finished on Thursday but want your feedback now in case I am going down the wrong path somewhere.

    Like most of you reading this, I have used various tools such as h2xs, Module::Starter, Module::Maker (and have examined Distribution::Cooker) to create skeleton distributions.

    And like most of you (I presume) I have found each to be lacking in some area.

    Hence, Module::Cooker. It draws upon what I consider to be the best of the aforementioned tools and adds a bit of my own. Specifically, I have strived to make it as easy as possible to create custom skeleton templates that meet the needs of different types of modules.

    I want whatever feedback you have, good or bad. If anyone wants to be a co-maintainer I wouldn't complain about that, either. :)

    I hope to release this no later than this Thursday since I will be on the road to Houston on Friday morning.

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
RFC extending Benchmark.pm to facilitate CODEHASHREF
3 direct replies — Read more / Contribute
by LanX
on Nov 25, 2013 at 17:30
    Hi

    I never liked the usage of the CODEHASHREF in Benchmark.

    Often people start writing things like

    sub name1 { ... } sub name2 { ... } cmpthese ( -5, { 'name1' => \&name1, 'name2' => \&name2, } )

    which isn't very DRY and makes experimenting with optimizations really cumbersome! (I hate it, every new function name has to be repeated 3 times in different locations...)

    see also Re: Best method to diff very large array efficiently for another examle.

    My idea is to put all subs into a dedicated package (defaultname "CMP" or so) and to automatically filter necessary name and coderefs.

    { package CMP; sub name1 { ... } sub name2 { ... } } cmpthese (-5, pckg_subs("CMP") )

    ATM I'm using a function pckg_subs() for this, not sure if it makes sense to extend the interface of cmpthese and timethese to directly accept a stash-ref like \%CMP::. ¹

    Following a proof on concept, request for comments.

    The idea code be extended with sub-attribute ':compare' or ':nocompare' to additionally mark functions which are supposed to be compared or not.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    ¹) is it possible to tell if a hashref belongs to a stash?

    ... well at least I could parse %main or pass the packagename directly =)

use feature 'postderef'; # Postfix Dereference Syntax is coming in 5.20
9 direct replies — Read more / Contribute
by Anonymous Monk
on Nov 23, 2013 at 03:28
Migrating from Perl to other language? Why would someone do that?
18 direct replies — Read more / Contribute
by pmu
on Nov 21, 2013 at 14:08

    Respected Monks,

    I have been using Perl for many weeks now and thoroughly enjoy the process of learning it and implementing it in my environment. Perlmonks by far has been the main reason why I could pick up Perl so fast. Monks here have been very helpful. I have always got clear and honest answers and hence thought I should bring up a recent incident. Please understand that the only reason to write this is I really truly seek some clarification. I like using Perl and neither have the inclination nor the required deep technical knowledge to differentiate the technical nuances, advantages, disadvantages of any language, especially something as mature and vast as Perl. So kindly note that I do not intend to sound like I am belittling/deriding Perl.

    I happened to discuss the scripts and my plans of automating many more reports and error / failure alerts with some technical managers and developers here and they appreciated it, but some of them seemed amused that I am using Perl. For some reason, they directly/indirectly kept bringing up Python and Ruby stating that now a days it makes more sense to learn these langauges. I tried Python quite a while ago, even before the above discussion but could not really get a hang of it. The whitespace and the scope issues kept biting me. I was infact told that most organizations are in the process of "migrating Perl scripts to Python". Few of them even stated, "If there's just one scripting language you wanna learn and get good at, use and stick to Python because everyone is using it and all the new stuff is done in Python. It's much more modern, more powerful and flexible than Perl, and definitely more legible and there are more Python jobs than Perl jobs so that should tell you which language is more in demand". Another guy stated that Python/Ruby are truly Object Oriented languages and it makes more sense to learn them.

    I've contacted these guys before for certain issues and they were always helpful and I am amazed no end why they think this way. Some of them are good well meaning friends as well.

    I therefore request the monks here to please shine some light on this issue.

    How and why would organizations move away from Perl? Is it because Python is easier to learn? From whatever I have seen of Perl in past few weeks, its one fine language and especially for scripting and text manipulation, I don't think there is any other language that can come even close to it. So why is this step brotherly treatment meted out to it? What would organizations gain by moving away from Perl? Just that fact that there are more Python guys out there than Perl guys?

    In my extremely limited understanding, a scripting language or the scripting facet of a language is a way to get a job done, to get a goal accomplished, or get a desired automation done. Why would someone really bother which sort of language is being used? It's not like I am writing a kernel or some big software. I just write scripts that automate things, that send the outputs, reports etc. They why so much focus on which language it should be done in?

    The question that's stuck in my mind though, is, why are people moving "away" from Perl? It's not like its a Technology Refresh where you have to move your servers/storage/databases/applications from "End of Life" Hardware/software to something new. Is this a common phenomenon?

    I once again humbly state that I do not intend to deride Perl. But at this point I am really really confused.

    || Aeterna Est Perspectum Cognitio ||
Carp; fresh water fish -- a delicious new recipie
2 direct replies — Read more / Contribute
by taint
on Nov 21, 2013 at 01:40
    Greetings, Monks.

    I just stumbled upon a fun, new recipie for carp

    It's a module (CGI::Carp::DebugScreen). Seems to add some potentially very useful additions -- almost a kind of Carp Blog. Enough of the nonsense. This looked like it might useful, so I thought I'd share my findings with you all.
    From it's page on CPAN:

    CGI::Carp qw/fatalsToBrowser/ is very useful for debugging. But the error screen it provides is a bit too plain; something you don't want to see, and you don't want your boss and colleagues and users to see. You might know CGI::Carp has a wonderful set_message() function but, you don't want to repeat yourself, right?
    Hence this module.
    This module calls CGI::Carp qw/fatalsToBrowser/ and set_message() function internally. If something dies or croaks, this confesses stack traces, included modules (optional), environmental variables (optional, too) in a more decent way.
    When you finish debugging, set debug option to false (via some environmental variable, for example). Then, more limited, less informative error screen appears with dies or croaks. If something goes wrong and your users might see the screen, they only know something has happened. They'll never know where your modules are and they'll never see the awkward 500 Internal Server Error -- hopefully.
    You can, and are suggested to, customize both debug and error screens, and some style settings, in harmony with your application.

    So what do you think? Let me know.

    --Chris

    #!/usr/bin/perl -Tw
    use Perl::Always or die;
    my $perl_version = (5.12.5);
    print $perl_version;
RFC: Perl-based Point of Sale Projects
1 direct reply — Read more / Contribute
by einhverfr
on Nov 19, 2013 at 05:41

    Fellow Monks;

    I am in the process of building modules and utilities for a point of sale project. My thinking here is as follows and I would like to open it up to other thoughts, review, etc. This may be a bit long, so I hid it as a spoiler

    In terms of point of sale frameworks, what changes should I consider in order to facilitate more code sharing with other projects?


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

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (8)
    As of 2014-04-23 09:17 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      April first is:







      Results (541 votes), past polls