Showing posts with label perl5. Show all posts
Showing posts with label perl5. Show all posts

Friday, April 29, 2011

Dude, what function am I in?

The ctags plugin for vim shows the function name containing the current line. This is helpful when you're refactoring down functions that are longer than a screenful.

I've been using this (exuberant) ctags based approach for years. It's quite handy and works across more languages than I use: 41 languages from ant to YACC. I've tested with perl, python, C, java and ruby.

The plugin has options to display the function name in the status bar or in the xterm menu bar. It takes care of generating the ctags files on the fly.

I've blogged before on using vim with tags file, recommending using ctags to create a tags file for your codebase. Using the tags browser to jump to subroutines defined in other files is just ... super fun.

ctags plugin for vim:
http://www.vim.org/scripts/script.php?script_id=610
exuberant ctags:
http://ctags.sf.net/
My blogpost on effective VIM with perl and tags. http://www.lowlevelmanager.com/2010/12/perl-tags-and-vim-effective-code.html

These are the options I use with the plugin:

  let g:ctags_statusline=1
  let g:ctags_title=0
  let g:generate_tags=1 
  let g:ctags_regenerate=1

PS. OSX comes with a different version of ctags, you'll need to install exuberant ctags for the ctag plugin to work, it's available in both fink and MacPorts.

Wednesday, April 27, 2011

More LWP SSL 500 issues! Now with HTTP::DAV crossover

