Perl-Sensitive Sunglasses PerlMonks

### Meditations

 ( #480=superdoc: print w/ replies, xml ) Need Help??

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
RFC: Emulating the monastery voting system
2 direct replies — Read more / Contribute
by biohisham
on Sep 10, 2015 at 08:27

Out of admiration for the PM voting and ranking system described in votes; I am inspired to suggest an implementation along its lines on a website being developed with a team of my friends. So as a proof of concept I wrote this interactive code that accepts: a member's reputation, (u)pvotes & (d)ownvotes, average likes per week as well as age of the node; then decides whether the number of u's or d's would result in reputation gain or loss relative to the current reputation.

As it is the code tests fine but I feel it could still use comments and anecdotal wisdom from the monks here, hence I posted it in Meditations.

use strict;
use warnings;
use Getopt::Long;
use Scalar::Util::Numeric qw(isint);

#age and avg_xp are calculated at the start of everyday.
#The avg_xp=sum(XP)/#nodes in the past 7 days.
#The program takes these two values in addition to #likes and #unlikes
+ to dynamically compute reputation gains and losses.
#Input for current reputation is prompted when it is time to update th
+e reputation.

my ($age,$avg_xp,$gained_rep,$lost_rep);
my ($upvotes,$downvotes, $total_rep); my$current_rep; #variable to hold the current user reputation from th
+e user page.
my $vote; #a listener:either (u)pvote or (d)ownvote. Readonly::Scalar my$args =>4;  #program accepts two args & two vals
if(@ARGV != $args){die "syntax error: perl calculate_rep.pl --age n -- +avg_xp n\n";} GetOptions( "age=i"=>\$age,
"avg_xp=i"=>\$avg_xp, )or die "syntax error: perl calculate_rep.pl --age n --avg_xp n\n" +; print "enter u for upvote or d for downvote\n"; while($vote=<>){
chomp $vote; if($vote =~/^u$/i){$upvotes++;
analyze_upvotes($age,$upvotes);
}elsif($vote=~/^d$/i){
$downvotes++; analyze_downvotes($age,$downvotes); }else{ print "ERROR: enter u for upvote or d for downvote\n"; } } sub analyze_upvotes{ my$node_age=shift;
my $like_counter=shift; printf "you have %d likes\n",$like_counter;
if($like_counter==1){#reward the first upvote$gained_rep=1;
rep_update($gained_rep,"gain",$like_counter);
$gained_rep=0; } if($age>2 && $like_counter>1){ #nodes older than two weeks get 1/5 + rep increase$gained_rep+=1/5;
if(isint $gained_rep){ #reputation is reported when gained +reputation sums to a whole number rep_update($gained_rep,"gain", $like_counter);$gained_rep=0;
}
}elsif($age<=2 &&$like_counter>1){ #rep for nodes < 2 weeks o
+ld is calculated with avg_xp perspective
if($like_counter<=$avg_xp){ $gained_rep+=1/3; } elsif($like_counter>$avg_xp &&$like_counter<=2*$avg_x +p){$gained_rep+=1/2; }
elsif($like_counter>2*$avg_xp && $like_counter<=3*$avg
+_xp){ $gained_rep+=2/3; } elsif($like_counter>3*$avg_xp &&$like_counter<=4*$avg +_xp){$gained_rep+=3/4; }
elsif($like_counter>4*$avg_xp){$gained_rep+=1;$gained
+_rep=int $gained_rep; } if(isint$gained_rep){
if($current_rep-$gained_rep==0){ #for when cur_rep
+=1 and gained_rep=1;
rep_update(1,"gain", $like_counter); }else{ rep_update($gained_rep, "gain", $like_coun +ter); }$gained_rep=0;
}
}
}

my $node_age=shift; my$unlike_counter=shift;
printf "you have %d unlikes\n", $unlike_counter; if($age<=2){
if($unlike_counter<= 3*$avg_xp){ $lost_rep+=1/3; } elsif($unlike_counter > 3*$avg_xp &&$unlike_counter <= 4*
+$avg_xp){$lost_rep+=1/4; }
elsif($unlike_counter > 4*$avg_xp){ $lost_rep+=0; } if(isint$lost_rep){
rep_update($lost_rep, "loss",$unlike_counter);
$lost_rep=0; } }elsif($age>2){ $lost_rep+=0;} } sub rep_update{ my$rep_gain_loss=shift;
my $status=shift; my$like_unlike_counter=shift;
print "what is the current user reputation?\n";
$current_rep=<>; chomp$current_rep;
if($status eq "gain"){ my$total_gain=$current_rep +$rep_gain_loss;
printf "you gained %d points\nyour reputation is %d\n", $rep_g +ain_loss,$total_gain;
}elsif($status eq "loss"){ my$total_loss=$current_rep-$rep_gain_loss;
printf "you lost %d reputation points\nyour reputation is
+%d\n", $rep_gain_loss,$total_loss;
}
}
[download]

I am also thinking about changing the way loss of reputation is done by basing it on a variable (say avg_unlike_xp) similar to the avg_xp that I currently use for calculating gain/loss or reputation. If I did this I won't be that benevolent of a dictator any more though as I could risk over-penalizing members.

Something or the other, a monk since 2009
Mojolicious and MongoDB
by rahuldhodapkar
on Sep 09, 2015 at 19:54
Hey Monks!

I haven't been around the perl community for a while, but have had a lot of fun getting familiar with the language again. Perl was my first language, but it seems to me that a lot of new programmers choose other languages like Python or Javascript to get themselves started.

I set out to make a simple, but robust starter framework using Mojolicious and MongoDB so that new programmers (especially those at hackathons) would be able to use Perl for fun and diverse projects.

http://github.com/rahuldhodapkar/MongoDB-Mojolicious-Starter

I wanted to put the current project out there, and would appreciate help (or even pull requests maybe ^_^) and feedback. Hope everyone is doing well

Dup: Perl 5 Optimizing Compiler, Part 14: RPerl v1.1 Release, Codename Jupiter, Now Supporting N-Body Benchmark
by Will_the_Chill
on Sep 05, 2015 at 19:37
Howdy Monks,

RPerl v1.1, codename 'Jupiter', has been released to CPAN!

Jupiter supports fully-automated compiling of the long-awaited N-body application software, which is a solar system simulator used by the Alioth Benchmark Game to rank programming languages by speed.

RPerl and the new PhysicsPerl software suite enable the N-body app to run at the speed of C++, dropping from over 19 minutes runtime to barely 13 seconds!

For now, see the INSTALL notes file for instructions on running N-body using RPerl & PhysicsPerl.

