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
One-line CSV Parser
on Apr 03, 2008 at 15:47
4 replies by BiffBaker
    How is this for quick parsing of standard CSV?
    map {if (/^".*"$/) {s/\s*"\s*//g; push @fields, $_;} else {push @field +s, split /\s*,\s*/;}} split /,*("[^"]*"),*/, $line;
regexp s/mode quicktest
on Mar 19, 2008 at 21:55
1 reply by halfcountplus
    This is just like ReadLine regexp quicktest except it tests a string for substitutions. You can screw it up just as in your own perl code! Again, if you have an instance where this doesn't hold true comment. To be clear:

  • string: give a string to be substituted from
  • replace: give a regexp pattern to replace
  • with: give a string to replace regexp pattern
  • suffix: something to follow the last "/", eg. smx

    And all the while you can shuffle up and down using the ReadLine command history...
  • #!/usr/bin/perl -w use strict; use Term::ReadLine; # for correction and command history you must have # Term::ReadLine::Gnu (from CPAN) installed my $term = new Term::ReadLine 'regexp Smode'; my $pr1 = "string: "; my $pr2 = "replace: "; my $pr3 = "with: "; my $pr4= "suffix: "; my $OUT = $term -> OUT || *STDOUT; my $output; while (1) { my $string = $term -> readline($pr1); my $replace = $term->readline($pr2); my $with = $term->readline($pr3); my $suffix = $term->readline($pr4); eval{ eval "(\$output = \$string) =~ s/\$replace/\$with/$suffi +x" }; print $OUT "$output\n"; }
regexp for directory
on Mar 17, 2008 at 10:05
1 reply by halfcountplus
    this is really not much more (and less) use than plain ol' grep, but i want to use it as the basis for a GUI code scanner/viewer. It is set to check only .pl files, and requires a regexp on the command-line to work. The output (linux) is exactly what my_nihilist describes below.

    I believe McDarren, FunkyMonk, and even sort of ikegami helped me with their feedback to ranking number of occurances and Counting in regular expressions. One of several modifications courtesy of toolic, below, lead me to eliminate an unnecessary while loop (strange...) about line 22; i left the loop in comments for those who might also find it's unnecessity worth noting.

    However, it did work just fine to begin with, toolic not withstanding. There is no planet on which i would post code that i hadn't tested.

    Update #2: see my final note below, in which i take Fletch and toolic's advices about variable names and whitespace.
    #!/usr/bin/perl -w use strict; my $regexp = $ARGV[0] || die "\nREQUIRES COMMAND-LINE ARGUMENT\n"; my $dir; if (defined($ARGV[1])) {$dir = $ARGV[1]} else {$dir = `pwd`} chomp $dir; print "\"$regexp\" in $dir/*.pl:\n"; my (%N_index, @files); opendir(DIR, $dir) || die "can't open $dir"; @files = readdir(DIR); closedir(DIR); foreach my $pl (@files) { if ($pl =~ /\.pl$/) { my $content; open (PL, "<$dir/$pl") || die "can't open $dir/$pl"; #while (<PL>) { $content = do {local $/; <PL>}; #} that was the deleted "while loop" close (PL); my $N; if ($content =~ /$regexp/) { $_=$content; $N =()= /$regexp/g; $N_index{$pl}=$N; } } } my @rank = sort {$N_index{$b} <=> $N_index{$a}} keys %N_index; foreach (@rank) {print "\t$N_index{$_} -- $_\n";}
mainframe screen - PCOMM - EHLLAPI
on Mar 14, 2008 at 10:42
0 replies by jeepj

    as I mentioned in Interact with mainframe screen, I am using the OLE interface of IBM Personal Communications 3270 emulator to perform automated tasks on a mainframe. However, some sessions get stuck when 3 or 4 sessions are used in parallel. So I tried to find another way...and I found it. Starting at version 4.1 or 4.3 (don't know exactly), a DLL EHLAPI.dll is provided with PCOMM to interface C or Java applications with the emulator, and I also found Win32::API.

    Once everything is put together, I managed to have some interaction between Perl script and the 3270 emulator with the following code.It is a just a simple one, but works, and shows an increase speed execution(and hopefully less buggy).

    use strict; use Win32::API; print "Getting API function\n"; my $hllapi = new Win32::API('D:/PC3270W/EHLAPI32.dll', 'hllapi', ['P', +'P','P','P'], 'N'); die("oups not created") unless(defined($hllapi)); print "Connecting to session A"; my $fct=pack('L', 1); my $connBuffer="A"."\0" x 3; my $connBufferLen = pack('L', 4); my $returnCode=pack('L',13); $hllapi->Call($fct,$connBuffer,$connBufferLen,$returnCode); my $ret=unpack('L',$returnCode); print "return code -$ret-\n"; die("oups") if($ret != 0); print "Trying sendkeys - JD\n"; $fct=pack('L', 3); my $keys='JD@E'; my $keysLengh=pack('L', 4); $hllapi->Call($fct,$keys,$keysLengh,$returnCode); print "Waiting for command to be finished\n"; $fct=pack('L',4); my $a="\0"; my $b=pack('L',0); my $rc=pack('L',0); $hllapi->Call($fct,$a,$b,$rc); print "Reading screen\n"; $fct=pack('L',8); my $readBuf= "\0" x 3000; my $lenToRead=pack('L',1920); my $offset=pack('L',1); $hllapi->Call($fct,$readBuf,$lenToRead,$offset); for(my $k=0;$k<24;$k++){ my $offset=$k*80; print substr($readBuf,$offset,80)."\n"; } print "\n"; exit(0);
Module::Install and Debian packages
on Mar 12, 2008 at 17:00
1 reply by dpavlin
    How many times did you wanted for Module::Install to just install available Debian packages and THEN use CPAN? I did several times. Here is quick diff to Module::Install::AutoInstall which does just that...
    --- /home/dpavlin/.cpan/build/Module-Install-0.68/lib/Module/Install/A +utoInstall.pm 2007-10-31 11:34:27.000000000 +0000 +++ /usr/local/share/perl/5.8.8/Module/Install/AutoInstall.pm 2008-0 +3-12 20:58:01.000000000 +0000 @@ -30,6 +30,15 @@ my @core = map @$_, map @$_, grep ref, $self->build_requires, $self->requires; + my @debs; + while ( my $module = shift @core ) { + my $ver = shift @core; + my $deb = 'lib' . lc($module) . '-perl'; + $deb =~ s/::/-/g; + push @debs, $deb; + } + system "sudo apt-get install @debs"; + my @config = @_; # We'll need Module::AutoInstall
ReadLine regexp quicktest
on Mar 11, 2008 at 12:53
1 reply by halfcountplus
    This is a very quick way way to check if a regexp will work the way one wants. It uses Term::Readline::Gnu so you get a command history (as in bash), simplifying repetative experiments. If anyone can find a string/regexp which doesn't work properly please comment. I imagine it will best serve beginners like myself in understanding things like, eg. that "7463" contains "\w", or that anything could contain "X*".

    a version of ReadLine regexp quicktest using substitution (s/) is regexp s/mode quicktest
    #!/usr/bin/perl use warnings; use strict; use Term::ReadLine; # for correction and command history you must have # Term::ReadLine::Gnu (from CPAN) installed my $term = new Term::ReadLine 'regular expression test'; my $pr1 = "string: "; my $pr2 ="regexp: "; my $OUT = $term->OUT || *STDOUT; while (1) { my $st=$term->readline($pr1); my $rg=$term->readline($pr2); if ($st =~ /$rg/) {print $OUT "$st contains $rg\n"} else {print "$st does not contain $rg\n"} }
split file in N part
on Mar 10, 2008 at 06:41
2 replies by jeepj

    Hello, here is a little function (split_file) which split a file into a given number of part. This is quite simple code, but ease the dispatching of a list of reference to be handled by several jobs running in parallel.

    Of course, I am not a Perl expert, and any advise on doing it in a fancier or more efficient way is welcome

    The function is called with two arguments, the name of the file, and the number of files to create. The countLines subroutine is called to count the number of lines in a file.

    Of course, I am quite new to perlmonks, so If you find that this has nothing to do here, just tell me.

    Updates:

    sub countLines { my $filename=shift(@_); die("amaUtils:countLines:invalid filename") if(length($filename)== +0); open(TMP,"<$filename") or die("amaUtils:countLines unable to open +file $filename"); my $nb=0; $nb += tr/\n/\n/ while sysread(TMP, $_, 2 ** 16); close TMP; return $nb; } sub split_file { my $filename=shift(@_); my $nbFiles=shift(@_); die("amaUtils:split_files invalid number") if($nbFiles !~ /^\d+$/) +; die("amaUtils:split_files invalid number") if($nbFiles < 1); my $curNb=1; my $totalCount=countLines($filename); my $nbLinesPerFile=int($totalCount/$nbFiles); $nbLinesPerFile++ if( ($nbLinesPerFile * $nbFiles)!=$totalCount); my $currentCount=0; open(ORIG,"<$filename"); my ($newfile,$ext)=split(/\./,$filename); open(DEST,">${newfile}_".sprintf("%02d",${curNb}).".$ext"); while(<ORIG>) { if($currentCount==$nbLinesPerFile) { close DEST; $curNb++; $currentCount=0; open(DEST,">${newfile}_".sprintf("%02d",${curNb}).".$ext") +; } print DEST $_; $currentCount++; } close DEST; close ORIG; }
Tk Virtual Keyboard
on Feb 26, 2008 at 15:34
1 reply by zentara
    This mimics the javascript virtual keyboards, which are commonly being used by online banks, to avoid keystroke loggers, when entering passwords. It's just the basic model. I still need to run tests on it to see if the letters and passwords can be kept more hidden. But if you ever wanted to play with something like this, but didn't want to go thru all the hassle of building the keyboard...... here is one for you.

    The big font I use, makes the script take significantly longer to start up, but is worth it for ease of letter reading.

    #!/usr/bin/perl use warnings; use strict; use Tk; # an 8 x 13 grid my @keys = ( '~','`','!','@','#','$','%','^','&','*','(',')','_', '1','2','3','4','5','6','7','8','9','0','-','+','=', 'Q','W','E','R','T','Y','U','I','O','P','{','}','"', 'q','w','e','r','t','y','u','i','o','p','[',']','\'', 'A','S','D','F','G','H','J','K','L',':','|','\\','/', 'a','s','d','f','g','h','j','k','l',';','<','>','?', 'Z','X','C','V','B','N','M','BackSpace','dummy','dummy','dummy','dummy +','dummy', 'z','x','c','v','b','n','m','.','Clear','dummy','dummy','dummy','dummy +'); #print "@keys\n"; my $mw=tkinit; $mw->fontCreate('big', -family=>'arial', -weight=>'bold', -size=>int(-18*18/14)); my $tframe = $mw->Frame()->pack(-expand=>1,-fill=>'both'); my $passwd = ''; my $label = $tframe->Label(-text => "Password: ", -font => 'big', )->pack(-side=>'left'); my $entry = $tframe->Entry( -show => '*', -textvariable => \$passwd, -bg => 'black', -fg => 'white', -font => 'big', )->pack(-side=>'left',-expand=>1,-fill=>'x', -padx=> 5); my $submit = $tframe->Button( -text=>'Submit', -font => 'big', -bg => 'yellow', -activebackground => 'hotpink', -command => \&submit, )->pack(-side=>'right',-expand=>1,-fill=>'x', -padx=> 5); for my $row (1..8){ my $frame = $mw->Frame()->pack(-expand=>1,-fill=>'both'); for my $col (1..13){ my $l = shift @keys; if($l eq 'dummy'){next}else{ $frame->Button(-text=> $l, -bg => 'beige', -activebackground => 'lightyellow', -font => 'big', -command => [\&process_key, $l], )->pack(-side=>'left',-anchor=>'w', -expand=>1,-fill= +>'both'); } } } MainLoop; ##################### sub process_key{ my $key = shift; print "$key\n"; if ($key eq 'Clear'){$passwd = '';} elsif ($key eq 'BackSpace'){ chop $passwd;} else{ $passwd .= $key;} } ##################### sub submit { print $entry->get(),"\n"; $entry->delete(0,'end'); }
Insert something like a hyperlink in a Tk Text widget
on Feb 12, 2008 at 13:09
1 reply by jdporter
    Given a Tk::Text widget, insert a string at the current insert location which is "active", i.e. when clicked, executes some function. Actually, the behavior of the "link" is defined by the caller in terms of Tk events. Clicking (<ButtonPress>) is merely one such possibility.
    { my $hypertext_tag_name = 't000000'; # candidate for 'static' # returns the tag name, in case there's anytyhing else # you'd like to do with it. sub Tk_Text_insert_active_text { my( $Text, $linktext, %callbacks ) = @_; my $start_index = $Text->index( 'insert' ); $Text->insert( insert => $linktext ); my $end_index = $Text->index( 'insert' ); my $link_tag_name = ++$hypertext_tag_name; $Text->tagAdd( $link_tag_name, $start_index, $end_index ); $Text->tagConfigure( $link_tag_name, -foreground => 'blue', -under +line => 1 ); $Text->tagBind( $link_tag_name, $_ => $callbacks{$_} ) for keys %c +allbacks; $link_tag_name } } # Example: make a real link: sub Tk_Text_insert_hyperlink { my( $Text, $url, $title ) = @_; Tk_Text_insert_active_text( $Text, $title, '<ButtonPress>' => sub { system $url }, # launch in system bro +wser '<Enter>' => sub { set_status_bar($url) }, '<Leave>' => sub { set_status_bar('') }, ); }
cmp two HTML fragments
on Feb 09, 2008 at 15:54
2 replies by GrandFather

    I had a need to compare two fragments of HTML to see if they were equivalent.

    This snippet builds two HTML::TreeBuilder representations of the fragments, then recursively compares the contents of the fragments.

    To use the snippet call cmpHtml passing the two fragments as strings:

    print cmpHtml( '<p><font foo="bar" bar="1">bar 1</font></p>', '<p><font bar="2" foo="bar">bar 1</font></p>' );

    or if you already have two HTML::Elements that you want to compare you can:

    print cmpHtmlElt ($elt1, $elt2);
    sub cmpHtml { my ($html1, $html2) = @_; my $root1 = HTML::TreeBuilder->new; my $root2 = HTML::TreeBuilder->new; $root1->parse_content ($html1); $root1->elementify (); $root2->parse_content ($html2); $root2->elementify (); return cmpHtmlElt ($root1, $root2); } sub cmpHtmlElt { my ($elt1, $elt2) = @_; my $cmp = defined $elt1 cmp defined $elt2; return $cmp if $cmp; return 0 unless defined $elt1; $cmp = ref $elt1 cmp ref $elt2; return $cmp if $cmp; return $elt1 cmp $elt2 unless ref $elt1; $cmp = $elt1->tag () cmp $elt2->tag (); return $cmp if $cmp; my %attribs1 = $elt1->all_attr (); my %attribs2 = $elt2->all_attr (); $cmp = keys %attribs1 <=> keys %attribs2; return $cmp if $cmp; for my $key (keys %attribs1) { return 1 unless exists $attribs2{$key}; next if $key =~ /^_/; $cmp = $attribs1{$key} cmp $attribs2{$key}; return $cmp if $cmp; } my @children1 = $elt1->content_list (); my @children2 = $elt2->content_list (); $cmp = @children1 <=> @children2; return $cmp if $cmp; for my $index (0 .. $#children1) { $cmp = cmpHtmlElt ($children1[$index], $children2[$index]); return $cmp if $cmp; } }