The Snippets Section is closed, and all of the snippets which were posted there have been converted to Cool Uses for Perl. Never fear! They have each been specially tagged, and are presented here for your reference.

If you wish to post a CUFP specifically as a snippet (which we don't recommend), you may, after posting it in CUFP, add the 'snippet' keyword to it via the Keywords Nodelet.

For a list of all the snippets — titles only — you may visit the Snippets Lister.

Snippets
functional programming: scan function
on Mar 12, 2009 at 15:49
1 reply by metaperl
    I needed a scan function for some data processing I am doing. Unfortunately Sub::Curried does not work, so I cannot use it's scan function.

    Language::Functional has a broken test suite. And I can't figure out how to fix its issues.

    fp does not have a scanl function. I considered contributing this code to it, but am turned off by the semantics of the reduce function... I think that would be better named behead. It also potentially conflicts with List::Util in that respect.

    So here we have the scanl function, a staple of functional programming, available in standalone fashion. As you can see, it behaves the same as scanl for haskell

    use strict; use warnings; use Data::Dumper; =for comment scanl f q ls = q : case ls of [] -> [] x:xs -> scanl f (f q x) xs =cut sub scanl { my ($f, $seed, @list)=@_; my @tail = @list[ 1 .. $#list ] ; my @rest = scalar @list ? scanl($f, $f->($seed, $list[0]), @tail) +: (); ($seed, @rest); } my @lis = (4,2,4); sub add { $_[0] + $_[1] } sub divide { $_[0] / $_[1] } my @result = scanl \&divide, 64, @lis; warn Dumper(\@result); @result = scanl \&divide, 3, (); warn Dumper(\@result); use List::Util 'max'; @result = scanl \&List::Util::max, 5, (1 .. 7) ; warn Dumper(\@result);
One-liner: Inspecting a browser cache with File::MMagic
on Feb 27, 2009 at 21:01
0 replies by missingthepoint
    Browser caches are interesting places. Firefox, in particular, has many files all with intuitive names like 'FA509DE4d01', and no extensions. Fortunately Unix culture has a method for bringing order to this chaos: 'magic' databases, or files containing bytes found in particular types of files. These allow you to guess a file's type based on its contents. Perl provides 'magic' support in the form of File::MMagic, and the following one-liner uses it to print the guessed types of all files in the current directory. (Update: typo, and removed useless Data::Dumper)
    perl -MFile::MMagic -e '$mm=File::MMagic->new; for(glob("*")){$res=$mm +->checktype_filename($_);print "$_:\t$res\n"}'
Win32: Launch and wait for Pageant before resuming
on Feb 03, 2009 at 20:06
0 replies by bart

    I use PuTTY tools from a Perl script, in particular pscp (PuTTY scp), and I use Pageant for automated authentication, so that I don't have to type in my password for every single file to transfer.

    But my Pageant uses a password to its vault, too. So Pageant must already be running and ready before I attempt to scp files, or I still have to type in my password, every time, manually.

    And that's where this snippet comes in. It tries to start up Pageant, waits till it comes back and/or until you typed in the password and pressed return, and only then resumes.

    I use Win32::Process to launch Pageant, and one of 2 things may happen:

    1. Pageant wasn't running and it will pop up a login dialog box asking for the password. And then, after the dialog box closes, the process will continue running in the background, with an icon in the systray. If you Wait for that process to finish, you can wait for a very long time...

    2. Pageant was already running in the systray and the process immediately exits.

    So, what does the snippet do?

    1. It reads the parameters to launch Pageant with from a Windows shortcut file (*.lnk file) — You may skip this part.

    2. It launches Pageant using Win32::Process, and it waits for 2 seconds for it to finish. So, in case (2) it'll immediately return, but in case (1) it'll give the program enough time to show its password dialog window.

    3. It uses Win32::GuiTest to see if the password dialog is still up, and polls, and waits until it closes.

    use Win32::Process; use Win32; use Win32::Shortcut; my $link = Win32::Shortcut->new; $link->Load("D:\\Program Files\\Putty\\start pageant.lnk"); $link->Close(); # print "Shortcut to: $link->{Path} $link->{Arguments}\nDirectory: + $link->{WorkingDirectory}"; Win32::Process::Create(my $process, $link->{Path}, qq("$link->{Path}" $link->{Arguments}), $link->{ShowCmd}, NORMAL_PRIORITY_CLASS, $link->{WorkingDirectory}) or die Win32::FormatMessage( Win32::GetLastError() ); require Win32::GuiTest; # while we're waiting... my $result = $process->Wait(2_000); # returns immediately if page +ant was running # times out if it just got st +arted up while(1) { my @windows = Win32::GuiTest::FindWindowLike(0, qr/^Pageant:\s ++Enter\s+Passphrase/i) or last; sleep 1; }
Programming in Perl without semicolon
on Jan 30, 2009 at 16:50
4 replies by buetow
    I've a few good friends who like Python a lot (yes it is a nice Language, but I like Perl more). One difference is, that you can program in Python without using semicolons. Well, this is possible using the Perl language too, like the following code demonstrates it (it calculates fibonacci numbers, however without use strict). I don't tell, that you will have any benifit by not using a semicolon. But I think this is a funny way of programming in Perl. Enjoy :)
    #!/usr/bin/perl { $n = shift || die "Usage: perl nosemicolon.pl NUMBER\n" } sub fib { if ($_[0] < 2) { $_[0] } else { fib($_[0] - 1) + fib($_[0] - 2) } } { print "Fibonacci numbers from 0 to $n are as follows:\n" } for (0 .. $n) { print "fib($_) = ", fib($_), "\n" } print "Thanks for using this software!\n"
Obfuscated accessor
on Jan 27, 2009 at 15:16
0 replies by bluescreen
    I was thinking if there any chance to write an accessor in just one line, and I came up with the following code. Of course I wouldn't use in a real project because its unreadable but it might worth sharing. The good thing is just replacing subroutine name creates a new accessor.
    sub methodA { $_ = (caller(0))[3];s/.*\://; @_ > 1 ? $_[0]->{$_} = $_[ +1] : $_[0]->{$_} };
Vow Triptych
on Dec 30, 2008 at 10:22
3 replies by hashED
    So I'm getting married in October, and I started thinking about wedding vows, and so I wanted to get a better feel for what other people spend most of their wedding vow-ing time talking about. Here's a little script that came out of that effort. It takes a text file full of wedding vows (which you'll have to provide for yourself) and prints the text's triptycs.
    #!/usr/bin/perl my@wordsInOrder; while (<>) { foreach ("$_" =~ m/\w+/g) { push @wordsInOrder, lc($_); } } my$trypHash = {}; for ($i=0;$i < scalar(@wordsInOrder)-2; $i++) { $trypHash->{$wordsInOrder[$i]." ".$wordsInOrder[$i+1]." ".$wordsIn +Order[$i+2]} += 1; } my$dupeHash = {}; for ($i=0;$i < scalar(@wordsInOrder)-1; $i++) { $dupeHash->{$wordsInOrder[$i]." ".$wordsInOrder[$i+1]} += 1; } my$oneHash = {}; for ($i=0;$i < scalar(@wordsInOrder); $i++) { $oneHash->{$wordsInOrder[$i]} += 1; } foreach my$one (sort {$oneHash->{$b} <=> $oneHash->{$a}} keys %{$oneHa +sh} ) { print "$one\n"; foreach my$two (sort {$dupeHash->{$b} <=> $dupeHash->{$a}} keys %{ +$dupeHash} ) { next unless $two =~ m/^$one/; print "\t$two\n"; foreach my$three (sort {$trypHash->{$b} <=> $trypHash->{$a}} k +eys %{$trypHash} ) { next unless $three =~ m/^$two/; print "\t\t$three\n"; } } }
Dump JudyHS
on Dec 29, 2008 at 17:57
0 replies by diotalevi

    This dumps the contents of a Judy::HS/JudyHS(3) array. I had to violate its API to do this. JudyHS is constructed as nested Judy::L/JudyL(3) arrays. The top level encodes the string length. The next level encodes a hashing. Each additional level encodes another 4 or 8 bytes of the input string until no more are needed and it terminates in a C struct which contains the key and value.

    The below example loaded Judy::HS with a map from string to line number. It's completely arbitrary and I did it just to demo to myself that I could enumerate the contents of Judy::HS if I needed to.

    Judy.h in the Judy C library has a nice, readable description of the structure that's being dumped here.

    #!perl use strict; use warnings; use Config '%Config'; use Judy::HS qw( Set ); use Judy::L qw( First Next ); use Judy::Mem qw( Peek Ptr2String2 ); use constant LONGSIZE => 0+$Config{longsize}; # Load $hs with a pile of data. my $hs; @ARGV = "$ENV{HOME}/Documents/Political Data/Secretary of state/Statew +idevoters13102.txt"; while (<>) { Set( $hs, $_, $. ); } # Nested printing. our $P = -1; sub p { print ' ' x ( 4 * $P ), @_ } # Loop over JudyL array, each entry contains all strings of length $le +ngthKey. my ( undef, $lengthL, $lengthKey ) = First( $hs, 0 ); while ( defined $lengthKey ) { local $P = 1+$P; p( "LENGTH: $lengthKey\n" ); # Loop over JudyL array, each entry contains all strings that map to + the same $hashKey. my $hashCount = 0; my ( undef, $hashL, $hashKey ) = First( $lengthL, 0 ); while ( defined $hashKey ) { local $P = 1+$P; p( sprintf "HASH @{[ ++ $hashCount ]}: 0x%x\n", $hashKey ); # Recurse down through JudyL until I find the key/value. dumpLTree( $hashL ); ( undef, $hashL, $hashKey ) = Next( $lengthL, $hashKey ); } ( undef, $lengthL, $lengthKey ) = Next( $hs, $lengthKey ); } sub dumpLTree { my ( $l ) = @_; # Find the stored key/values. if ( Judy::JLAP_INVALID & $l ) { $l &= ~Judy::JLAP_INVALID; local $P = 1+$P; # Unpack the C struct containing my key value. The value is the fi +rst my $value = Peek( $l ); my $str = Ptr2String2( LONGSIZE + $l, $lengthKey ); p( "{Value: $value, String: $str}\n" ); } else { # Go deeper. my ( undef, $innerL, $key ) = First( $l, 0 ); while ( defined $key ) { local $P = 1+$P; p( "str: $key\n" ); dumpLTree( $key ); ( undef, $innerL, $key ) = Next( $l, $key ); } } }
Corrector
on Dec 02, 2008 at 10:47
2 replies by gok8000

    Hi all,

    Sometimes I have to change words inside text files. When this happens, and when I know what to search for, I use this program.

    #!c:/Perl/bin/Perl.exe # # corrector.pl # changes words inside text files # placed in the win directory C:\filestochange # which is supposed to contain text files # my $dir_to_process = "C:\\filestochange"; opendir DH, $dir_to_process or die "Cannot open $dir_to_process: $!"; foreach $file (readdir DH) { unless ($file eq "." || $file eq ".." || $file eq "discarded" || $fi +le eq "tmp") { print "in $dir_to_process $file is processed\n"; open (INFILEHANDLE, "C:\\filestochange\\$file") or die "error open +ing"; open (OUTFILEHANDLE, ">C:\\filestochange\\tempfile8000") or die "e +rror opening"; while (<INFILEHANDLE>) { # chomp; s/this/that/; # substututes this with that s/one/two/; # substututes one with two print OUTFILEHANDLE; } close INFILEHANDLE; close OUTFILEHANDLE; rename "C:\\filestochange\\tempfile8000","C:\\filestochange\\$file +"; } } closedir DH; print "\nDone (press enter key)\n"; $line = <STDIN>;
Commifying sensibly
on Dec 01, 2008 at 09:57
2 replies by oko1

    Recently, I was thinking about that example in the docs where they demonstrate a method for inserting commas into a numerical string. Now, I realize that they're trying to illustrate a specific mechanism with regexes... but that thing is just clumsy and awful and obfuscated for any Perl beginner. So, just for my own entertainment, I decided to see how I'd do it "for real" - i.e., in the best way possible rather than by this contrived method.

    Herewith, humbly, I present a couple of options. :)

    #!/usr/bin/perl -w use strict; die "Usage: ", $0 =~ /([^\/]+)$/, " <numeric_string>\n" unless @ARGV && $ARGV[0] =~ /^\d+$/; my ($c, @list); for (reverse split //, $ARGV[0]){ unshift @list, $c++ % 3 || $c == 1 ? $_ : "$_,"; } print @list; # Or, instead of "cheating" with an unquoted list, we could # aggregate to a string. It's not quite as neat, though. :( # # my ($c, $out); # for (reverse split //, $ARGV[0]){ # $out = $c++ % 3 || $c == 1 ? "$_$out" : "$_,$out"; # } # print "$out\n";
RedHat Linux Security Audit
on Nov 26, 2008 at 15:06
2 replies by redleg7