Also, take a look at the pre-release user documentation, Learning RPerl!

Please visit us on IRC for real-time tech support:

irc.perl.org
#perl11

Perling,
~ Will the Chill, rperl.org & austin.pm
Notepad++ Perl Function List with "Classes"
No replies — Read more | Post response
by VinsWorldcom
on Aug 24, 2015 at 12:50

Windows Monks,

As follow-on to my previous meditation regarding Notepad++ Integrated Perl Debugging, I've been doing other things with Notepad++ to make it more friendly when I write Perl (of which I've been doing more than usual lately).

One thing I did was to get Python debugging working the same way as with Perl. In case you're interested, see here: http://vinsworldcom.blogspot.com/2015/08/notepad-dbgp-and-python.html.

This got me thinking as I looked in the "Function List" window at Python code:

file.py
+[Class]h_main
__init__
+[Class]h_base
toXML
convert
main
[download]

Why does the "Function List" window show Python classes, but not Perl by default? Of course by Perl class, I mean 'package <name>'. All I would see was a list of subs. Take the following example program:

#!perl

use strict;
use warnings;

package MyPkg;
sub one {
1;
}
sub two {
1;
}
1;

package main;

my $p = pre(); print$p . MyPkg->one;

sub pre {
return "ONE = ";
}
[download]

file.pl
one
two
pre
[download]

But there are clearly "classes" (read: packages) under which I'd like my subs grouped. Thankfully, Notepad++ allows customization of a file in the Notepad++ top level directory called 'functionList.xml' (documentation: https://notepad-plus-plus.org/features/function-list.html). A quick web search turned up a partial solution and with some more tweaking I finally got it to display:

file.pl
+[Class]MyPkg
one
two
+[Class]main
pre
[download]

If there are no "packages", then the original display of just filename with the subs is what is displayed. I even tweaked it a bit to ignore stuff after __END__, so any "sub name" that appears in POD won't be mistakenly added to the Function List. I've tested it by viewing a few of my scripts, some modules and a few "custom" codes to demonstrate different use cases. So far, so good.

The solution; save a copy of your existing 'functionList.xml' to something like 'functionList.xml.ORIG' (just in case you want to revert back), open the existing 'functionList.xml' file, find the Perl parser lines:

<parser id="perl_function" displayName="Perl" ...
...
</parser>
[download]

and replace the whole lot with:

