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").
I want to meditate on some of the most useful perl-isms that, while easy, are oft misunderstood for beginners. I say that, and am possibly projecting, since when I was a beginner, I had not grokked them and had misused them. I also want to give kudos to the comments below as they have greatly helped refine this posting.
Map, Grep and Sort are not the same thing, but are often used together. Flowing from right to left, they act like shell pipelining in reverse. They build something new, like a tiny little factory. While the original data structure is untouched, it should feel like a list is being transformed every step of the way.
Did you ever want to memorize the s/// option list? The full list (from perlop) is msixpodualgcer.
Here are some anagrams I found:
* discourage p/m/xl (petite, medium, extra-large)
* glamorised x cpu
* Proclaimed, "g sux!" (oft heard?)
* xl CPU ideograms (extra-large CPU)
* goru x misplaced ("guru is misplaced")
* ex-cpu marigolds
* dog pux miracles (poo or pukes)
Can anyone come up with something better?
-QM
--
Quantum Mechanics: The dreams stuff is made of
I use my laptop as test environment. When all (upgrades) pass on production/utility software, I upgrade my workstation. If that shows no problems after a few weeks, I start upgrading other production servers.
So I installed 5.18.0 on my laptop as default perl, and then tried to install all CPAN modules I ever used in 5.16.x
There are just a few things that stand out as a reason for FAILure:
Test files that use for $foo qw( … ) { which is now deprecated. The module autor should rewrite that to for $foo (qw( … )) {. I filed RT tickets for all I encountered. Lets hope the authors will fix their code.
POD failures. As the POD checker is now way stricter than the old version was, it shows more real trouble. And it should! The problem is that many authors ship the pod tests too, so the test suite will fail if Test::Pod and friends are installed, and thus cpan won't install those modules. That means manual work ignoring the pod errors (and when obvious file RT tickets). Authors: unless you keep in sync with reality and release often, please do not include pod tests in you distribution.
Loads of warnings when a module uses given/when as those are now marked experimental. I can ignore the warnings when testing, but will they fill up my logs when run in production code? When the module also uses Test::NoWarnings, one cannot install. A module like MooseX::App now won't install, and it causes many other modules that have this as a prerequisite to fail too.
XS authors that never updated ppport.h from Devel::PPPort. Easy to fix.
Modules that use Module::Install but ship ancient or incomplete versions of it in inc. The easiest solution for me was to just recursively remove inc/ and all problems vanish. I have no tuits to RT all of them.
Several modules fail because they declare optional deps that are actually hard deps, like using JSON::XS, Lexical::Sub or Data::Alias - which won't build under 5.18.0
Test failures, or maybe even code failures, due to hash randomization. Unless I am absolutely sure that the test is wrong, I cannot install these modules.
Some failures have been reported to the authors but the available fix has not (yet) been applied (like in Template::ToolkitRT#84778) or not yet released (Tk and SQL::Statement). When their repository is open, they build fine from the repo and I am confident the next release will build fine.
The message is: perl-5.18.0 is awesome, but please please test the module you require before starting the installation on machines other than a test environment.
Hello Monks,
I wanted to write a basic how-to on using WWW::Mechanize that was suggested in Tutorial Quest.
I will provide a basic over-view of how to log in to a website.
One DON'T that I will say right off the bat to save future frustration is that
WWW::Mechanize DOES NOT SUPPORT JAVASCRIPT.
One of my first tasks at my job was to write a crawler that logged into a website and
downloaded some account information. I will provide that portion here.
Some other tools will make working with Mechanize much easier. These would be Firebug
(or some other web page inspector) and HTTP Live Headers. For this project, I really
only needed Firebug. You will need this to inspect what the names and values of particular
parts of the website you are trying to access.
One can also set the agent_alias to several different things. In this example, I did not set it.
But you can do so like: $mech->agent_alias($alias);.
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
my $url = "https://homepage.com";
$mech->get($url);
$mech->follow_link( url => 'https://account.login.page.com');
if ($mech->success()){
print "Successful Connection\n";
} else {
print "Not a successful connection\n"; }
You will notice here that I just made an if statement to verify if the event was successful.
There is a $mech->success function which is very useful for knowing if it went through OK.
It is good practice from what I have learned so far to give yourself some kind of verification that
what you did worked. This can also be done by putting:
The mech->dump_* functions are very useful for debugging or finding out more things about the page you have
accessed last. Use them frequently. There is a dump_forms, dump_text, dump_links, etc..
The next part I had to do was enter username/password, start/end date for the report I wanted to receive.
I did it with the following:
#This block of code is intended to fill in the required forms
$mech->get("https://account.login.page.asp");
my $usr = "username";
my $pw = "password";
$mech->form_number(1);
$mech->field( "capsn", $usr);
$mech->form_number(2);
$mech->field("capsp", $pw);
$mech->form_number(3);
$mech->field( "startdate", $start_date);
$mech->form_number(4);
$mech->field( "enddate", $end_date);
$mech->click();
Here I had to inspect the page with Firebug and find the name of each of the fields
(in quotes in my script) and set their value to the variable I declared.
The 'click' method did not need the button name specified, though you may have to do that some times.
Yes, this site used SSL, and no, I did not need to do anything special to login to it this time.
However, I have had to crawl another website using SSL, which I did need to do something special with.
This is what I had to do:
use WWW::Mechanize;
use IO::Socket::SSL qw();
my $mech = WWW::Mechanize->new(ssl_opts => {
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
verify_hostname => 0,});
In this method, I set it to not verify SSL.
Actually, the start and end dates were acquired with a little bit more work using a
different module, DateTime. I can get into that later.
Newbies to this module should keep in mind that Mechanize DOES NOT interpret javascript.
The only way around this that I have found so far is to use HTTP Live Headers to inspect
what the HTTP is doing as you navigate through the site. Where there is GET, use $mech->get($url). Where there is
a POST, use $mech->post('$url'). I HAVE successfully navigated a javascript heavy
web page using this method. It is extremely tedious. If you have a CHOICE, use
WWW::Mechanize::Firefox, WWW::Selenium, or some other module that interprets javascript.
One way for the Perl 6 community to attract contribution to Perl 6 is to write How-To instructions. This meditation is a request for brainstorming and constructive comments on what else we can do. For example, would a Perl 6 realm on questhub be helpful?
Please don't post if you are not currently interested in contributing to Perl 6. If you do post, please hug trolls and focus on helping yourself or other potential Perl 6 contributors get what you/they want. Thanks!
Honing my understanding and skills, I have a script which accesses a mounted windows system and clears out temporary folders. Great for learning about recursion etc...
I set about providing myself with some default filepaths and mountpoints, lest i decide not to provide them as arguments to my script. The starting directories are in the file and the script runs through the paths and recursively unlinks the files under those directories.
I developed a nice little help parser
die 'do not run this code';
#get arguments;
my ($filepathlist,$mountpoint)= @ARGV;
die 'usage & defaults' if $filepathlist =~ /^-{0,2}h(elp)?\s*$/;
die 'do not run this code';
$filepathlist = 'home/Documents/directorieslist' unless $filepathlist;
$mountpoint = '/mountpoint/windows/' unless $mountpoint;
push @dirpaths readdir($filepathlist);
# homemade file::find with custom unlinking behaviour
# simplified for this example
sub recursivelyunlinkfiles{
while(my $path = shift @dirpaths){
$path = $mountpoint.$path;
unlink if -f $path;
&recursevilyunlinkfiles if -d $path;
}
}
so this works if no arguments are provided and sets the filepath if one argument is provided, using the default mountpoint.
I went back to clear up the edge case of an orphaned hyphen whilst requesting the usage info. At which point I realised the tremendous disaster which lay ahead, had I tested this on a singular argument consisting of either a filepath or mountpoint. Of course I had put die statements everywhere like a keen domino course constructor interspersing the frail light blocks with large heavy lumps of immutable iron. Debugger runs the code and dieing in source is a good way to reinforce your breakpoints.
The following is a standard example in Ruby for the combination of code-blocks {... } and yield-statement:
#!/usr/bin/ruby
def test
puts "You are in the method"
yield 1
puts "You are again back to the method"
yield 2
end
test {|a| puts "You are in the block #{a}"}
Just to prove my strong opinion that Ruby is semantically just a Perl dialect I tried to simulate it with some syntactic sugar:
use strict;
use warnings;
use feature qw/say/;
=pod
Block sub is basically syntactic sugar for taking an anonymous sub {}
and returning it. Blessing it with "Block" facilitates syntax checks.
=cut
sub b(&) {
my $c_block=shift;
bless $c_block, "Block";
return $c_block;
}
=pod
"yield" uses a little know trick to access the @_ of the caller. It
checks the last argument of the caller, if its a ref blessed to
"Block" and calls it with the own arguments.
Note:
Ruby allows mixing normal arguments and blocks, as long as the
block is in the last position. When using & prototypes in Perl like
in C<test(&&)> only the first block can be passed w/o leading sub.
=cut
sub yield {
package DB;
my ($package, $filename, $line, $subroutine)=caller(1);
no warnings;
my $c_block = $DB::args[-1];
package main;
return $c_block->(@_)
if ref $c_block eq "Block";
die "$subroutine called w/o block in $filename line $line";
}
=pod
simulating the ruby test-code
=cut
sub test {
say "You are in the method";
yield 1;
say "You are again back to the method";
yield 2;
}
test b{ say "You are in the block $_[0]" };
I have been meditating on Prims MST algorithm and a pre-order walk of the MST. The code below is the solution that I generated. The code uses the Graph module for the data structure. There are a couple of assumptions with the solution. 1.)The vertexes have (x,y) coordinates 2.)The weighted edges are the euclidean distance between two edge connected vertices. 3.)The graph is complete and undirected
Let me know what you think and or suggestions for improvement
#Prims algorithm to calculate MST of $G
sub prims{
my($G, $root, $output) = @_;
my $MST = (ref $G)->new;
$MST->add_vertex($root);
$MST->set_vertex_attribute($root, "X", $G->get_vertex_attribute($r
+oot, "X"));
$MST->set_vertex_attribute($root, "Y", $G->get_vertex_attribute($r
+oot, "Y"));
my @MST;
while($MST->vertices != $G->vertices){
my $edge_weight = 9**9**9;
my $lw_vertex;
my $compared_vertex;
foreach my $vertex($MST->vertices){
foreach my $successor ($G->successors($vertex)){
##Find the lowest cost safe edge
if(($edge_weight > $G->get_edge_weight($vertex,$successor
+)) && ! $MST->has_vertex($successor)){
$edge_weight = $G->get_edge_weight($vertex,$successor
+);
$lw_vertex = $successor;
$compared_vertex = $vertex;
}
}
}
#add the vertex and edge to the cut
$MST->add_vertex($lw_vertex);
$MST->add_weighted_edge($compared_vertex, $lw_vertex, $edge_we
+ight);
$MST->set_vertex_attribute($lw_vertex, "X", $G->get_vertex_att
+ribute($lw_vertex, "X"));
$MST->set_vertex_attribute($lw_vertex, "Y", $G->get_vertex_att
+ribute($lw_vertex, "Y"));
push(@MST, "($compared_vertex, $lw_vertex)");
}
##Print out the set for assignment
print "MST = {@MST} \n";
print {$output} "MST = {@MST} \n";
return $MST;
}
I guess Perl would be pretty useless then. But that's actually a red herring question, because if CPAN doesn't exist now, people will soon create it or something like it.
The real question to ponder is: if you were to design something like CPAN today (a.k.a. 2013 instead of 1995), how would you design it? Assume things like RubyGems, PyPI, Packagist, npm are already there for us to steal good ideas from. Would you design it completely differently, or do you want nothing to change at all?
We are talking about the whole ecosystem here (PAUSE, the metadata, the clients, the accompanying services like CPANTesters, MetaCPAN, etc).
API instead of filesystem. Looking at the trends, the static pages and filesystem-oriented design are out, replaced by an API-/service-oriented one. A feature will soon be added, one which always remains absent from current CPAN: download/install counters.
More centralized. Servers are now usually powerful enough (in terms of CPU and bandwidth) to host something like a CPAN web application, so being distributed and FTP-/mirror-friendly now perhaps do not need to be a primary design criteria. A caching/proxy/minicpan-like mechanism can always be added later.
Client. The main CPAN client will be something no fuss and configless like cpanm right from the start, as there are no mirrors etc or static index files to choose/download anyway. Features like installing from github/bitbucket by pointing at a URL will be standard.
Metadata. Things that CPAN do right like separating build/test/runtime dependencies (something which most other languages do not bother to do) are certainly still in.
I actually love the Text::Something::Blah or WWW:: namespace style, so that will also stay in (it's a good balance between full reverse DNS style in Java like org.mycompany.Package.SubPackage, and unique+cryptic names in the Ruby/Python/npm world like cucumber/jinja/twig/whatever). One thing that should be popularized is for authors to add tags or categories metadata to its distributions (it's something that's already in the spec but rarely, if ever, used).
Updating module status, like marking it as deprecated, should be doable without creating a new release.
Something like BackPAN should definitely exist.
Other ideas: Live inside a single git repo or as a github project?
It's still early here and I'm still half awake. But I'll add more later.
I spent the Easter vacation with my son and friends in the country. I took my netbook with me, just in case, because a colleague of mine asked me to add a new feature to my survey web application. Once the boy fell asleep, I turned the netbook on to realize that I forgot to reinstall the CPAN modules after upgrading the OS and Perl, and that there was no wi-fi.
Instead of turning the computer off, I gave the situation some thought. After few minutes of thinking and locating, I discovered I still had all the CPAN build directories for the modules (mostly Plack and Dancer & their dependencies) in my .cpan directory. It was not so hard to create a script that went through all of them (sorted by last access time so I did not have to bother about dependencies) and rebuilt all the packages. After several minutes, I was able to start the application and began implementing the feature.
I'm doing some market research for Stratopan, which is an experimental service for hosting private CPAN-like repositories of Perl modules in the cloud. I'd like to know how you manage the upgrade and deployment of CPAN modules in your world. Some of the techniques I've seen are:
Install from a local mini CPAN
Vendor packages (RPM, PPM, Debian Pkgs)
Install directly from public CPAN
Stash the tarballs from CPAN in version control
Build the modules directly into our source tree
Use carton and/or cpanfile
Don't use any CPAN modules
Never upgrade any CPAN modules
The sysadmins do everything
Aside from helping me, your answers will shed some light on how CPAN modules are handled in the wild, which could lead to some insights on how to improve the tool chain. Just this past weekend at the QA Hackathon, there was much discussion about improving the CPAN infrastructure, so your feedback will be really helpful to them.
We have seen some success in the April issue of our all beloved TIOBE index. This is the result of various efforts here @ Perlmonks as well as other work (monks working hard on the english Wikipedia and other pages).
For propaganda.pm, this positive glimpse when the April numbers
were published, came not as a surprise, because we're now
monitoring the same parameters TIOBE does, do the same computations -
on a daily basis.
And because we do, we now can see trends, hot spots (a.k.a. burning
issues), especially if efforts seem to "run out of juice". And of
course if search engines do weird and shady things. (Does anyone have
the email of mommy Marissa Meyer?) Currently we see again stagnation
in the overall numbers, therefore I'd like to present here the
currently most burning issue. I have set up an
article showing the
current status quo and discussing YouTube
The article describes the issue in detail and has also a call for
action, but let me paraphrase some things here for a short
summary:
There are (order of magnitude) about 2mio search hits for the term
"Python", there are about 80k search hits for the term "Perl". Yes not
all of these denote the programming languages, but
most of them
do. Interestingly, the quotient of these numbers and the occurence
"XXX programming" is about 100:1, so you will find 22k hits for
"Python programming" while only a little bit less than 900 for "Perl
programming" (which - BTW - are already a result of propaganda.pm
work, two weeks ago it was 800).
We therefore strongly suggest, you
Fetch yourself some popcorn, nachos and favourite bewerage and
start watching the perl-related videos. There's a high chance you
will be surprised of the content and the quality you'll find
there. We were.
Comment on these videos, answer questions and make sure, you
mention in your comment at least once the "Perl programming
language".
If you have Perl-related videos on YouTube or know someone who
does, please suggest that these are tagged with "Perl programm
ing (language)"
Have a look at the "python programming" videos and see if some of
them couldn't be done for Perl accordingly (and containing "Perl
programming language").
If you have own ideas of Perl-related content on YouTube, please
make them come true.
Participate in Perl/Python, Perl/Ruby, Perl/PHP discussions. Be
polite, don't advocate but educate, make sure the "Perl
programming language" term is used.
If you have other ideas how to bridge that 900 to 22000 gap, by
all means, please try to implement them.
In general, however, there is virtually NO Perl-related content
on YouTube (compared to other popular scripting languages). No mass,
nothing to yield from. Let's gain mass!
Despite YT only having a weight of 9% in the index, this huge
unbalance in content, drag the Perl numbers in the overall TIOBE index
down badly. Please help. Please focus your contributions on this
popular channel, which is not seldom the entry point for newbies to
programming in general.
propaganda.pm - Not just another Perl Mongers Group.
I am Storage Administrator on a lookout for finding ways to automate certain tasks. Recently we encountered an issue where a few server HBAs would suddenly log out of a SAN storage array. The problem was random but was happening with storage array from a specific vendor. The storage and the server vendors' analyses of various parameters could not point out to the underlying issue.
Unfortunately, the Storage Array alerting system is not capable of capturing the log outs and many times we were caught unaware.
So, we were on a lookout for a solution that would report this issue. That's where Perl came in. :). Using DWIM Perl, a script was written that would log in to each storage array (Net::SSH2 Module) picking up the IPs from a text file, write the output to a text file, then using regular expressions, only the hosts that had one or more HBAs logged out would be e-mailed to our DL (MIME::Lite). The username/password information, the mail server information, the location of the text files, and the command that would capture the information, was saved in a seperate file and as & when required, the fields were called into the script (Config::Tiny Module).
Another issue was noted with our NAS Arrays where in the Data Movers would reboot/panic and the alert indicating the same would many times not be fired for some reason. Also, the data movers would not reflect that they were a few hours or even days behind each other.
Once again, Perl helped automate the alerting. Using similar methods as above, it would generate e-mails and that ways, avoid issues.
I used to read about how Perl shines at slicing and dicing text files, how the modules make the work easy and such stuff. But only when I started writing the scripts, the power was visible. Perl is truly a great language.
Apart from writing some basic, small C programs, I had never done any programming at all, and the last time I wrote a C Program was about 12 years ago....Not that learning Perl happened in a matter of few days. It did take me quite a while to get some basic comfort level with the language and the eternal learning will continue, but what is amazing is the quickness with which Perl allows one to get a script up and running. The fact that your script is running in your production environment, doing some really useful stuff gives a real different high. What I have written is not rocket science or something that is mind boggling complicated stuff, yet, the satisfaction is immense.
Another advantage, is that Perl rekindled my interest in Linux. Yeah, DWIM Perl on Windowsis amazing and comes pre installed with almost all the modules that one would need, yet, learning Perl on Linux was a quite different experience.
And just to get Perl on my system, I installed Linux on my personal laptop. I tried CentOS, Fedora, Ubuntu and started toying around with the OS, with the System Perl that came pre installed in them and such stuff. It helped me get comfortable with Linux, which got me interested in some system admin related stuff, which in turn helped me become a better storage administrator.
To the Perl Community, the creators of DWIM Perl, and ofcourse..PerlMonks, Thank You. Thank You Very Much. It feels good.
Perlpetually Indebted To PerlMonks
use Learning::Perl;
use Beginning::Perl::Ovid;
print "Awesome Books";
I saw this web framework benchmark on hacker news and didn't see any perl frameworks on there. Does anyone have time to add benchmarks for some of the popular perl frameworks like Catalyst, Mojolicious, Dancer, etc.?