LWP::UserAgent is returning a 500 level error in the case of a self-signed site key. This is similar to my previous post on this topic, ( Fixed 500 can't verify SSL peers ):
For https://... default to verified connections with require IO::Socket::SSL and Mozilla::CA modules to be installed. Old behaviour can be requested by setting the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0. The LWP::UserAgent got new ssl_opts method to control this as well.
I use HTTP::DAV to push changes to the Los Angeles Perl Mongers website. When I tried to push updates for tonight's meeting, HTTP::DAV threw an error " The URL "https://groups.pm.org/groups/losangeles/" is not DAV enabled or not accessible.".

This seemed familiar -- in fact I filed a bug against HTTP::DAV ( Bug 59674 ) to pass through SSL errors from LWP when SSL libraries were not installed. ( Cosimo, I am sorry that I didn't respond in a timely manner when the fixes were proposed. Thanks for fixing it!). The fix for 59674 included having a specific message for various classes of errors out of LWP::UserAgent.

## Error conditions
my %err = (
    'ERR_WRONG_ARGS'    => 'Wrong number of arguments supplied.',
    'ERR_UNAUTHORIZED'  => 'Unauthorized. ',
    'ERR_NULL_RESOURCE' => 'Not connected. Do an open first. ',
    'ERR_RESP_FAIL'     => 'Server response: ',
    'ERR_501'           => 'Server response: ',
    'ERR_405'           => 'Server response: ',
    'ERR_GENERIC'       => '',
);

LWP::UserAgent is returning a 500 level error in the case of a self-signed site key. Not 501 as in the prior case.

Example:

#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use Data::Dumper;
my $url = "https://groups.pm.org/groups/losangeles";
my $ua=LWP::UserAgent->new();
my $resp = $ua->get( $url );
print Dumper $resp;
Output Snippet:
LWP::Protocol::https::Socket: SSL connect attempt failed with unknown errorerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed at /Library/Perl/5.10.0/LWP/Protocol/http.pm line 51.

One can get around this by setting an environment variable export PERL_LWP_SSL_VERIFY_HOSTNAME=0, or by using the ssl_opts option to UserAgent. A third, preferred solution would be import the key and mark it as "OK" on the client side.

I pushed my website changes by using the PERL_LWP_SSL_VERIFY_HOSTNAME=0 workaround. Now let's see if I can figure out workarounds 3 and 2.

Saturday, March 12, 2011

Vroom - vim overrides and mapping for presentation remote

The second best thing about using Vroom (Formerly Vroom::Vroom ) for presentations is hearing, "I've never seen a presentation in vim before." The best thing is using vim as both the editing and display platform.

I realized yesterday while cramming to finish my "intro to git" presentation for work that my recently added vim plugin "magic space" (space.vim) interferes with the default Vroom vimrc bindings. Space.vim rebinds space in a variety of ways to repeat the previous movement commands (search, movement, etc).

Disabling the plugin took a couple of iterations because the documentation was incorrect -- it references loaded_space while the code was checking space_loaded. Actually, the documentation was correct, but the comments in the plugin code are incorrect. I opened a ticket, cloned the github repo, pushed the changes, and updated the ticket with a pull request via git request-pull. Not bad for 5 minutes.

This encouraged me to expand my Vroom knowledge. First, I found the syntax for adding a vimrc override to my presentation. Today, I created a user specific vroom vimrc override in $HOME/.vroom/vimrc to disable magic space when I'm running Vroom presentations.

Since I was already adding custom configuration, I dug out my nerdnite presentation remote and found that the buttons are mapped to PageUp, PageDown and b. These are what powerpoint use for previous page, next page and blank screen. They aren't particularly useful while presenting in vim, so I remapped them in the vroom override to previous and next file.

You think people are shocked by a presentation in vim? Wait until you pull out your laser pointer remote to advance the slides. priceless.

My Intro to Git vroom presentation
https://github.com/spazm/presentations/tree/master/open42-git-intro
Vroom vimrc override file:
https://github.com/spazm/config/blob/master/vroom/vimrc
vim-space
https://github.com/spiiph/vim-space
my fork with fix for issue 8
Issue 8

"" Custom .vimrc overrides for Vroom
"" These will be automatically added to all 
"" vroom autogenerated .vimrc files

" disable space.vim during Vroom presentations.
" in my version of space.vim the docs refer to
" g:loaded_space, but the code checks g:space_loaded
let g:space_loaded = 1

" My presentation remote has three buttons
" forward: sends PageDown
" back:    sends PageUp
" blank:   sends b
" Bind PageUp to previous doc and PageDown to next doc
map  :N:gg
map  :n:gg
" map b ???

Tuesday, January 11, 2011

SCALE presentation proposals : denied.

Sigh, Neither of my modern perl SCALE proposals were accepted -- dev track proposals for hands on demonstrations of using Hadoop Streaming with Big Data and quickly building web applications with Dancer. I hope we get an perl mongers booth/table.

I'm glad to hear there were so many presentation proposals. Sounds like we'll have some great talks!

Dear Speaker,

The SCALE committee has reviewed your proposal(s). Unfortunately, your proposal, while excellent, was not accepted. SCALE again had many high quality submissions, so we could only accept a small fraction of those submitted (47 out of 160 submissions).

We thank you for your interest in SCALE and we appreciate your submittal! We hope you'll participate in future SCALE events. The latest updates for the conference are available at http://www.socallinuxexpo.org

Sunday, December 19, 2010

Perl 2011: Where are we now?

Piers Cawley wrote an excellent forward looking piece The Perl Future in January 2009. As we approach the two year mark, how have we fared? He talks about perl 6, perl 5.10.0, aka "perl5 version 10," Perl Enlightenment & the rise of Moose, and "on frameworks and the future."

Where are we now?

Perl 5.12 is out, as scheduled, on time -- two years of work representing 750,000 lines of changes over 3000 files and 200 authors. Deprecated features of perl4&5 are finally marked as such. More Unicode improvements. Features improvements for the Y2038 bug (is epoch time 64 bit now ?) Includes pluggable keywords and syntax. A new release schedule means stable releases come out in the spring, followed by a .1 fix release, then monthly releases (on the 20th) for new bug fixes.

Perl 6 released a real, honest to goodness release candidate. Rakudo Star, "A useable perl6 release" was released in June, aimed at "Perl 6 early adopters." Rakudo star has seen monthly updates, most recently Rakudo Star 2010.11 released in November 2011. Rakudo Perl is a specific implementation of Perl 6 the language, this Rakudo Star 2010.11 release includes "release #35 of the Rakudo Perl 6 compiler, version 2.10.1 of the Parrot Virtual Machine, and various modules, documentation, and other resources collected from the Perl 6 community."

A year-and-a-half of the Perl Iron Man blogging project has seen a flurry of posts from nearly 250 perl bloggers! We've seen advocacy, snippets, whining, and community. I've seen a lot more Japanese language perl posts -- folks happy to use perl, python and ruby and pull the best from each.

I now find it strange and unsettling to meet self proclaimed perl programmers who don't use Moose. If you haven't played with it (and it does feel like playing, it's liberatingly fun), go do so now. I'll wait.

I don't know about you, but I just switched from one startup using perl to another startup using perl. Awesome perl folks are hard to find, they're mostly already busy doing work they love. Why are we using perl? -- because perl works, it scales with developer time, and perl is beautiful.

Piers mentioned frameworks -- yes individual frameworks are important but the vast armada of options available at CPAN as a whole provide an immense multiplier on developer productivity. It's so massive, it is easy to overlook -- Doesn't everyone have a massive, distributed, user-written body of code with excellent testing methodology available at the touch of a button?

Merry Christmas to all!

[...snip...]
However, if you look at the good parts (O'Reilly haven't announced "Perl: The Good Parts", but it's a book that's crying out to be written), there's a really nice language in there. Arguably there's at least two. There's the language of the one-liner, the quick throwaway program written to achieve some sysadmin related task, and there's the more 'refined' language you use when you're writing something that is going to end up being maintained.

I think it's this split personality that can put people off the language. They see the line noise of the one liner school of programming, the games of Code Golf (originally called Perl golf, the idea spread), the obfuscated Perl contests, the terrible code that got written by cowboys and people who didn't know any better in the dotcom bubble (you can achieve an surprising amount with terrible Perl code, but you will hit the wall when you try and change it) and they think that's all there is.

But there is another Perl. It's a language that runs The Internet Movie Database, Slashdot, Booking.com, Vox.com, LiveJournal and HiveMinder. It's a language which enables people to write and maintain massive code-bases over years, supporting developers with excellent testing and documentation. It's a language you should be considering for your next project. It's also something of a blue sky research project - at least, that's how some people see Perl 6.

----http://www.h-online.com/open/features/Healthcheck-Perl-The-Perl-Future-746527.html

Friday, October 8, 2010

GRT : Guttman Rosler Transform

The Guttman-Rosler Transform is a technique from Uri Guttman and Larry Rosler for improving sort speed in perl.

The Guttman-Rosler transform runs faster than the orcish or Schwartzian transforms by avoiding the use of custom search subroutines. This is accomplished via pre and post transformation of the list. This allows the native optimizations of the perl sort function to shine.

Sort::External has a special affinity for the GRT or Guttman-Rosler Transform, also known as the "packed-default" sort. The algorithm is examined at length in "A Fresh Look at Efficient Perl Sorting", a paper by Uri Guttman and Larry Rosler, located as of this writing at http://www.sysarch.com/perl/sort_paper.html.

For many applications, the GRT is the most efficient Perl sorting transform. This document explores how to use it to solve common coding problems in conjunction with either Perl's built-in sort() function or Sort::External.

-- Sort::External::Cookbook

Synopsis:
  1. prefix each element with a synthetic key (string or numeric).
  2. sort.
  3. remove the prefix key from each element.

Example:

    
    my %colors = (
        "Granny Smith"     => "green",
        "Golden Delicious" => "yellow",
        "Pink Lady"        => "pink",
    );

  #A) standard sort:
    my @sorted_by_color = sort { $colors{$a} cmp $colors{$b} } keys %colors;

  #B) GRT sort:
    # 1. Encode
    my @sortkeys;
    while ( my ( $variety, $color ) = each %colors ) {
        push @sortkeys, sprintf( "%-6s%-16s", $color, $variety );
    }
    # @sortkeys = (
    #     "green Granny Smith    ",
    #     "yellowGolden Delicious",
    #     "pink  Pink Lady       ",
    # );

    # 2. Sort
    my @sorted_by_color = sort @sortkeys;    # no sortsub!

    # 3. Decode
    @sorted_by_color = map { substr( $_, 6 ) } @sorted_by_color;

Links:

Research Paper from Uri Guttman and Larry Rosler:
http://www.sysarch.com/Perl/sort_paper.html
Sort Sort::Maker on cpan:
http://search.cpan.org/perldoc?Sort::Maker
Sort::External::Cookbook
Http://Search.cpan.org/perldoc?Sort::External::Cookbook

Tuesday, July 20, 2010

Hadoop::Streaming module updated and awesome

Verison 0.101881 of my Hadoop::Streaming module is released on CPAN.

This is a bug fix release -- fixing bugs in my test suite! I had problems with errors from the smoke testers, even though it all "worked for me." To fix this I wrote my tests in a sane manner, so they weren't held together by "gravity and good luck." See Bug #59164 for the gory details. 

I'm happy and proud to report that version 0.101881 has 81 PASS and 0 FAIL results from cpants!

Now all I need is a well written tutorial on how to use it.

links
Bug #59164 for Hadoop-Streaming: Test failures on a variety of platforms
https://rt.cpan.org/Public/Bug/Display.html?id=59164
Hadoop::Streaming Module
Documentation
http://search.cpan.org/perldoc?Hadoop::Streaming
Module Overview:
http://search.cpan.org/search?q=Hadoop::Streaming
Test Reports:
http://www.cpantesters.org/show/Hadoop-Streaming.html#Hadoop-Streaming-0.101881
Open Bugs (0!):
https://rt.cpan.org/Public/Dist/Display.html?Name=Hadoop-Streaming
Git Repo:
http://github.com/spazm/hadoop-streaming-frontend

morning reading: Getopt::Long::Descriptive (GLD) and App::Cmd

"Getopt::Long::Descriptive - Getopt::Long, but simpler and more powerful"
given a descriptive getopt argument, returns a usage summary and an object containing set options.
I am a fan of this less is more approach of "simpler AND more powerful."
Getopt::Long::Descriptive
"App::Cmd - write command line apps with less suffering"
Simplify writing command line apps by breaking functionality into module(s) with a minimal runner script. Makes extending command line apps easy by adding additional sub-modules.
Uses Getopt::Long::Descriptive.
App::Cmd

Have you ever asked "why do I have to document my command line options twice? once in the usage command and once in the Getopt statement?" I know I was asking just last week at the Thousand Oaks Perl Mongers meeting. If you don't ask, is it because you consider your Getopt command documentation? We discussed and compared various Getopt alternatives: Getopt::Long, Getopt::Euclid, Getop::Clade, etc.

One interesting solution is Getopt::Euclid. Euclid parses specially formatted pod commands to create the Getopt configuration. This is an awesome idea, but leaves me with two problems: 1) There is an extra step to create this parsing setup, and that means I can't test the exact code that my user will see. 2) it employs a source filter which freaks me out. Perhaps the source filter has been upgraded to use one of the PPI parsing modules instead, that would be less scary than the black magic happening in source filters.

GetOpt::Long::Descriptive (GLD) is built on Getopt::Long and takes a more verbose/descriptive input format. It outputs a usage command and an object containing options and values. Unlike Euclid, it doesn't read or create perldoc/POD.

I think adding a podweaver+Getopt::Long::Descriptive plugin would be interesting. Creating a nicely documented POD section during the dzil build step of my Dist::Zilla based modules would be a big win. I just browsed the code for Getopt::Long::Descriptive::Usage, and it looks like adding a weaver transform would be possible, if I could figure out how to extract the usage code from the module during the build step. This may be easier to visualize once I start investigating App::Cmd.

Example
From the SYNOPSIS section:

use Getopt::Long::Descriptive;

my ($opt, $usage) = describe_options(
    'my-program %o ',
    [ 'server|s=s', "the server to connect to"                  ],
    [ 'port|p=i',   "the port to connect to", { default => 79 } ],
    [],
    [ 'verbose|v',  "print extra stuff"            ],
    [ 'help',       "print usage message and exit" ],
);
print($usage->text), exit if $opt->help;
Client->connect( $opt->server, $opt->port );
print "Connected!\n" if $opt->verbose;

...and running my-program --help will produce:

  my-program [-psv] [long options...] 
    -s --server     the server to connect to
    -p --port       the port to connect to
                  
    -v --verbose    print extra stuff
    --help          print usage message and exit

I'm quite fond of how s|server became -s --server, showing both the long and short form of the arguments.

Go play with these modules and let me know if you start using them. Many thanks to their Authors for sharing their work on CPAN. You guys rock. I'm going to start using these modules and will report back when I have a better feel for them. This will likely become a future topic for the Los Angeles Perl Mongers (LAPM).

Links:

Getopt::Long::Descriptive
http://search.cpan.org/perldoc?Getopt::Long::Descriptive
App::Cmd
http://search.cpan.org/perldoc?App::Cmd
Getopt::Euclid
http://search.cpan.org/perldoc?Getopt::Euclid
Dist::Zilla
http://search.cpan.org/perldoc?Dist::Zilla
Pod::Weaver
http://search.cpan.org/perldoc?Pod::Weaver
PPI documentation
http://search.cpan.org/perldoc?PPI
Los Angeles Perl Mongers
la.pm.org
Thousand Oaks Perl Mongers
http://thousand-oaks-perl.org

Tuesday, July 6, 2010

Do you have CPAN::Reporter installed? Go do it!

Do you have CPAN::Reporter installed? Did you maybe not know what it is, what it does, and why it's the easiest way to help the perl+cpan community? CPAN::Reporter sends back test results every time you download a module from CPAN. This gives module authors something tangible to know that people are using their modules and to automatically report errors.
Now anyone with an up-to-date CPAN.pm can contribute to CPAN Testers -- no smoke server needed.
...
Becoming a CPAN Tester with CPAN::Reporter is easy. From the CPAN shell prompt:

cpan> install CPAN::Reporter
cpan> reload cpan
cpan> o conf init test_report
cpan> o conf commit

  --  http://use.perl.org/articles/06/11/08/1256207.shtml

My Hadoop::Streaming module has all sorts of crazy errors on esoteric platforms. I only know this because of automated smoke tests run by CPANTesters. It would be nice to have some reports from actual users mingled in with the automated runs.

In the latest release I pushed out over Independence Day weekend, I added monitoring on STDERR from my sub-command tests. Now I have some test results that capture error messages from external apps I try to run from my tests. At least now I have a chance of figuring them out... not sure I understand these error messages yet. Maybe they'll make more sense tomorrow. I'd like to make it so all my users see this output from cpan:


All tests successful.
Files=5, Tests=12, 2 wallclock secs ( 0.05 usr 0.00 sys + 2.04 cusr 0.20 csys = 2.29 CPU)
Result: PASS
(/usr/bin/make test exited with 0)
CPAN::Reporter: Test result is 'pass', All tests successful.
CPAN::Reporter: preparing a CPAN Testers report for Hadoop-Streaming-0.100270
CPAN::Reporter: sending test report with 'pass' to cpan-testers@perl.org

Friday, June 11, 2010

ubuntu 10.4 + perl 5.10.1 => personal config moved to .local/share/.cpan

The personal .cpan directory for perl 5.10.1 under ubuntu 10.4 has moved from $HOME/.cpan to $HOME/.local/share/.cpan. I was very confused to get messages about not being able to write to /root/.cpan/build when I knew I had that overridden in my personal configuration file.

Once I found this new location, I was able to delete the new .cpan directory and replace it with a symlink to my old ~/.cpan. Now I can get back to building modules as a non-privileged user into a local::lib based configuration.

Delete empty new .cpan directory and replace with a symlink to my old .cpan:
rm -rf $HOME/.local/share/.cpan && ln -s $HOME/.cpan $HOME/.local/share/

Thursday, May 20, 2010

Perl Survey is Live!

Perl: solving your problems since 1987
--me

From: Kieren Diment

The Perl Survey 2010 is now live. Its purpose is to better understand the demographics and opinions of the Perl community. You can complete the survey at http://survey.perlfoundation.org - it should take about 10 to 15 minutes.

Once you've done that, please let your relevant friends and colleagues know about the survey so they can complete it as well. My aim is to get a response of over 1000 individuals, and to run the survey (lightly adapted) every two or three years so we can see how the community changes over time. The official announcement of the survey is here:

http://news.perlfoundation.org/2010/05/grant-update-the-perl-survey-1.html


My notes:
  1. This is a well put together survey that looks like it has a good methodology, not just a survey-monkey one-off. It'll take a good 15-20 minutes.
  2. captcha required (boo)
  3. The survey is a bit clever with jscript/html and prevented me from filling it out on my iphone browser.

Tuesday, April 27, 2010

Powerpoint considered harmful

Enemy Lurks in War Briefings - PowerPoint - NYTimes.com
We Have Met the Enemy and He Is PowerPoint

Military commanders are concerned that computer-generated charts and bullet point lists stifle discussion, critical thinking and thoughtful decision-making, as well as take up too much time.
[...]
“It’s dangerous because it can create the illusion of understanding and the illusion of control,” General McMaster said in a telephone interview afterward. “Some problems in the world are not bullet-izable.”
[...]
Senior officers say the program does come in handy when the goal is not imparting information, as in briefings for reporters.

Source: http://www.nytimes.com/2010/04/27/world/27powerpoint.html



Death by Powerpoint blogpost expands on the comments at the end of the times article about the 2006 allegations that Tommy Franks sent battle plans by powerpoint. Would this slide help you plan for combat?

Grousing about the destructive nature of powerpoint on presentation skills is not new. Yet, I hadn't realized how much powerpoint style programs are being used outside of presentation space to replace technical documentation and scientific reports.


Edward Tufts has written two editions of The Cognitive Style of PowerPoint: Pitching Out Corrupts Within. In PowerPoint Does Rocket Science--and Better Techniques for Technical Reports he asks a difficult question, Did powerpoint make the Space Shuttle crash?. The comments on that article are of unusually high quality. I read through them all with a sense of building anticipation. This meme is riffed upon in a washington post article, PowerPoint: Killer app.

What to do?

Find a method of presentation that minimizes impedance mismatch with your audience and your data. Tuft recommends a one duplex 11x17 paper for a 3 hour talk. Find a way to present idea and defend it with data that works for you.

A commenter recommended The A3 Method of report generation (named for A3 sized paper (equivalent to US B sized 11 x 17 )) presentation style adapted from practices as Toyota.
In Tuft's workshops, [he] describes how to replace PowerPoint presentations with 11 x 17 sized reports, and provides many good arguments for why "engineering by PowerPoint" doesn't work very well.
Tuft replies warning that this may just be a BMF: Business Methodology Fad:
In the Beautiful Evidence chapter on corrupt techniques in evidence presentations, the section on over-reaching concludes with this: "When a precise, narrowly focused technical idea becomes metaphor and sprawls globally, its credibility must be earned afresh locally by means of specific evidence demonstrating the relevance and explanatory power of the idea in its new application." (p. 151)


Anytime you pare down your presentation to fewer words and fewer pictures, you have an opportunity to reduce fluff and focus on the primary point of the presentation. Practice examples include turning a 5 minute talk into a 30 second elevator pitch. What do you keep? Once you've pared it down to 30 seconds, expand it back to 5 minutes by including explanatory details. (Expanding it back will be even more difficult than slimming it down).

NEED 2-PAGE SHORT STORY TWO DAYS.

Mark Twain replied:
NO CAN DO 2 PAGES TWO DAYS. CAN DO 30 PAGES 2 DAYS. NEED 30 DAYS TO DO 2 PAGES.

If you're going to be trapped using powerpoint, you might as well learn to use it well via a book like Beyond Bullet Points
. Science daily has an article on how to report scientific research to a general audience
Extreme Presentation claims to be extreme. I have a couple more presentation books on my bookshelf, e.g.: Present Like a Pro: The Field Guide to Mastering the Art of Business, Professional, and Public Speaking

[...] factor that constitutes my own violent objection to its prevalent use, that being that increased reliance on PP and other visual aids in education, training, project and crisis management fundamentally undermines the active involvement and cognitive engagement of the target audience/students/team members by converting the desemination of information to a passive presentation.

Kerry Parslow (email), February 9, 2007

It's easy to blame the tool ... but I think .ppt is just a symptom of something else. There are two sides: authentic presentation and authentic listening. We need both.

-- Dennis Allen, September 12, 2006
Don't forget your audience. You may utter as much as you'd like, but it isn't communication until your message is actively listened to by your audience. Until they've listened and you've agreed a plan for action and turned that into work items, it is at best good intentions.
"...it is the recipient who communicates. The so-called communicator, the person who emits the communication, does not communicate. He utters."

— Peter Drucker


Another approach is to free yourself completely from format by following the data. In this TED talk, Hans Rosling shows the best stats you've ever seen you'll find some amazing live visualization of world statistics. Find out more at his site Gapmind.org

Not to be outdone, The Gettysburg Address, power point edition.

Update:


Did I mention I write my perl mongers presentations in Vroom::Vroom, a perl + vim tool for presentations. It is very simplistic, I'd actually like to add some structured markup (markdown or similar) to give the slides a bit more clarity. (or do I just want some style and punch?). Presenting code in the my development environment means I'm not placing an unneccessary presentation layer between myself and my audience.
It doesn't just look like vi, it is vi.

"You look like you're presenting in vi or something," remarked a new attendee.
"Yeah, I'm presenting in VIM," I replied.

--Los Angeles Perl Mongers, March 2010 meeting.

I can interact live with the slides, run the code snippets, include external files and more: all with syntax highlighting. The presentations can be exported to the standard vim format or to a minimal web template. When displaying in gvim, you can even change the font!

Example slides in html or raw vroom formats.

Monday, March 22, 2010

Convert::Binary::C

I stumbled across a new module this morning, Convert::Binary::C. The premise is simple and clever: rather than manually maintaining pack/unpack statements to read/write data from C structs, use this module to parse the c header files and create the pack/unpack routines for you. Oh and it takes into account compiler settings too. For the Win!

I don't have anything to use this in right now. But when I do? Blammo!

DESCRIPTION ^

Convert::Binary::C is a preprocessor and parser for C type definitions. It is highly configurable and supports arbitrarily complex data structures. Its object-oriented interface has pack and unpack methods that act as replacements for Perl's pack and unpack and allow to use C types instead of a string representation of the data structure for conversion of binary data from and to Perl's complex data structures.

Actually, what Convert::Binary::C does is not very different from what a C compiler does, just that it doesn't compile the source code into an object file or executable, but only parses the code and allows Perl to use the enumerations, structs, unions and typedefs that have been defined within your C source for binary data conversion, similar to Perl's pack and unpack.

Beyond that, the module offers a lot of convenience methods to retrieve information about the C types that have been parsed.

Thursday, March 4, 2010

perlmonks

You gained 7 experience points. Maybe you should blog about it.
--perlmonks.org
Hey, when was the last time you were at Perlmonks.org? Go answer some questions, it'll remind you why you love perl so much.

Here I answer a fun classic unix programming question: How do I change settings in my shell from a program?, with the general answer of "no." Has anyone actually gone through the windy path I mention of manually poking into the memory space of the parent shell to change settings? Totally Grody, yet it'd be awesome in its peversity.

Division by zero isn't impossible, it's just really really hard
-- old blacker hovse quote about the Division by Zero suit (tm).

Tuesday, January 5, 2010

CPAN upload, ONE!

My very first CPAN upload is happening *RIGHT NOW*. go go gadget CPAN upload! And now off to sleep, really.


2010-01-05 13:26:15 $$23346 v1048: Info: Need to get uriid[S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz] (paused:333)
2010-01-05 13:26:15 $$23346 v1048: Info: Going to fetch uriid[S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz] (paused:619)
2010-01-05 13:26:15 $$23346 v1048: Info: Requesting a GET on uri [ftp://pause.perl.org/incoming/Hadoop-Streaming-0.100050.tar.gz] (paused:641)
2010-01-05 13:26:16 $$23346 v1048: Debug: ls[-rw-rw-r-- 1 root root 16457 2010-01-05 13:26 /home/ftp/tmp/S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz
]zcat[/bin/zcat]tpath[/home/ftp/tmp/S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz]ret[]stat[2057 470407906 33204 1 0 0 0 16457 1262694376 1262694375 1262694375 4096 40]: No child processes (paused:696)
2010-01-05 13:26:16 $$23346 v1048: Info: Got S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz (size 16457) (paused:492)
2010-01-05 13:26:18 $$23346 v1048: Info: Sent 'has entered' email about uriid[S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz] (paused:555)
2010-01-05 13:27:43 $$23346 v1048: Info: Verified S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz (paused:304)
2010-01-05 13:27:43 $$23346 v1048: Info: Started mldistwatch for lpath[/home/ftp/pub/PAUSE/authors/id/S/SP/SPAZM/Hadoop-Streaming-0.100050.tar.gz] with pid[24954] (paused:309)
2010-01-05 13:27:53 $$23346 v1048: Debug: Reaped child[24954] (paused:64)

I think it should show up soon on my cpan page or perhaps the Hadoop::Streaming search.cpan page?

Hadoop Streaming - running a job

Logs from running a hadoop streaming job in a freshly set up environment
  1. copy input files
  2. run streaming jar (now located in contrib/streaming)
  3. hope.

1) copy input files to dfs:
hadoop dfs -copyFromLocal examples/wordcount wordcount

2) run streaming job:
hadoop jar /usr/lib/hadoop/contrib/streaming/hadoop-0.20.1+152-streaming.jar \
-input wordcount \
-output wordcountout \
-mapper examples/wordcount/map.pl \
-reducer examples/wordcount/reduce.pl \

packageJobJar: [/home/hadoop/tmp/hadoop-hadoop/hadoop-unjar5876487782773207253/] [] /tmp/streamjob4555454909817451366.jar tmpDir=null
10/01/05 03:29:34 INFO mapred.FileInputFormat: Total input paths to process : 1
10/01/05 03:29:35 INFO streaming.StreamJob: getLocalDirs(): [/home/hadoop/tmp/hadoop-hadoop/mapred/local]
10/01/05 03:29:35 INFO streaming.StreamJob: Running job: job_201001050303_0003
10/01/05 03:29:35 INFO streaming.StreamJob: To kill this job, run:
10/01/05 03:29:35 INFO streaming.StreamJob: /usr/lib/hadoop-0.20/bin/hadoop job -Dmapred.job.tracker=localhost:54311 -kill job_201001050303_0003
10/01/05 03:29:35 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201001050303_0003
10/01/05 03:29:36 INFO streaming.StreamJob: map 0% reduce 0%
10/01/05 03:30:19 INFO streaming.StreamJob: map 100% reduce 100%
10/01/05 03:30:19 INFO streaming.StreamJob: To kill this job, run:
10/01/05 03:30:19 INFO streaming.StreamJob: /usr/lib/hadoop-0.20/bin/hadoop job -Dmapred.job.tracker=localhost:54311 -kill job_201001050303_0003
10/01/05 03:30:19 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201001050303_0003
10/01/05 03:30:19 ERROR streaming.StreamJob: Job not Successful!
10/01/05 03:30:19 INFO streaming.StreamJob: killJob...
Streaming Command Failed!
Sigh. Failure. Time to debug the job. Definitely needs the -file flag to bundle the executables to the remote machine.
-file map.pl
-file reducer.pl

Step back and run a simpler job.
hadoop jar /usr/lib/hadoop/contrib/streaming/hadoop-0.20.1+152-streaming.jar -input wordcount -output wordcountout3 -mapper /bin/cat -reducer /bin/wc


10/01/05 03:36:17 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201001050303_0004
10/01/05 03:36:17 ERROR streaming.StreamJob: Job not Successful!
10/01/05 03:36:17 INFO streaming.StreamJob: killJob...
Streaming Command Failed!

This is the example code. Why did it fail again? Is there a problem with my input file?

I'll pick this back up tomorrow (or later). A little birdie just told me it was 3:40am. Well past my bedtime. I'd like to finish this up, but that's what I've been saying since I started at midnight. I have the Hadoop::Streaming::Mapper and ::Reducer modules all packaged up and ready to make an initial push to CPAN, but first I need to get an example running under hadoop. I did finish writing the tests for the non-hadoop case, and those are clean and ready. Feel free to follow along at my github repository.

Update

or maybe I'll just try a few more times...

hadoop jar /usr/lib/hadoop/contrib/streaming/hadoop-0.20.1+152-streaming.jar -input wordcount -output wordcountout7 -mapper map.pl -reducer reduce.pl -file examples/wordcount/map.pl -file examples/wordcount/reduce.pl


packageJobJar: [examples/wordcount/map.pl, examples/wordcount/reduce.pl, /home/hadoop/tmp/hadoop-hadoop/hadoop-unjar390944251948922559/] [] /tmp/streamjob7610913425753318391.jar tmpDir=null
10/01/05 03:59:11 INFO mapred.FileInputFormat: Total input paths to process : 1
10/01/05 03:59:11 INFO streaming.StreamJob: getLocalDirs(): [/home/hadoop/tmp/hadoop-hadoop/mapred/local]
10/01/05 03:59:11 INFO streaming.StreamJob: Running job: job_201001050303_0010
10/01/05 03:59:11 INFO streaming.StreamJob: To kill this job, run:
10/01/05 03:59:11 INFO streaming.StreamJob: /usr/lib/hadoop-0.20/bin/hadoop job -Dmapred.job.tracker=localhost:54311 -kill job_201001050303_0010
10/01/05 03:59:11 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201001050303_0010
10/01/05 03:59:12 INFO streaming.StreamJob: map 0% reduce 0%
10/01/05 03:59:23 INFO streaming.StreamJob: map 100% reduce 0%
10/01/05 03:59:35 INFO streaming.StreamJob: map 100% reduce 100%
10/01/05 03:59:38 INFO streaming.StreamJob: Job complete: job_201001050303_0010
10/01/05 03:59:38 INFO streaming.StreamJob: Output: wordcountout7

Success!


hadoop dfs -ls wordcountout7;

Found 2 items
drwxr-xr-x - hadoop supergroup 0 2010-01-05 03:59 /user/hadoop/wordcountout7/_logs
-rw-r--r-- 1 hadoop supergroup 125 2010-01-05 03:59 /user/hadoop/wordcountout7/part-00000


hadoop dfs -cat wordcountout7/part*

apple 2
bar 2
baz 1
c 1
c++ 2
cpan 9
foo 2
haskell 4
lang 1
lisp 1
ocaml 2
orange 2
perl 9
python 1
ruby 4
scheme 1
search 1

Friday, December 11, 2009

Dec Perl Mongers was a blast

We'll have the slides up soon along with some Perl+VIM tips. Really, I mean it this time. Do you have some favorite perl/shell/vim integration tips you'd like to pass along?

In the mean time, you can follow along in the git repository. Including the drama where 10 minutes before presentation time I merged in changes from my cohort that deleted 90% of the files, and then I blindly pushed those up to the public master.

You can look directly at the Vroom slides from http://github.com/spazm/config/blob/master/slides/slides.vroom . I'll render those to html and push them somewhere for viewing.

Omnicompletion actually worked during my talk/demo. I think that's the first time I've ever actually had it work. Totally exciting. While preparing the slides and doing I found that I was missing a configuration option in my vimrc, so my ftplugin/perl directory was getting skipped.

Tuesday, October 27, 2009

LA Perl Mongers: Pushed back a week

Our next L.A. Perl Mongers meeting has been pushed back a week.
Instead of 10/28 we'll now meet on Wednesday, November 4th.

Topics:

  1. Tommy Stanton: Testing for the Win! Test::More, Test::Most and Test::Unit.
  2. Andrew Grangaard: either "Care and Feeding of third party modules, revisited -- a local::lib example" or "Hadoop with Perl"

la.pm.org

Monday, October 19, 2009

Cowboy culture.

Cowboys.

What is a cowboy, in this context? He's writing scripts, not programs not software. He's someone who runs off on his own, thinking he understands what his is working when he is really cargo culting and making guesses and assumptions. Loves making changes live in production and uses phrases like "I think it should work, right after this patch." Patching things up in a belt-and-suspenders way that obscures the original logic or business case. They have yet to see the light of testing (at all, let alone automated unit testing with high coverage), check things into source control after-the-fact which may or may not match what is in production (which well may vary from machine to machine). And "hey, this 6000 line function should basically work, most of the time, but when it doesn't I have errors sent to /dev/null in the crontab."

Let's say you're a cowboy or you work with one. How do you survive? Adapt? Reform?

Blast off and nuke it from orbit, its the only way to be sure.
--Aliens
If only we could just nuke it. But that's not going to happen until you have a replacement. The fact that the replacement is cleaner and more understandable won't be enough unless it also faster and provable more correct and quite likely it'll need to be bug-for-bug compatible with the old code.

What's the problem with just rewriting it all from scratch? First, code archeology time. When dealing with legacy code, that is spaghetti and undocumented and untested, you will spend most of your time figuring out what it does and why. Is it important that this test short circuits? Why is most of the logic up here, but some is down there? Does the sort order of this array of keynames matter? Are there implied dependencies?

Now, the only reason you're in there is that something is broken, and now someone has allocated some time and resources to fix it, firefighting style. Otherwise, no one wants to go near that code. Especially given that the code owner seems to be putting in herculean efforts to keep it running (staying up late most nights handling error escalations that ring his pager at 4am). Of course, it also probably terribly important code to the business (it handles logs or stats or something similar in the direct money path) so it HAS TO BE DONE! OMG OMG THE SKY IS FALLING FIX IT RIGHT NOW!

Resist the urge to just jump in and make that one change. Yes, someone will be yelling "why isn't this ready" and you'll have to be firm on your reply that you can't know that simple change won't affect the whole system negatively in a chaotic system. Blind refactoring my just further hide the business logic and cause you to rewrite and obscure current bugs. You have to assume there are other problems than the one you are fixing, just no one has noticed the others (or noticed and failed to report). You don't want to be the one called at 4am because your simple fix took payroll offline when the 3am job kicked in and was expecting some old, broken format.

I recommend a two fold approach. First you start with a light bottom-up refactor. Trim the lexical variables down to their minimum needed scope, and change the seven $t variables into useful names that match their scope (big scope == big more descriptive name). Pull blocks of that behemoth function into smaller blocks. Find a test case that exercises the important features, and make sure the original code runs on it reproducibly, giving the same output each time. Really start with this test case. I've been burned so many times chasing my tail because my test output doesn't match the original, due to some random or non-causal output from the original code. Then find any external dependencies (the database, time-of-day, phase-of-moon) and start thinking about how you'll test them.

Once you have that done, start working top-down. You can't do this step until you've been a bit steeped in the code as you won't know the right questions to ask the business sponsors. You have to know how it does things without letting it set your mind-view of how things will be done -- a fine line to tread. Now we look at the problem and the problem domain and wonder if this approach is still valid, given the way the data and data model have changed. Can you use bring some patterns into the code, separate out pre-processing and report definition and number crunching? What can you learn from the evolution of the old code, over multiple passes of tweaks and updates about what we've learned from the business? There is value in that knowledge, if you can separate the wheat from the chaff, the important changes from the incidental, accidental and cargo-cult-copy-and-pasted changes. Build your modules from the ground up to be reusable and modular and yet designed for the business case that the current script handles. Test as you go, you'll be so much happier.

Now, you have your middle rewrite written. It has some of your top down and all of your bottom-up changes. Test it against some minimal output, comparing with the old script. You're going to be running this test a lot, please write a script to automate it. You'll thank yourself later which is nicer than cursing yourself out later because that 1/2 hour test has gone wonky because you broke your shell command history. Now you'll be adding bug-for-bug compatibility, to make sure your code produces output to match current production. Add those bugs, really. And then document them in your bug tracking and make sure they really are bugs and not "oh my goodness, of course I need the fact that the reports come out sorted by the third character of the report name" expected functionality by someone.

When they match, make the switch. Now there should be no visible difference from the outside. But now you can go to town on your in-between scaffolding code. That's why you put in all those unit tests. Now you can hack up chunks of internals and know you aren't affecting the eventual output. Soon you'll have a business critical chunk of software that won't call you for help at 4am, a program you're proud to have rescued from it's prior life as a "script written by a cowboy."

Update: Todd sent me links to two of his cartoons from asciiville, from when he was dealing with a "slew of these cowpies".

BTW: I loved the Cowboy Culture post. I had to fix a slew of those cowpies about a year ago, and I drew a couple of toons as a release. I thought you might enjoy these as we are on the same wavelength with respect to cowboy coding.. :)