<parser id="perl_function" displayName="Perl" commentExpr="(#.*?$|(__E +ND__.*\Z))"> <classRange mainExpr="(?&lt;=^package).*?(?=\npackage|\Z)"> <className> <nameExpr expr="\s\K[^;]+"/> </className> <function mainExpr="^[\s]*(?&lt;!#)[\s]*sub[\s]+[\w]+[\s]*$$?[^$$\ +(]*?\)?[\n\s]*\{"> <functionName> <funcNameExpr expr="(sub[\s]+)?\K[\w]+"/> </functionName> </function> </classRange> <function mainExpr="^[\s]*(?&lt;!#)[\s]*sub[\s]+[\w]+[\s]*$$?[^$$$$] +*?$$?[\n\s]*\{"> <functionName> <nameExpr expr="(?:sub[\s]+)?\K[\w]+"/> </functionName> </function> </parser> [download] MCE::OrdHash naming Push and Unshift methods supporting merging and reordering 1 direct reply — Read more / Contribute by marioroy on Aug 18, 2015 at 12:49 Greetings all, I have been working on MCE::OrdHash, a sharable ordered hash module for use with MCE::Shared. These things will be included with MCE 1.7 when released. MCE::OrdHash is 100% compatible with Tie::IxHash. It overlays a modified tombstone deletion seen in Hash::Ordered. It supports both OO and Tie. The OO interface is faster, but provides auto-tie on-demand when hash-like dereferencing is requested. This is done via an autoload directive. The Push and Unshift methods in MCE::OrdHash merges for existing keys to remain compatible with Tie::IxHash. It adds two methods when reorder is desired. The method names are PushRo and UnshiftRo. Reorder means having to delete an existing key prior to inserting. I seek for the opinion of other monks on the naming of PushRo and UnshiftRo. Should I name these something else? Thank you, Mario If interested, I benchmarked against Hash::Ordered and Tie::IxHash. I have dropped MCE::Hash::Indexed (OI) and keeping MCE::Hash::Ordered (OT) which is now MCE::OrdHash. OT: Sigh ... Windows 10 9 direct replies — Read more / Contribute by roboticus on Aug 14, 2015 at 19:27 Annoying OT rant. You'll probably want to skip reading this altogether. I built myself a rather nice Gaming system a while back, and for the most part, I'm pretty happy with it. The big pain in the ass, though, was that I installed Windows 8.1 on it, rather than finding a copy of Windows 7. I've used Windows 7 for a couple years at work, and am pretty happy with it. However, Windows 8.1 was a nasty kick in the teeth. I'm still fighting with it, and hating it. So when the new and improved Windows 10 was announced, I thought I'd go and install it. Though, this time, I thought I'd learn a little about it first, so as not to install something even worse than Windows 8.1 (which sucks horribly, by the way). (Note: It's pretty much just the UI part that seems to suck. Performance is good. It's just that the UI went to hell for no good reason. When you mention it on a mailing list, you get the old "Oh, you old farts are afraid of change". Bullhocky! I'm not a *bit* afraid of change. I just hate things that suck!) Anyway, reading the reviews, it seems that Windows 10 might be a significant improvement over Windows 8.1. Not that I'll be finding out, though. Luckily, before I allowed my box to upgrade to Windows 10, I stumbled across something: Apparently Windows 10 is going to *force* autoupdates--no compromises. Sorry, Microsoft, but you've lost *far* too much trust for me to allow you to decide when to upgrade my operating system. So I'll be sticking with Windows 8.1 until someone either gives me a (legal) copy of Windows 7 (I'm not interested in pirating it, *nor* am I planning on giving Microsoft another dime to fix their mistake.) Sorry for the off-topic rant, but I'm in a ranting mood. (For those advising that I should use Linux, I'll let you know that I have more Linux boxes (5) at home than Windows boxes (2). I put this box together for gaming, but I run it most of the time because it has the good monitors on it, the big honkin' CPU and the excessive RAM. The instant that game stops being fun, this box'll be getting upgraded to Debian, and there'll only be my son's Windows box left in the place.) ...roboticus When your only tool is a hammer, all problems look like your thumb. RFC: Improving the quality of your module 1 direct reply — Read more / Contribute by SBECK on Aug 14, 2015 at 15:24 I have been looking for a list of tools that I can use to improve the quality of my modules, and I haven't been able to find one elsewhere, so I posted a question to Seekers and summarized the tools below. I propose adding the following to be added to the tutorials list (under Modules: How to Create, Install, and Use -> Creating and Distributing Modules). # Improving the quality of a perl module There are a large number of tools available which can be used to improve the quality of a perl module. This might mean decreasing the number of bugs in it, improving it's performance, improving it's ability to interact with various other perl tools, or making it more usable to others. Below is a list of tools that are available which may help improve various aspects of your module. Not all will be useful in all situations, but it should still be a useful starting point. Change Kwalitee Every module should come with a description of the changes made at each version. There is a standard format that can be used. This site can be used to determine if your changes file meets the standard. CPAN Testers Once a module is released to CPAN, it is automatically tested by a set of volunteer testers on various platforms with different versions of perl. This site lists the platforms used to test the module as well as which ones succeed and which fail. CPANTS Kwalitee There are a number of best practices when creating a module. This site lists many of the most common ones and reports on which ones a module passes and which ones it fails. Devel::Cover, cpancover.com These can be used to make sure that every line in your module is covered by at least one test in the test suite. Devel::NYTProf This is THE tool for profiling a module to see where the time is being spent in order to speed things up. Perl::Critic This can be used to check perl code to see whether it uses the best practices described in Damian Conway's Perl Best Practices book. Perl::Tidy This can be used to fix indentation and enforce a few other coding style practices. Pod::Spell A spell checker for Pod files. Release::Checklist A check list of things to look at when releasing a new module. Task::Kensho A list of recommended perl modules. Especially useful are Task::Kensho::ModuleDev and Task::Kensho::Testing which contain modules recommended for development and testing. Test::Pod, Test::Pod::Coverage These are used to make sure that no pod files are missing and that they cover all of the functions in a module. Travis CI This tool can be used for modules stored on GitHUB. Every time a set of changes is checked in, the module will be automatically tested using a number of different perl versions to make sure that all tests pass. Ternary vs. Sort vs. Max 8 direct replies — Read more / Contribute by QM on Aug 10, 2015 at 05:23 A line in BrowserUK's post reminded me of one of my cobwebs that I'm always chasing, namely, whether the Conditional Operator, ?:, is preferable over sort. In the end I should import a max function when possible, but I don't always do so. Conditional operator: my$n = $x >$y ? $x :$y;
[download]

I find this awkward to read, and it also duplicates the variable names.

Sort:

my $n = (sort {$a <=> $b}$x, $y)[-1]; [download] But because sort needs a numeric sort function, that's a bit long winded. And the max function: use List::Util qw(max); my$n = max($x,$y);
[download]

Which seems to be the laziest and preferred way.

-QM
--
Quantum Mechanics: The dreams stuff is made of

RFC: (DRAFT Tutorial) A Gentle Introduction to Perl 6
5 direct replies — Read more / Contribute
by u65
on Aug 05, 2015 at 20:56

I have posted a draft tutorial in my scratchpad here below (per Arunbear's suggestion) and am looking for constructive criticism. Thanks.

UPDATE 1: Added three subheadings including an informal list of Perl 6's desirable features.

UPDATE 3: After some rework (perltidy, perlcritic) in the Perl 5 code, modified the Perl 6 code accordingly, then made additional improvements to the Perl 6 code to be more Perl6ish.

=== BEGIN TUTORIAL ===

## Introduction

Perl 6 is almost upon us, and it promises to cure many of the shortcomings of Perl 5. For all the official information, check out its web site at <http://perl6.org>. I use the instructions here <http://rakudo.org/how-to-get-rakudo/> for a Linux source installation with the rakudobrew script.

I asked for users opinions of Perl 6's "killer" features on the Perl 6 users list and following are some of the responses:

• variables must be declared
• strong typing available
• built-in command line processing
• built-in multiple dispatch
• the where clause
• built-in sets and bags
• built-in pick and roll
• built-in better arithmetic (Rat number type)
• improved regex
• no parens required for if statements
• built-in facilities for the language to parse, transform and extend itself (std grammar, macros)
• awesome error messages
• hyphens allowed in names
• grammars
• easy interface with C
• named subroutine arguments
• better classes and namespaces
• built-in object methods
• see rosettacode for good examples

• Just make them look at Perl6 source code, e.g., on rosettacode. Someone who doesn't see how wonderful Perl6 is, is a lost soul anyway.
• Less cumbersome to write and easier to read.
• Grammars: Perl 6 is most attractive to me as a framework development tool. It lets you be really creative in how you let users describe their problem to your framework, whether that be webserver, parser, etc.
• One thing that was not mentioned already is using Rat instead of standard floating point number. It prevents many silly mistakes, especially when counting money.

## Purpose

This tutorial aims to show how my typical modest Perl 5 scripts translate into Perl 6. As the current Perl 6 documentation is not yet complete, my beginning Perl 6 efforts have resulted in putting together a simple model for a typical task for me. It was completed somewhat by trial and error along with much help from the Perl 6 mailing list.

## The Code

A typical script of mine does something like the following:

• Provides a simple usage statement when executed without any arguments.
• Provides detailed help when the '--help' or '-h' or '?' options are provided.
• Opens and parses some kind of data file (often in a special key-value format).
• Takes some kind of action with the input data.
• Writes data to STDOUT or a specific file.
• Provides a friendly results message upon successful completion.

The following table is a side-by-side comparison of the two example programs (both of which work for me; please report any errors you may find). There are some comments to indicate differences in Perl 5 versus Perl 6, but many are not documented explicitly. In many cases of my Perl 6 usage, as in Perl 5, TIMTOWTDI, so I'm sure both programs can be improved.

Below the programs is the input data file used by each program. Run each program like this to compare results (assuming you have done chmod +x filename for each file):

  $./tutorial-p5.pl -g -d >& p5.txt$ ./tutorial-p6.pl -g -d .& p6.txt
[download]
Perl 5Perl 6
#!/usr/bin/env perl

# file: tutorial-p5.pl

# PRELIMS  ========================
use v5.10;    # features 'say' and 'state'
use strict;
use warnings;

use File::Basename;    # p6: no such module yet
use Data::Dumper;

my $default_infile = 'tutorial-data.txt'; my$prog           = basename $0; my$debug  = 0;
my $infile = 0; my$usage  = "$prog: --go | --infile=<data file name>";$usage    .= ' | --help | ? [--debug[=N]]';

# ARG/OPTION HANDLING ========================
if (!@ARGV) {
say $usage . "\n"; exit; } foreach my$arg (@ARGV) {
my $oarg =$arg; # save original for error handling
my $val = undef; my$idx  = index $arg, q{=}; if ($idx >= 0) {
$val = substr$arg, $idx+1;$arg = substr $arg, 0,$idx;
}
if ($arg eq '-g' ||$arg eq '--go') {
$infile =$default_infile;
}
elsif ($arg eq '-i' ||$arg eq '--infile') {
$infile =$val;
}
elsif ($arg eq '-d' ||$arg eq '--debug') {
$debug = defined$val ? $val : 1; } elsif ($arg eq '-h' || $arg eq '--help' ||$arg eq q{?}) {
long_help();
}
else {
die "FATAL:  Unknown argument '$oarg'.\n"; } } # MAIN PROGRAM ======================== die "FATAL: No such file '$infile'.\n"
if (! -e $infile); my %user; my @keywords = qw(last first job); my %keywords; @keywords{@keywords} = (); parse_data_file($infile, \%user, $debug); if ($debug) {
print Dumper(\%user);
}
else {
say 'Normal end.';
}

#### SUBROUTINES ========================
sub parse_data_file {
my $fname = shift @_; my$href  = shift @_;
my $debug = shift @_ || 0; say "Parsing input file '$fname'...";
open my $fp, '<',$fname
or die "$fname:$!";

my $uid = undef; my$linenum = 0;
while (defined(my $line = <$fp>)) {
++$linenum; my$err = 0;
my $idx = index$line, q{#};
if ($idx >= 0) {$line = substr $line, 0,$idx;
}
# skip blank lines
next if $line !~ /\S/xms; # every valid line must have a colon (':') # following a key word$idx = index $line, q{:}; if ($idx >= 0) {
# ensure the key is lower case
my $k = lc substr$line, 0, $idx; # trim ws on both ends$k =~ s{\A \s* | \s* \z}{}gxms;

my $val = substr$line, $idx+1; # also needs trimming$val =~ s{\A \s* | \s* \z}{}gxms;

# User attributes
if ($k eq 'user') {$uid = $val; die 'FATAL:$uid not defined.'
if !defined $uid; if ($uid =~ /\D/xms) {
say 'ERROR:  User ID not an integer.';
++$err; } elsif ($uid <= 0) {
say 'ERROR:  User ID not an integer > 0.';
++$err; } elsif (exists$href->{$uid}) { say 'ERROR: User ID is not unique.'; ++$err;
}
next;
}

# for the following keys, an exception will be
# thrown if $uid is not defined if (!defined$uid) {
say 'ERROR: User ID is not defined for this user.';
++$err; } elsif ($k eq 'hobbies') {
$href->{$uid}{hobbies} = [];
my @h = split q{,}, $val; foreach my$h (@h) {
# trim ws on both ends
$h =~ s{\A \s* | \s* \z}{}gxms; push @{$href->{$uid}{hobbies}},$h;
}
}

elsif (exists $keywords{$k}) {
$href->{$uid}{$k} =$val;
}
else {
chomp $line; say 'ERROR: Unknown line format:'; say " '$line'";
++$err; } } else { say 'ERROR: Unknown line format.'; ++$err;
}
if ($debug) { chomp$line;
say STDERR "DEBUG: line = '$line'"; } if ($err) {
chomp $line; say "FATAL error in file '$fname' at line $linenum:"; say " '$line'";
exit;
}
}
} # parse_data_file

sub long_help {

say <<"HERE";
Usage (one of the following three):

$prog --go (or '-g')$prog --infile=<data file name> (or '-i=')
$prog --help (or '-h' or '?') The '--go' option uses the default input file:$default_infile

Any of the first two options can use the '-d' (or '--debug')
flag for debugging.
A debug number may be provided with '-d=N' (or '--debug=N').

HERE

exit;
} # long_help
# EOF ========================
[download]
#!/usr/bin/env perl6

# file: tutorial-p6.pl

# PRELIMS  ========================
use v6.0; # not required, but good practice for
# maintenance
# 'strict' and 'warnings' are the default

# Note: Using perl6 -v =>
#   '2015.07.1-66-g0dcbba7 built on MoarVM version 2015.07-8-gb8fdeae'

use Data::Dump;

my $default_infile = 'tutorial-data.txt'; my$prog = basename($*PROGRAM); my$debug  = 0;
my $infile = 0; my$usage  = "$prog: --go | --infile=<data file name>";$usage    ~= ' | --help | ? [--debug[=N]]'; # '~=' instead of '.='

# ARG/OPTION HANDLING ========================
# See [http://design.perl6.org/S06.html]
# for built-in methods similar to Getopts::Long
if !@*ARGS.elems {
say $usage ~ "\n"; # '~' instead of '.' exit; } for @*ARGS ->$arg is copy { # 'is copy' allows modifying locally
my $oarg =$arg; # save original for error handling
my $val = Any; # 'Any' instead of 'undef' my$idx  = index $arg, '='; if$idx.defined { # index is defined if an index is found
$val = substr$arg, $idx+1; # use substr function$arg = substr $arg, 0,$idx;
}
if ($arg eq '-g' ||$arg eq '--go') {
$infile =$default_infile;
}
elsif ($arg eq '-i' ||$arg eq '--infile') {
$infile =$val;
}
elsif ($arg eq '-d' ||$arg eq '--debug') {
$debug = defined$val ? $val : 1; } elsif ($arg eq '-h' || $arg eq '--help' ||$arg eq q{?}) {
long_help();
}
else {
die "FATAL:  Unknown argument '$oarg'.\n"; } } # MAIN PROGRAM ======================== die "FATAL: No such file '$infile'.\n"
if $infile.IO !~~ :f; my %user; my @keywords = <last first job>; my %keywords; %keywords{@keywords} = (); parse_data_file($infile, %user, $debug); if$debug {
say Dump(%user);
}
else {
say 'Normal end.';
}

#### SUBROUTINES ========================
sub parse_data_file(Str $fname, # declare args #Any$href,
%href,
Int $debug = 0) { say "Parsing input file '$fname'...";

my $uid = Any; # p6 doesn't use 'undef' my$linenum = 0;
for $fname.IO.lines ->$line is copy {
++$linenum; my$err = 0;
my $idx = index$line, '#', 0;
if defined $idx {$line = $line.substr(0,$idx);
}
# skip blank lines
next if $line !~~ /\S/; # '~~' and '!~~' for matching # every valid line must have a colon (':') # following a key word$idx = $line.index(':'); if$idx.defined  {
# ensure the key is lower case
my $k =$line.substr(0, $idx).lc; # trim ws on both ends$k = $k.trim; # string object method my$val = $line.substr($idx+1); # use object method
# also needs trimming
$val =$val.trim;

# User attributes
if $k eq 'user' {$uid = $val; die "FATAL: \$uid not defined."
if !$uid.defined; if$uid ~~ /\D/ {
say "ERROR:  User ID not an integer.";
++$err; } elsif$uid <= 0 {
say "ERROR:  User ID not an integer > 0.";
++$err; } elsif %href{$uid}:exists { # 'exists' adverb
say "ERROR:  User ID is not unique.";
++$err; } next; } # for the following keys, an exception will be # thrown if$uid is not defined
if !$uid.defined { say "ERROR: User ID is not defined for this user."; ++$err;
}
elsif $k eq 'hobbies' { # literal string keys must be quoted %href{$uid}<<hobbies>> = [];
my @h = split ',', $val; for @h ->$h is rw {
# trim ws on both ends
$h .= trim; # literal string keys must be quoted # use '@()' instead of '@{} push @(%href{$uid}<hobbies>), $h; } } elsif %keywords{$k}:exists {
%href{$uid}{$k} = $val; } else {$line .= chomp;
say "ERROR: Unknown line format, \$k = '$k'.";
say "  '$line'"; ++$err;
}
}
else {
say 'ERROR: Unknown line format (no key).';
++$err; } if$debug {
$line .= chomp; say "DEBUG: line = '$line'";
}
if $err {$line .= chomp;
say "FATAL error in file '$fname' at line$linenum:";
say "  '$line'"; exit; } } } # parse_data_file sub long_help { # note indent is taken from position of ending token say qq:to/HERE/; Usage (one of the following three):$prog --go                      (or '-g')
$prog --infile=<data file name> (or '-i=')$prog --help                    (or '-h' or '?')

The '--go' option uses the default input file:

$default_infile Any of the first two options can use the '-d' (or '--debug') flag for debugging. A debug number may be provided with '-d=N' (or '--debug=N'). HERE exit; } # long_help sub basename(IO::Path$fname) {
# no File::Basename module in p6 yet
my $idx = rindex$fname, '/';
if $idx { return$fname.substr($idx+1); # use substr method } return$fname;
} # basename
# EOF ========================
[download]

Following is the input data file used in the programs above:

# file: tutorial-data.txt
# a data file of users and their attributes
# note all valid lines are in format "key: value..."
user: 1234 # unique ID (an integer > zero)
last: Brown
first: Sam
job: gunsmith
# hobbies may be a comma-separated list
hobbies: hunting, Perl Monging
user: 2316
last: Doe
first: Jane
job: financial analyst
hobbies: Python open source, bowling
[download]
2 direct replies — Read more / Contribute
by VinsWorldcom
on Aug 05, 2015 at 06:28

Windows Monks,

Do you use Notepad++ as your preferred editor? Have you done some things with NppExec to move towards an IDE? Do you want integrated debugger support?

I was out of luck on the last one and a myriad of Google-ing didn't help. There was a debugger plugin for Notepad++ (DBGp - http://sourceforge.net/projects/npp-plugins/files/DBGP%20Plugin/) but it was for PHP debugging with XDebug ... originally. I set out to get Perl working with it and lo and behold - I did it!

UPDATE: I'm on Windows 7 x64 and using Strawberry Perl 5.18.1 MSWin32-x64-multi-thread.

The gory details can be found here:

http://vinsworldcom.blogspot.com/2015/08/debugging-perl-debugger-part-2-variable.html
http://vinsworldcom.blogspot.com/2015/08/debugging-perl-debugger-part-3.html

Essentially, you need:

#### DBGp plugin

Get it from the SourceForge page at http://sourceforge.net/projects/npp-plugins/files/DBGP%20Plugin/. Get the latest (0.13 beta as of this writing) and you'll only need the DLL. Current file name is: DBGpPlugin_0_13b_dll.zip. Unzip the DLL to your Notepad++\plugins directory.

#### Perl Debugger for Komodo IDE

We only need this since there isn't a "Perl Debugger for Notepad++ IDE". It essentially supplies the interface via "perl5db.pl" and subdirectory "DB" of various supporting modules. You get it here: http://downloads.activestate.com/Komodo/releases/archive/4.x/4.4.1/remotedebugging/ and you'll want the Komodo-PerlRemoteDebugging-4.4.1-20896-win32-x86.zip file. NOTE: I tried newer releases, but found other issues cropped up in addition to the ones I show you how to fix below, so use this version, or the rest of this won't make much sense.

I created a directory in my Notepad++\plugins directory called "PerlDebug"; so, ...Notepad++\plugins\PerlDebug. I unzipped only the "perl5db.pl" file and the entire "DB" directory and its sub directories into that PerlDebug directory.

#### Getting it to Work

You need to make some edits to the Perl Debugger scripts from the Komodo IDE as well as set some environment variables. First, the edits.

##### Edit DB\DBgrProperties.pm

Open the Notepad++\plugins\PerlDebug\DB\DBgrProperties.pm file. Line 657-659 is something like:

    $res .= sprintf(qq(<value%s><![CDATA[%s]]></value>\n),$encoding ? qq( encoding="$encoding") : "",$encVal);
[download]

Change that to:

    $res .= sprintf(qq(<![CDATA[%s]]>\n),$encVal);
[download]

Also, further up on line 131, you'll see:

    context_id="%d"
[download]

Change that to:

    context="%d"
[download]
##### Edit perl5db.pl

Open the Notepad++\plugins\PerlDebug\perl5db.pl file. On line 1525:

    $res .= sprintf(' line="%s"', [download] change to: $res .= sprintf(' lineno="%s"',
[download]

And, after line 2898, which should read:

    my $bpInfo = getBreakpointInfoString($bkptID, function => $bFuncti +on); [download] add the following three lines:  if ($bpInfo) {
$res .=$bpInfo;
}
[download]
##### Environment Variables

You'll need some environment variables to get this to work. I wanted them to be volatile so as not to upset normal operations. This where I used NppExec. I'll assume you have it installed as it's an awesome plugin that you should have installed. If not, get if from the Plugin Manager.

The only essential environment variables to set are:

set PERL5LIB=C:\path\to\Notepad++\plugins\PerlDebug
set PERLDB_OPTS=RemotePort=127.0.0.1:9000
[download]

where "\path\to\Notepad++" is your directory path to Notepad++. I have mine at "C:\usr\bin\npp\plugins\PerlDebug". Yours may be "C:\Program Files\Notepad++\plugins\PerlDebug". Note if your path has a space (like between "Program" and "Files" in the example, you'll probably need to double-quote the entire path assigned to PERL5LIB like: set PERL5LIB="C:\Program Files\Notepad++\plugins\PerlDebug".

I set my variables with an NppExec script:

NPP_SAVE
cd "$(CURRENT_DIRECTORY)" NPP_MENUCOMMAND Plugins\DBGp\Debugger ENV_SET PERLDB_OPTS=RemotePort=127.0.0.1:9000 ENV_SET PERL5LIB=$(SYS.PERL5LIB);$(NPP_DIRECTORY)\plugins\PerlDebug INPUTBOX "Command Line Arguments: " cmd /c start "Perl Debug" cmd /c perl.exe -d "$(FILE_NAME)" $(INPUT) [download] I saved it as "Perl - Debug" and used NppExec to add it to my "Macro" menu in Notepad++. It saves the current file, changes to the working directory, enables the DBGp plugin, sets the environment variables (only temporarily within the Notepad++ context, and careful not to step on a current value that may be in PERL5LIB), prompts for any command-line input to pass to your script to get it to run and finally starts the Perl debugging session - integrated in Notepad++! Some options I used to tune the DBGp plugin; from the Notepad++ "Plugins" menu, select "DBGp" and then "Config...". • Ensure the top checkbox "Bypass all mapping (local windows setup) is checked • No configuration in the "Remote Server IP", "IDE KEY" ... window • Under the "Misc" section, check: • "Break at first line when debugging starts" • "Refresh local context on every step" • "Refresh global context on every step" Hope it works for you - happy debugging! Building the Right Thing (Part I): Pretotyping 8 direct replies — Read more / Contribute by eyepopslikeamosquito on Aug 04, 2015 at 07:56 The biggest waste in software development seems to be building the wrong product, or the wrong features -- from How to build the right thing by Henrik Kniberg There is nothing so useless as doing efficiently that which should not be done at all I'd originally planned yet another installment of the long-running Agile Imposition series, reporting on Lean startup and related ideas. As I began my research however, I soon realized this is a vast, complicated and perplexing topic; a topic so important it can make or break your business. So, to do it justice, I've decided instead to start a new series of articles on building the right thing. Innovators Trump Ideas Most new ideas fail, even if they are very well executed. -- from The Pretotyping Manifesto by Alberto Savoia At work we have a place where googlers submit their ideas; there are over 10,000 ideas. I call it the place where ideas go to die. -- from The Pretotyping Manifesto by Alberto Savoia If you have any doubt about the business value of ideas, try going to any venture capitalist and telling them: "I have a great idea that could be turned into a multi-billion$ business. I am not going to implement it, but if you give me a mere $10,000 I'll give you my idea and it's yours to do whatever you want with it." Just for fun, I created an ad peddling my services as an Ideator and posted it on Craigslist: "Ideator for hire.$10 per idea." I am still waiting for a serious reply.

-- from Innovators beat Ideas by Alberto Savoia

Leonard approaches them with an idea for a smartphone app that helps users solve Differential Equations and announces that nobody else is currently making an app like theirs. Because of Penny's presence, Sheldon is afraid Penny will steal Leonard's idea. He points out an "Unlikely, but very plausible scenario" that Penny befriends the gang to steal a marketable idea from them. Penny points out that she hangs out with them partly because she receives free food.

-- from The Bus Pants Utilization Big Bang Theory, Season 4, Episode 12

Sheldon's reaction notwithstanding, ideas themselves are of little value.

Though innovators trump ideas, backing an innovator -- even one with a successful track record -- is hardly a safe bet. Innovation is hard. Startups are risky. Indeed, the prime motivation of both Alberto Savoia (father of pretotyping) and Eric Ries (father of Lean startup) is that they both experienced both phenomenal success and catastrophic failure in different Startups -- and so became determined to figure out why.

Some Famous Product Failures

Many businesses disappear because the founder-entrepreneur insists that he or she knows better than the market

The Innovator's nightmare is spending years and millions to build and perfect a product or service that people don't need or want

-- from The Pretotyping Manifesto by Alberto Savoia

The throwaway merchants at Bic thought; I know we've been very successfully making disposable pens, lighters and razors, why not make disposable underwear for women?

Some examples of spectacular failures caused by building the wrong "it":

Many other examples could be given.

What is especially tragic is when huge investments are made up front, then -- when the product idea is clearly failing -- instead of calling it quits, still more cash is pumped in. Until bankruptcy ensues. How to avoid this sort of tragedy?

Pretotyping

IBM 30 years ago did something very clever. They thought that speech to text would be the next big thing because managers could not type. Their market research told them that if they built a speech to text translator, people would buy it. As a small experiment they got people who said "we will pay $10,000 if you build it" and brought them to IBM. They put them in a room with a microphone and a screen, so they thought they had a speech to text translator when in fact they had a super typist in a hidden room! It sounded like a good idea. However, after using it, at the end of the day my throat is sore; and I cannot dictate confidential memos in an open office. After the test, folks said "I'm sorry, I hope you didn't build too many of them, because we don't want them". The person who built the Palm Pilot, Jeff Hawkins, had an innovator's nightmare, lost millions. This time, instead of whipping my investors into a frenzy, this time let's test the idea with a little wood block and a tooth pick, and he went around for two weeks pretending he had built this Palm Pilot. After two weeks of this pretending, he said "You know, if this wasn't just a piece of wood I would actually use it". It had much less functionality than the Newton, yet was much more successful. -- from The Pretotyping Manifesto by Alberto Savoia Pretotyping: Validating the market appeal and actual usage of a potential new product by simulating its core experience with the smallest possible investment of time and money. -- from The Pretotyping Manifesto by Alberto Savoia The Pretotyping Manifesto: • innovators beat ideas • pretotypes beat productypes • data beats opinions • doing beats talking • simple beats complex • now beats later • commitment beats committees False Positives and False Negatives Remember Webvan, the originators of the idea of groceries ordered online, then delivered to your door? Conceived during the first internet boom of the late 1990's, the idea behind Webvan was an instant success in Thoughtland. Everyone gave it a thumbs-up, and why not? It sounded simple, convenient, it had that why-didn’t-I-think-of-that, forehead-smacking ring of genius. Who can ignore Twitter? But when you first heard of the service, what was your reaction? Some may have thought it an intriguing experiment in real-time micro-broadcasting (though what evidence there was that this was a gap for people is unclear to me). But surely few intuited that it would ultimately power the democratic revolutions of the Arab Spring. The elevator pitch for Twitter has that terrier-twisting-its-head-to-comprehend, temple-scratching ring of insanity. -- from Pretotyping@Work Invent Like a Startup, Invest Like a Grownup by Jeremy Clark With Webvan, people who had been asked a hypothetical "would you use it?" question turned out to be far less enthusiastic when faced with a concrete "will you use it?" question. By the way, seeking to learn from failure, Amazon has recently hired several of the original Webvan developers to launch a new Amazon Fresh grocery business. It seems that False Positives are usually based on the opinions of acknowledged (and over-confident) experts. We pretotype because data beats opinions. False Negatives, such as Twitter, are much rarer. Which leads us to Clark's second law of failure: too few crazy-sounding ideas get tried. To avoid both False Positive and False Negative outcomes, revealed-preference market testing of reasonable proxies for the final product have to be achievable at much lower investments of time and money. -- from Pretotyping@Work Invent Like a Startup, Invest Like a Grownup by Jeremy Clark Some Pretotyping Techniques • Fake Door aka Landing Page. Advertise a new product or feature then track the response rate to see who would be interested. • Pinocchio. As used by Jeff Hawkins with his wooden model of the Palm Pilot. • Mechanical Turk. As used above by IBM to test customer reaction to speech-to-text translation "software". • Create a Video. As, for example, DropBox did. • One Night Stand (aka Concierge service aka Wizard of Oz). A fairly complete service experience is provided, minus the expensive underlying infrastructure required by a permanent solution. • Partnership. Instead of building expensive underlying infrastructure, partner with others who have it. Webvan, for example, might have avoided building expensive infrastructure by partnering with existing grocery stores (or by using Concierge). • Impersonator. A new wrapper is put on an existing product in order to impersonate a new one. • Piecemeal Solution. Similar to Impersonator, the product is presented by combining existing technologies, using minimal code/scripting to glue components together. • Walking Skeleton by Alistair Cockburn. Similar to Piecemeal Solution. • Audience Building. Get an audience before you build your product. For example, blog first. • Crowdfunding. Get the money first, before you actually build your product. • Single Feature. Instead of building the whole product, build just a single feature that can be used to test assumptions. • MVP. A Minimum Viable Product (MVP), a core part of Lean startup, is a working prototype put in the customer's hands. It is stripped down to the bare minimum required to perform a fair test. A complementary approach to pretotyping that has made a big splash recently is Lean startup, the subject of the next installment in this series. Perl Monks References External References Extra References Added Later Updated Sep/Oct 2015: Added "Create a Video", "Partnership", "Audience Building", "Crowdfunding", "Single Feature", "Piecemeal Solution", and "Walking Skeleton" to "Some Pretotyping Techniques" section. Added Extra References section. Time for an application portfolio 9 direct replies — Read more / Contribute by talexb on Jul 27, 2015 at 12:04 I have been tinkering with a few tools lately, and now want to put up a portfolio of some web applications that I am working on. I have an account on pair Networks (they also host this site), so I set up local::lib and went ahead and tried to install Mojolicious::Lite, since that's the platform I'm working on these days. No dice -- Mojo::Lite requires 5.10, and pair only has 5.8.9. I checked with the other provider I use, and they have 5.8.8. So the two options I can see are a) install an up-to-date Perl on one of those accounts, or b) have these web applications run on my home machine (perhaps using http://www.easydns.com to provide consistent name resolution -- not sure is this is still available). I could go find another web provider, but that's additional expense, and not really my best option right now. Feedback welcome! Alex / talexb / Toronto Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013. RFC: newscript.pl , my very first script! 6 direct replies — Read more / Contribute by Darfoune on Jul 24, 2015 at 15:40 Hello monks, This is my very first post on this site! I wrote my first program, newscript.pl , a few times ago, in order to save some repetitive typing and I really want your opinions, critics, suggestions etc.. It's job is very simple, create an empty script. At first written in bash, with only bash as supported language, now written in Perl it includes Perl, Bash and I started slowly working to include C as well. It's not very portable and surely not very efficient, but I'm using it everyday, when reading thru intermediate Perl, advanced Bash scripting and learning C the hard way. The script first ask user for the name of the new script, then it asks for the language you're going to use. It will then print the shebang line as well as wanted modules (if you asked for a Perl script) and save it to a file withyourname.test. It then fires up emacs -nw with your newscript so you are ready to input code right away. #!/usr/bin/perl use strict; use warnings; use File::Basename; ############################ # # Name : newscript # Usage: Makes ready to use script templates for # Bash and Perl only at the moment. It includes # the shebang line for both. Perl templates # includes some useful pragmas and the option to # include the required modules on the command line. # ############################ # declare some required vars my ($name, $language); my @modules = (); my$fullname = $0; my$progname = basename($fullname); ## main program: print "Name of the new script : "; chomp ($name = <STDIN>);

print "Language of $name script: "; chomp ($language = <STDIN>);

# If laguage is Bash, make a Bash script
if ($language =~ /bash/i) {$name = "$name.test"; print "\nMaking a Bash script:$name\n";
_makebash();

# If language is Perl, make a Perl script
} elsif ($language =~ /perl/i) {$name = "$name.pl.test"; print "\nMaking a Perl script:$name\n";
print "\nAdd modules? ex: File::Basename;\n(use strict and use war
+ning are turned on by default).\n";
print "[yes/no]: ";
# check if user wants modules
chomp (my $addmodule = <STDIN>); if ($addmodule =~ /yes/i) {
print "\nThis script does NOT add a ';' for you!\nSay 'done' w
+hen you done..\nModules: ";
while (<STDIN>) {
last if ($_ =~ /done(;)?/i); push @modules,$_;
}
_makeperl();
} elsif ($addmodule =~ /no/i) { _makeperl();} else { print "I assume no.\n"; _makeperl(); } # If language is C, make a C program } elsif ($language =~ /c/i) {
$name = "$name.test.c";
print "\nMaking a C program: $name\n"; print "\nThis is the first version with C included, no more option +s yet.\n"; print "Only '#include <stdio.h>' added at this time.\n\n"; _makec(); } else { print "This might help you:\n"; _usage(); } # Make a bash script sub _makebash { if ($language eq 'bash') {
open (NEWSCRIPT, '>', $name); print NEWSCRIPT "#!/bin/bash\n\n"; close NEWSCRIPT; chmod 0700, "$name";
exec (emacs -nw +3 $name); } } # Make a perl script sub _makeperl { open (NEWSCRIPT, '>',$name);
print NEWSCRIPT "#!/usr/bin/perl\n\nuse warnings;\nuse strict;\n";
if (defined($modules[0])){ # if module is defined +, include them to the template for my$mods (@modules) {
print NEWSCRIPT "use $mods"; } } print NEWSCRIPT "\n"; close NEWSCRIPT; print "\n"; chmod 0700, "$name";
exec (emacs -nw +50 $name); } # Make a C program sub _makec { open (NEWPROG, '>',$name);
print NEWPROG "#include <stdio.h>\n\n";
close NEWPROG;
print "\n";
chmod 0700, "$name"; exec (emacs -nw +10$name);
}