bedtime stories

the new recruit

Sunday, October 11, 2009

LA perl mongers October update and September recap

September's perl mongers meeting was awesome. We had two presentations (both from me!). The meeting for October will be Wednesday October 28th. The first presentation was an example of getting work done using perl. Specifically using JIRA::Client (a thin wrapper around SOAP::Lite) to access a JIRA bug tracking installation to pull bug counts. Slides included fully working example code. The author of JIRA::Client commented on the blog post. That is so exciting! That's what community and social coding feels like.
Nice example. It inspired me to make it easier to get from filter names to filter ids. I just released JIRA::Client version 0.16 which implicitly casts filter names into filter ids in the calls to getIssueCountForFilter and getIssuesFromFilterWithLimit.
-- Gnustavo
The second presentation was a discussion of "care and feeding of third party perl modules." We started with my blog post and went around discussing what approaches people had tried, which ones they liked which ones they found lacking. Tommy was kind enough to run the video camera for part of the discussion, so once I transfer the tape, we'll have something to upload.

Some of the main points to come out of the discussion were: the importance of staying up-to-date, of having unit-tests of the features you expect and use from external modules, green field testing (make sure you can build it all from scratch in your test environ). The need for a company to institute some sort of revisioning on top of CPAN came up a few times.

Some novel ideas included: source control hooks that check for external modules used in a given commit and updating all those modules to current release, requiring the programmer to verify that his/her checking works with current modules; a single repository for third party modules and other code, that can be easily pulled into any internal project or repository (local::lib helps here); considering what is pushing you to be "up-to-date" as maybe you don't actually need it (sacrilege!)

Some related tasks that need to happen soon: upload the video and notes from the second presentation before the October meeting. Update the website with the October date Edit:done. Put up the slides for the JIRA::Client talk. Find a speaker for October ( Tommy signed up, but then had to defer to November). Find a November date to work around Thanksgiving. Decide if we need to cut back to a single speaker (or two speakers every two months).