# Sets the usage message.
sub _usage {
print<<EOF;

Usage: \$progname [no options yet]

Creates ready to use script templates.

The script will first ask you for the name of your program,
then the language in which you want it written.

If your chosen language is supported, it will make an empty
script, with your name and 'test' appended to it. The script
then makes an exec call to emacs -nw with your new file.
(not very portable yet ..)

note: If your chosen language is Perl, The script will ask you
if you wish to import more modules. If you do want more input them
then followed by a ';' and input 'done' when finish.

bash:
#/bin/bash

perl:
#/usr/bin/perl
use warnings;
use strict;
use [yourmods];

C:
#include <stdio.h>

EOF
}

[download]
IBM Cloud Challenge.
4 direct replies — Read more / Contribute
by BrowserUk
on Jul 21, 2015 at 18:07

I just read about an IBM programming challenge to try and entice developers to IBMs Bluemix Cloud development environment.

(Don't bother if you're outside the UK; or if you want to use Perl (it ain't supported :(); or if stupid sign-up processes that don't work annoy you; or ... )

What struck me was that the three programming tasks are, at least notionally, so trivial. It took me less than 5 minutes to write (working, but probably not best) solutions to all three.

(Whether they would pass their test criteria I guess we'll probably never know)

I was also struck by this part of the description:

that you can put together a programme that can run within a time limit or on limited resources rather than just lashing together a hideous brute-force monstrosity. And that you can actually read the questions properly in the first place (a useful start, but one that's often forgotten).

I think it would be interesting to see how the best Perlish solutions we can come up with compare with those other languages that get entered to the competition; when and if they are actually made public.

So have at them. (Don't forget to add <spoiler></spoiler> tags around your attempts.)

I'd post the questions here but I'm not sure it wouldn't be a problem copyright wise?

I'll post my solutions here in a few days.

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!
Beyond Agile: Subsidiarity as a Team and Software Design Principle
3 direct replies — Read more / Contribute
by einhverfr
on Jul 20, 2015 at 21:24

This is a collection of thoughts I have been slowly putting together based on experience, watching the development (and often bad implementation of) agile coding practices. I am sure it will be a little controversial in the sense that some people may not see agile as something to move beyond and some may see my proposals as being agile.

## What's wrong with the Waterfall?

I think any discussion of agile programming methodologies has to start with an understanding of what problems agile was intended to solve and this has to start with the waterfall model of development, where software has a slow, deliberate life cycle, where all design decisions are supposed to be nailed down before the code is started. Basically the waterfall approach is intended to apply civil engineering practices to software and while it can work with very experienced teams in some limited areas it runs into a few specific problems.

The first is that while civil engineering projects tend to have well understood and articulated technical requirements, software projects often don't. And while cost of failure in dollars and lives for a civil engineering disaster can be high, with software it is usually only money (this does however imply that for some things, a waterfall approach is the correct one, a principle I have rarely seen argued against by experienced agile developers).

The second is that business software requirements often shift over time in ways that bridges, skyscrapers, etc don't. You can't start building a 30 floor skyscraper and then have the requirements change so that it must be at least 100 floors high. Yet we routinely see this sort of thing done in the software world.

Agile programming methodologies arose to address these problems. They are bounded concerns, not applicable to many kinds of software (for example software regulating dosage of radiotherapy would be more like a civil engineering project than like a business process tool), but the concerns do apply to a large portion of the software industry.

## How Agile is Misapplied

Many times when companies try to implement agile programming, they run into a specific set of problems. These include unstructured code and unstructured teams. This is because too many people see agile methodologies as devaluing design and responsibility. Tests are expected to be documentation, documentation is often devalued or unmaintained, and so forth.

Many experienced agile developers I have met in fact suggest that design is king, that it needs to be done right, in place, and so forth, but agile methodologies can be taken by management as devaluing documentation in favor of tests, and devaluing design in favor of functionality.

There are many areas of any piece of software where stability is good, where pace of development should be slow, and where requirements are well understood and really shouldn't be subject to change. These areas cut against the traditional agile concerns and I think require a way of thinking about the problems from outside either the waterfall or agile methodologies.

## Subsidiarity as a Team Design Principle

Subsidiarity is a political principle articulated a bit over a hundred years in a Papal encyclical. The idea is fairly well steeped in history and well applicable beyond the confines of Catholicism. The basic idea is that people have a right to accomplish things and that for a larger group to do what a smaller group can therefore constitutes a sort of moral theft. Micromanagement is therefore evil if subsidiarity is good but also it means that teams should be as small as possible, but no smaller.

In terms of team design, small teams are preferable to big teams and the key question is what a given small team can reasonably accomplish. Larger groupings of small teams can then coordinate on interfaces, etc, and sound, stable technological design can come out of this interoperation. The small team is otherwise tasked with doing everything -- design, testing, documentation. Design and testing are as integrated with software development as they are in agile, but as important as they are in the waterfall approach.

This sort of organization is as far from the old waterfall as agile is but it shares a number of characteristics with both. Design is emphasized, as is documentation (because documentation is what coordinates the teams). Stability in areas that need it is valued, but in other areas it is not. Stable contracts develop where these are important and both together and individually, accomplishments are attained.

## Subsidiarity as a Technical Design Principle

Subsidiarity in team design has to follow what folks can accomplish but this also is going to mean that these follow technological lines as well. Team responsibility has to be well aligned with technological responsibility. I.e. a team is responsible for components and components are responsible for functionality.

The teams can be thought of as providing distinct pieces of software for internal clients, taking on responsibility to do it right, and to provide something maintainable down the road. Once a piece of software is good and stable, they can continue to maintain it while moving on to another piece.

Teams that manage well defined technical and stable components can then largely end up maintaining a much larger number of such components than teams which manage pieces that must evolve with the business. Those latter teams can move faster because they have stability in important areas of their prerequisites.

But the goal is largely autonomous small teams with encapsulated responsibilities, producing software that follows that process.

text here (a paragraph)

and:  code here to format your post; it's "PerlMonks-approved HTML":

• Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
• Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
• Read Where should I post X? if you're not absolutely sure you're posting in the right place.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
• You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
 For: Use: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2015-11-27 23:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?