Re: 5 minimums for any perl script?

2012-02-03 Thread Smylers
David Cantrell writes:

 On Thu, Feb 02, 2012 at 02:57:35PM +, Smylers wrote:
 
1 Make lots of small commits, one for each separable bug, feature,
  refactoring, or whatever, and clearly described as much: make a
  commit whenever you have something which is an unambiguous
  improvement on the previous state, however small. (Unambiguous
  cos if adding a feature has temporarily broken a different one,
  that's not an improvement to somebody using the other feature;
  don't commit till you've sorted it out.)
 
 But do commit at the end of the day, even if it's still broken.  It's
 OK to break your dev branches usually,

Hmmm, I'm not sure about that.

 and you want to get the only copy of your work-in-progress off your
 personal desktop if only so it gets backed up.

If you're somewhere that already has nightly back-ups then I think I'd
prefer not to have end-of-day-regardless-how-broken commits (and pushes
as well, if you're using Git or something where a commit is only local
anyway).

Mainly because allowing broken end-of-day commits makes it seem OK for
the dev branch to be broken. Which can make people care less about their
quality of commits overall. Whereas if the policy is 'you aren't ever
supposed to break the dev branch' it's easier to get a culture of people
thinking more carefully about their commits.

Note I'm not saying 'never commit work in progress'. There's plenty of
sorts of work in progress that can be committed:

* Adding a new function to a library or method to a class can be
  committed, even if nothing (committed) uses is yet. In fact,
  _especially_ if nothing uses it yet, cos it means the function or
  method doesn't have to be finished, or even work, so long as the
  module still compiles.

* Adding a new web page, however incomplete, if nothing else links to
  it.

* New tests can be committed, marked TODO if the functionality they test
  isn't ready to be committed yet.

* Incidental small fixes, doc patches, and minor enhancements that you
  happen to spot while working on the main code can be committed. (git
  commit -p is great for this kind of thing.)

* If adding a feature involves re-arranging some existing code in order
  to prise it open and create a place where it can be added, split this
  into first doing the refactoring, and commit that.
  
  The functionality will be unchanged; at that point the code may be
  needlessly long-winded or over-engineered for what it currently does,
  but your commit message can explain why you've done it and if it is
  supposed to function identically then it's easier for a colleague to
  review you haven't inadvertently changed something when that's the
  only thing in the commit.

2 Look on Cpan for everything.

  If you think a task is in any way common or might have been done
  before, check Cpan.
 
 s/If you think.*before,//
 
 There's plenty of *un*common things on the CPAN too.

True. I used to do Perl training, and the introductory Perl course
included a section on Cpan. As well as some exercises involving modules
I knew about, people were also encouraged to search for something which
could help in their current project -- which at one client meant
somebody searching for 'Cisco'. He couldn't've been more delighted to
discover Cisco::CopyConfig, a very niche module that I certainly hadn't
encountered before.

He wasn't actually a developer but a network administrator, and had come
on the course in the hope of picking up enough Perl so he'd be able to
automate one specific task: copying configs between Cisco devices. That
afternoon he was able to knock together a program he'd been expecting
would take him weeks to write, and was my equal-happiest[*1] course
participant ever, completely amazed that Perl would have a free library
already available to do something so specific.

And I was particularly relieved: the client was a mortgage provider, and
by co-incidence happened to own more of my own home than I did, so the
potential consequences of the course going badly seemed rather more
drastic than usual ...

I was actually trying to use common above in the sense of 'something
you have in common with other organizations', as distinct from things
specific to your business. My apologies for not expressing what I meant
more clearly.

Cheers

Smylers

[*1] I'm not prepared to disclose in public what I did for my other
equal-happiest course attendee, but feel free to ask me face-to-face
sometime.


Re: 5 minimums for any perl script?

2012-02-03 Thread Dave Hodgkinson

On 3 Feb 2012, at 11:25, Smylers wrote:

 David Cantrell writes:
 
 On Thu, Feb 02, 2012 at 02:57:35PM +, Smylers wrote:
 
  1 Make lots of small commits, one for each separable bug, feature,
refactoring, or whatever, and clearly described as much: make a
commit whenever you have something which is an unambiguous
improvement on the previous state, however small. (Unambiguous
cos if adding a feature has temporarily broken a different one,
that's not an improvement to somebody using the other feature;
don't commit till you've sorted it out.)
 
 But do commit at the end of the day, even if it's still broken.  It's
 OK to break your dev branches usually,
 
 Hmmm, I'm not sure about that.

If you're doing CI on branches, you'll get to wear the pointy hat of ridicule
until you fix it.



Re: 5 minimums for any perl script?

2012-02-02 Thread Smylers
Leo Lapworth writes:

 I've been asked what would be a good minimum to have as a coding
 police for a company that isn't focused on Perl, but uses it
 occasionally.

Hi. Thanks for posing such an interesting question, Leo, and for
everybody who's contributed answers -- it's been useful to see the
variety of views on this.

When I contemplated it the coding policies I most care about a Perl dev
team following turned out to be not very Perl specific:

  1 Make lots of small commits, one for each separable bug, feature,
refactoring, or whatever, and clearly described as much: make a
commit whenever you have something which is an unambiguous
improvement on the previous state, however small. (Unambiguous cos
if adding a feature has temporarily broken a different one, that's
not an improvement to somebody using the other feature; don't commit
till you've sorted it out.)

  2 If a database is involved, spend time thinking about the table
design, preferably several of you together before any code is
written. Make sure that it represents what it is you're actually
storing.

A poorly designed database forces all code that accesses it into
awkward contortions to sort things out; it pretty much precludes you
from ever writing clean code. Whereas if the database design is good
but the code lousy, it's much easier to later clean up the code.

  3 Don't hard-code host names, absolute file paths, or similar. Always
find a way of making them relative to the current server or
directory, so that it's easy to check out multiple instances of your
codebase and run them.

  4 When designing classes try to make each class be a noun which
actually exists in the business requirements, not a made-up concept
that's an artefact of a particular implementation. Try to make
mutators be verbs that exist in the business requirements, rather
than nouns which are attributes of the class.

  5 Keep code under 80 characters wide. While this seems like a trivial
issue, when I've encountered lines that are hundreds of lines long
they also seem to suffer other issues, so forcing people to break
lines up might make people think about them and the readability of
the code a bit more.

Shorter lines also generally diff more nicely.

Those might be useful if you mean that the team in question only
occasionally do any development at all (and happen to use Perl for it).

But if it's a team of full-time developers who are adept at programming
in other languages but only occasionally use Perl then they're probably
on top of that kind of thing already and some more Perl-specific advice
would be better.

What'd be most useful to them depends which other languages they are
most familiar with, and what level they've reached with Perl. (For
example in many places use strict and use warnings goes without saying,
quite literally: it doesn't need to be said in a coding policy cos
everybody's doing it anyway.) But here's a go:

  1 Write your Perl in a way which maps to the business requirements as
closely as possible.

Perl is a very expressive language, allowing you more freedom than
most in how you express a particular instruction. For example, map,
grep, statement modifiers, and regular expressions built into the
language offer ways of expressing things not found in some other
languages. Use this to your advantage, so that it's easier to see
that the requirements and their implementation match.

  2 Look on Cpan for everything.
  
If you think a task is in any way common or might have been done
before, check Cpan. Bother to install Cpan modules even for fairly
small things which might not seem worth the hassle of installing a
module -- because doing so means the module is then installed and
available for use by other programs you write in the future too, and
collectively it is worth it.

For example it may not seem worth installing List::AllUtils just to
avoid writing your own max function, but if you do install it then
you have a handy library of common functions available.

And if you use cpanm to install modules it isn't much hassle any
more anyway.

  3 Use strict and warnings, and act on them.

If you get a warning, find out what it means. Then either fix the
issue or (if you've determined it isn't actually an issue)
deactivate the warning for that part of the code, with something
like:

  no warnings qwuninitialized;

Don't get into the habit of putting up with 'ignorable warnings'
which you're used to seeing scrolling past, and therefore
potentially missing new ones.

  4 Design for testability.

It can be awkward to graft tests into some Perl code which wasn't
designed with testing in mind in the first place. So think about
testing from the start, even if you write your tests later or don't
test everything.

In 

Re: 5 minimums for any perl script?

2012-02-02 Thread David Cantrell
On Thu, Feb 02, 2012 at 02:57:35PM +, Smylers wrote:

   1 Make lots of small commits, one for each separable bug, feature,
 refactoring, or whatever, and clearly described as much: make a
 commit whenever you have something which is an unambiguous
 improvement on the previous state, however small. (Unambiguous cos
 if adding a feature has temporarily broken a different one, that's
 not an improvement to somebody using the other feature; don't commit
 till you've sorted it out.)

But do commit at the end of the day, even if it's still broken.  It's OK
to break your dev branches usually, and you want to get the only copy of
your work-in-progress off your personal desktop if only so it gets
backed up.

   2 Look on Cpan for everything.
   
 If you think a task is in any way common or might have been done
 before, check Cpan.

s/If you think.*before,//

There's plenty of *un*common things on the CPAN too.  Some are rubbish,
of course, but others are maintained by weirdo obsessives who have
spent years agonising over the edge-cases.

 Bother to install Cpan modules even for fairly
 small things which might not seem worth the hassle of installing a
 module -- because doing so means the module is then installed and
 available for use by other programs you write in the future too, and
 collectively it is worth it.

But do remember to list it as a dependency and make sure that you add it
to whatever you use for automagically installing dependencies when you
deploy a new version of the code, or add a new developer to your team.

Think about how you'll cope with future versions of modules changing
their behaviour - this could be as a bug fix, or as a new bug, or
deprecating old behaviour which the author has decided to no longer
support, or ...

-- 
David Cantrell | A machine for turning tea into grumpiness

It's my experience that neither users nor customers can articulate
what it is they want, nor can they evaluate it when they see it
-- Alan Cooper


Re: 5 minimums for any perl script?

2012-01-30 Thread Kaoru
On Sun, Jan 29, 2012 at 9:02 PM, Leo Lapworth l...@cuckoo.org wrote:
 I've been asked what would be a good minimum to have as a coding police
 for a company that isn't focused on Perl, but uses it occasionally. So if
 Perl Best Practices is too much, and you could only have 5 rules for any
 perl script, what would they be?

Here goes then...

1) Have sensible exit codes

0 on success, 1 on failure. You can use exit() and die() in Perl to
get this right.

Be careful with usage messages. If I ask for help with --help then
that's a good (zero) exit, if I mess up and get the flags wrong that's
a bad (non-zero) exit.

==

2) Have a good --help message

Where possible/sensible the usage message should be printed by default
if no flags are given at all, ie. the script should not do anything if
you run it blind.

I usually use Pod::Usage and Getopt::Long together to get this.

use Getopt::Long;
use Pod::Usage;
GetOptions('help|h' = sub { pod2usage(0); });

=head1 NAME

...

=head1 SYNOPSIS

...

==

3) Pass at least Perl::Critic severity level 4 (stern.)

This gets you use strict and use warnings for free, along with a
host of other good practices :-)

==

4) Modularize for unit testability

Where possible the script itself should contain very little logic. A
good template is:

use strict;
use warnings;

use My::Script::Module;

use Getopt::Long;
use Pod::Usage;

GetOptions(
...
);

my $Obj = My::Script::Module-new(...);

$Obj-run();

exit 0;


Note that you can use pod2usage(-input = My/Script/Module.pm);

If you want to keep your docs close to the actual code.

Inside My::Script::Module split up the code into logical segments that
are easily unit tested, and of course write those unit tests!

==

5) Consider the script's audience carefully when deciding on the
amount and level of output

I think there are probably two kinds of scripts - one is designed to
be run via cron, and the other is designed to be run by a person.

For the designed to be run by a person scripts use say(),
Term::ProgressBar, IO::Prompter, Term::ANSIColor, etc to make the
output and interactivity as user-friendly as a Perl script can
possibly be.

For the cron (etc.) scripts make them silent, or use Log::Log4perl
or similar to log to a file. However consider also providing a run by
a person mode (via a --verbose or --debug flag) where it gives good
output to the terminal too. You'll use it one day :-)


- Alex


Re: 5 minimums for any perl script?

2012-01-30 Thread Abigail
On Sun, Jan 29, 2012 at 06:34:06PM -0500, Joseph Werner wrote:
  So if Perl Best Practices is too much, and you could only have 5 rules
  for any perl script, what would they be?
   ...
  3. Strictures: Always 'use strict' (and 'use warnings' during development) 
  and
    explicitly state your minimum Perl version requirement. (e.g. 'use v5.10')
    [Ch18: Strictures, Warnings]
 
 I will agree with always 'use strict', I have never [yet] had to not
 'use warnings' AFTER development.

Funny. If I have to pick between strict and warnings in production, I'd
pick warnings each and every time. 

I cannot remember ever having something in production which is then tripped
by the run time effects of strict (except trying to dereference an undefined
value, but see next sentence). But I see the run time effects of warnings
(usually in the form of uninitialized value) all the time.

Now, the compile time effects of use warnings, I can easily live without.
In fact, some of them I disable right away; I always follow my use warnings;
by a no warnings 'syntax';.

 Explicitly stating minimum Perl version requirement does not rise to
 the same level of concern as  'use strict'  and 'use warnings'.  How
 often do you regression test to know the minimum Perl version
 requirement anyhow?


It depends who the code is for *and* for its side effects. For $WORK code,
I don't bother with supplying a version. We're on 5.8.5; writing code that
doesn't work with it is pointless, and we have to plans to revert to 5.6.

However, soon we should be on 5.14.x. Then I'll be using use 5.010 (or
some higher number), but not so much as to signal a minimum version. But
since 5.010, use 5.XXX will have side effects. In particular, use 5.010
enables the say, given and state features.

For CPAN code however, I typically do supply a use $MINIMUM_VERSION to
signal the minimem required version. And I do have some old perls on my
system so I can test against them.



Abigail


Re: 5 minimums for any perl script?

2012-01-30 Thread David Cantrell
On Sun, Jan 29, 2012 at 09:02:41PM +, Leo Lapworth wrote:

 I've been asked what would be a good minimum to have as a coding police
 for a company that isn't focused on Perl, but uses it occasionally. So if
 Perl Best Practices is too much, and you could only have 5 rules for any
 perl script, what would they be?
 
 (let's assume recent 5.10+?)
 
 Mine:
 
 1) use strict; use warnings;
 - obvious why
 
 2) all files to be perl tidied (ideally automatically)
 - it makes reading code easier, as long as there is a standard
 
 3) All variable names to be clear about what they contain, no short
 variable names unless in a small loop (e.g. $i)
 - But I know $e means doesn't help me in reading code
 
 4) use Path::Class and always keep files/dirs as Path::Class objects
 as long as possible
 - this is a strange one, but it's more about being consistent and having
   $file-slurp; $file-openw() $dir-mkpath(). It seems to make code
 cleaner, others have
   suggested IO::Any, but that still has missing / odd behaviour for my
 liking at the moment
 
 5) Always ask one other person to review your code

I disagree strongly with 2 and 4.  They're nice to have, but nothing
like as important as things like:

* use a version control system
* always write documentation

-- 
David Cantrell | http://www.cantrell.org.uk/david

Deck of Cards: $1.29.
101 Solitaire Variations book: $6.59.
Cheap replacement for the one thing Windows is good at: priceless
-- Shane Lazarus


Re: 5 minimums for any perl script?

2012-01-30 Thread David Cantrell
On Mon, Jan 30, 2012 at 11:07:53AM +1100, Damian Conway wrote:

 This advice is mainly because there are still an absurd number of people
 stuck on 5.8 (for perfectly good reasons), which version I now no longer
 support. A simple 'use 5.010' in the code avoids an endless amount of
 fruitless email discussion and cajoling about my decision to treat 5.10
 (and soon, 5.12) as my minimal supported platform.

I used to bitch and moan about authors who did this.  Then I STFU and
wrote some code.  I'm surprised how few people use cpXXXan, it was
written for those people who can't easily upgrade their perl.

-- 
David Cantrell | A machine for turning tea into grumpiness

One person can change the world, but most of the time they shouldn't
-- Marge Simpson


Re: 5 minimums for any perl script?

2012-01-30 Thread Dominic Humphries
On Sun, Jan 29, 2012 at 09:02:41PM +, Leo Lapworth wrote:

 2) all files to be perl tidied (ideally automatically)

How do people recommend setting up automatic perltidy? I've been
considering setting it up so vim would perltidy any time I save a file
with filetype perl. Or maybe tying it to a git hook.

Cheers

djh 



Re: 5 minimums for any perl script?

2012-01-30 Thread Dominic Thoreau
On 30 January 2012 13:04, Dominic Humphries d...@thermeon.com wrote:
 On Sun, Jan 29, 2012 at 09:02:41PM +, Leo Lapworth wrote:

 2) all files to be perl tidied (ideally automatically)

 How do people recommend setting up automatic perltidy? I've been
 considering setting it up so vim would perltidy any time I save a file
 with filetype perl. Or maybe tying it to a git hook.

The issue I have with perltidy, nice as it is, is that just making it
a rule can be problematic with existing untidy code bases.

Untidy code + small change = unrelated blame attaches to unfortunate developer.

If you were writing new code, yes perl tidy is good, but you can't
always force it.
-- 
Nonnullus unus commodo reddo is mihi.
ABC*D1EFGHIJK2.LMNO3*4PQRST*ITUBE-STANDARD-ANTI-BULLSHEIT-EMAIL*U.56X


Re: 5 minimums for any perl script?

2012-01-30 Thread Guinevere Nell
I would suggest that Perl::Critic, version control, and modularization
combined with use of perldoc (instead of just comments with hoped for
documentation to be made later/never) and make when a project is ready for
production allow a high coding standard. If incorporated from the start
they are easy to work with, and they encourage/force the programmers to
keep readable, tidy, documented code.

On Mon, Jan 30, 2012 at 1:04 PM, Dominic Humphries d...@thermeon.com wrote:

 On Sun, Jan 29, 2012 at 09:02:41PM +, Leo Lapworth wrote:

  2) all files to be perl tidied (ideally automatically)

 How do people recommend setting up automatic perltidy? I've been
 considering setting it up so vim would perltidy any time I save a file
 with filetype perl. Or maybe tying it to a git hook.

 Cheers

 djh




-- 
http://economicliberty.net/


Re: 5 minimums for any perl script?

2012-01-30 Thread Gareth Kirwan

On 30/01/12 13:46, Dominic Thoreau wrote:
The issue I have with perltidy, nice as it is, is that just making it 
a rule can be problematic with existing untidy code bases. Untidy code 
+ small change = unrelated blame attaches to unfortunate developer. If 
you were writing new code, yes perl tidy is good, but you can't always 
force it. 


I envision one big perltidy commit to the codebase as the solution to 
that.


I also generally strongly recommend that all commits should separate out 
prerequisite changes from commits.

Fix indentation separately.
Rename a variable everywhere separately.
Now finish the code you were writing when you started that yak.




Re: 5 minimums for any perl script?

2012-01-30 Thread Sam Kington
On 30 Jan 2012, at 13:50, Guinevere Nell wrote:

 I would suggest that Perl::Critic, version control, and modularization
 combined with use of perldoc (instead of just comments with hoped for
 documentation to be made later/never) and make when a project is ready for
 production allow a high coding standard. If incorporated from the start
 they are easy to work with, and they encourage/force the programmers to
 keep readable, tidy, documented code.


One problem with perlcritic is that many of its rules, out of the box, are 
silly and annoying. You need to do a fair amount of tweaking to stop it 
bitching about stuff you don't care about, before you can get to the bits where 
it's actually useful. Here's $WORK's standard perlcriticrc:

severity = brutal
# Tell us which rule this violated, so we can tell it to fuck off.
verbose  = [%p] %m at %f line %l, near '%r'\n

### Git
# We use git, not svn or RCS
[-Miscellanea::RequireRcsKeywords]

# We'll enforce dependencies in other ways, rather than magically putting
# a $VERSION variable in modules.
[-Modules::RequireVersionVar]

### Modern Perl
# We'll run on at least perl 5.10
[Compatibility::PodMinimumVersion]
above_version = 5.010

### Chimera style
# No, you don't need to double-quote heredocs
[-ValuesAndExpressions::RequireQuotedHeredocTerminator]

# We *do* mean the difference between low- and high-precedence operators.
[-ValuesAndExpressions::ProhibitMixedBooleanOperators]

# Perltidy is a judgement call.
[-CodeLayout::RequireTidyCode]

# Damian Conway's insistence that the literal '' or  in a proper
# monospaced font is difficult to read is frankly bizarre.
[-ValuesAndExpressions::ProhibitEmptyQuotes]
[-ValuesAndExpressions::ProhibitNoisyQuotes]

# There's muscle memory of always adding /xms to a regex, and then there's
# typing for the hell of it.
[-RegularExpressions::RequireDotMatchAnything]
[-RegularExpressions::RequireLineBoundaryMatching]

# Inline POD is good, dammit.
[-Documentation::RequirePodAtEnd]

# These are internal Perl modules. They don't need all these sections.
[-Documentation::RequirePodSections]

### We'll check this via code review, rather than automated tools.
# PPI can't tell the difference between methods (fine to use e.g. delete)
# and subroutines (might trigger the indirect access mechanism by mistake),
# so this rule is useless.
[-Subroutines::ProhibitBuiltinHomonyms]

# This rule is also useless, as it doesn't know about named captures.
[-RegularExpressions::ProhibitUnusedCapture]

# Named captures also break this one.
[-Variables::ProhibitPunctuationVars]

# Tacit return values, or situations where it doesn't matter, are fine.
[-Subroutines::RequireFinalReturn]

# Similarly, if it compiles, who the hell cares what the last value was?
[-Modules::RequireEndWithOne]

# Double-sigil dereferences are almost certainly fine. The examples of bad
# stuff in PBP are straw men.
[-References::ProhibitDoubleSigils]

# Accessors that look at @_ before doing things are fine.
[-Subroutines::RequireArgUnpacking]

# Unless blocks are fine, possibly.
[-ControlStructures::ProhibitUnlessBlocks]

# Let a human decide whether range comparisons in an unless block are fine
[-ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions]

# Likewise postfix if et al
[-ControlStructures::ProhibitPostfixControls]

# Some few modules need global variables. Let a human decide.
[-Variables::ProhibitPackageVars]

# Let use warnings warn about reusing a variable at the same lexical scope;
# this rule warns about reusing at a different scope, which is potentially
# fine.
[-Variables::ProhibitReusedNames]

# A lot of our code deals with pure ASCII. This stuff is probably fine.
[-RegularExpressions::ProhibitEnumeratedClasses]

# That trailing comma warning is annoying. Shut up.
[-CodeLayout::RequireTrailingCommaAtNewline]

# Don't require a final semicolon either.
[-CodeLayout::RequireFinalSemicolon]

# Far more numbers than 0, 1 and 2 are acceptable, but I can't be bothered
# configuring them. So, shut up. Code review will deal with this.
[-ValuesAndExpressions::ProhibitMagicNumbers]

# A blanket ban on parentheses around builtins is annoying, and over-zealous.
[-CodeLayout::ProhibitParensWithBuiltins]

# Putting braces around file handle objects is reasonable.
# Putting braces around bareword file handles like STDERR is frankly daft.
[-InputOutput::RequireBracedFileHandleWithPrint]

# reverse sort @array is indeed better than
# sort { $b cmp $a } @array
# I'm not so sure about hating on $b vs $a in e.g.
# sort { $b-{stuff} = $a-{stuff} }
[-BuiltinFunctions::ProhibitReverseSortBlock]

# This is overridden by the better rule RequireCheckedSyscalls
[-InputOutput::RequireCheckedClose]

# Nobody (hopefully) thinks that prototypes allow argument-checking.
# But they do allow syntactic sugar, which is why we use them in e.g. Moose.
[-Subroutines::ProhibitSubroutinePrototypes]

# This alerts unnecessarily for e.g. $foo = $1 if /.../ so skip it.

Re: 5 minimums for any perl script?

2012-01-30 Thread Paul Johnson
On Mon, Jan 30, 2012 at 03:00:00PM +, Sam Kington wrote:

 One problem with perlcritic is that many of its rules, out of the box, are 
 silly and annoying. You need to do a fair amount of tweaking to stop it 
 bitching about stuff you don't care about, before you can get to the bits 
 where it's actually useful. Here's $WORK's standard perlcriticrc:

I wouldn't argue with most of those (though I don't use perlcritic
myself anyway) but

 # Checking return values is a good thing. Checking the return value of
 # close or print STDERR is downright silly.
 [InputOutput::RequireCheckedSyscalls]
 functions = :builtins
 exclude_functions = print close

could you explain why you think checking the return value of close() is
silly?  I tend to have the opposite opinion.

-- 
Paul Johnson - p...@pjcj.net
http://www.pjcj.net


Re: 5 minimums for any perl script?

2012-01-30 Thread Paul Makepeace
On Mon, Jan 30, 2012 at 15:00, Sam Kington s...@illuminated.co.uk wrote:
 # Checking return values is a good thing. Checking the return value of
 # close or print STDERR is downright silly.

You've clearly not done much IPC…

P



Re: 5 minimums for any perl script?

2012-01-30 Thread Mike Whitaker

On 30 Jan 2012, at 15:26, Paul Johnson wrote:

 could you explain why you think checking the return value of close() is
 silly?  I tend to have the opposite opinion.

I don't have the slides of the talk I gave on Defensive Perl Programming a 
couple of years ago, but there's a definite case or two of printing to a 
*socket* that can cause the print to fail when the far end goes away.

Re: 5 minimums for any perl script?

2012-01-30 Thread Sam Kington

On 30 Jan 2012, at 15:26, Paul Johnson wrote:
 On Mon, Jan 30, 2012 at 03:00:00PM +, Sam Kington wrote:
 One problem with perlcritic is that many of its rules, out of the box, are 
 silly and annoying. You need to do a fair amount of tweaking to stop it 
 bitching about stuff you don't care about, before you can get to the bits 
 where it's actually useful. Here's $WORK's standard perlcriticrc:
 
 I wouldn't argue with most of those (though I don't use perlcritic
 myself anyway) but
 
 # Checking return values is a good thing. Checking the return value of
 # close or print STDERR is downright silly.
 [InputOutput::RequireCheckedSyscalls]
 functions = :builtins
 exclude_functions = print close
 
 could you explain why you think checking the return value of close() is
 silly?  I tend to have the opposite opinion.


In the code that we write at $WORK, any filehandle we close tends to be a log 
file or something, so adding extra boilerplate to our close statements would 
just be annoying.

Similarly, if we've managed to open a random file on the local filesystem for 
output, it seems slightly silly to check the return value of print every single 
time. If it was going to fail, it would have failed on the open call; adding 
boilerplate to every subsequent print statement just makes the code verbose and 
messy for no good reason.

If we were doing anything at all intricate, regularly, then yeah, I'd re-enable 
this warning. But for simple filehandles on a local filesystem, IMO it's 
overkill.

Sam
-- 
Website: http://www.illuminated.co.uk/




Re: 5 minimums for any perl script?

2012-01-30 Thread Mike Whitaker

On 30 Jan 2012, at 15:40, Sam Kington wrote:

 In the code that we write at $WORK, any filehandle we close tends to be a log 
 file or something, so adding extra boilerplate to our close statements would 
 just be annoying.

use 5.10;
use autodie;

perhaps?

Re: 5 minimums for any perl script?

2012-01-30 Thread Mark Fowler
On Mon, Jan 30, 2012 at 3:40 PM, Sam Kington s...@illuminated.co.uk wrote:

 # Checking return values is a good thing. Checking the return value of
 # close or print STDERR is downright silly.

 In the code that we write at $WORK, any filehandle we close tends to be a log 
 file or something, so adding extra boilerplate to our close statements would 
 just be annoying.

Why are you doing this by hand?  Why aren't you letting autodie handle
this for you?

Mark.


Re: 5 minimums for any perl script?

2012-01-30 Thread Sam Kington
On 30 Jan 2012, at 15:44, Mike Whitaker wrote:
 On 30 Jan 2012, at 15:40, Sam Kington wrote:
 
 In the code that we write at $WORK, any filehandle we close tends to be a 
 log file or something, so adding extra boilerplate to our close statements 
 would just be annoying.
 
 use 5.10;
 use autodie;
 
 perhaps?


If that makes perlcritic shut up, possibly. Although I suspect it wouldn't - we 
tend to put common pragmas like that in our internal our::way module, which 
also does things like enabling strictures and (most) warnings, unicode strings, 
English variables, etc. etc. in the calling package. So perlcritic wouldn't see 
autodie in the source and would still bitch and moan.

Sam
-- 
Website: http://www.illuminated.co.uk/




Re: 5 minimums for any perl script?

2012-01-30 Thread Mark Fowler
On Sun, Jan 29, 2012 at 11:11 PM, Damian Conway dam...@conway.org wrote:

 3. Strictures: Always 'use strict' (and 'use warnings' during development) and
   explicitly state your minimum Perl version requirement. (e.g. 'use v5.10')
   [Ch18: Strictures, Warnings]

I'd point out that if you state a reasonably modern version of Perl
you don't need to turn on strict, it's turned on for you.  If you use
Moose (or several other modules out there) then warnings get turned on
for you too.

At $work in our key codebase we find demanding all these strictures
tiresome.  We instead have a standard line that you need to put this
into your source:

 use OurSecretProjectName::Strict;

(If you don't the test suite will fail and our build system will get
angry with you.)  This module turns on a bunch of handy strictures:

package OurSecretProjectName::Strict;

use strict;
use warnings;
no indirect 0.24 :fatal;
no multidimensional 0.008;
use Sub::StrictDecl 0.003;

sub import {
strict-import;
warnings-import;
indirect-unimport(:fatal);
multidimensional-unimport;
Sub::StrictDecl-import;
}

sub unimport {
strict-unimport;
warnings-unimport;
indirect-import;
multidimensional-import;
Sub::StrictDecl-unimport;
}

1;



Re: 5 minimums for any perl script?

2012-01-30 Thread Mike Whitaker

On 30 Jan 2012, at 16:28, Mark Fowler wrote:

 On Sun, Jan 29, 2012 at 11:11 PM, Damian Conway dam...@conway.org wrote:
 
 3. Strictures: Always 'use strict' (and 'use warnings' during development) 
 and
   explicitly state your minimum Perl version requirement. (e.g. 'use v5.10')
   [Ch18: Strictures, Warnings]
 
 I'd point out that if you state a reasonably modern version of Perl
 you don't need to turn on strict, it's turned on for you.  If you use
 Moose (or several other modules out there) then warnings get turned on
 for you too.
 
 At $work in our key codebase we find demanding all these strictures
 tiresome.  We instead have a standard line that you need to put this
 into your source:
 
 use OurSecretProjectName::Strict;
 
 (If you don't the test suite will fail and our build system will get
 angry with you.)  This module turns on a bunch of handy strictures:



You could perhaps add 

$ENV{PERL_UNICODE} = AS;
use open qw/:encoding(UTF-8) :std/;
use warnings qw/FATAL utf8/;
use feature qw/unicode_strings/;

but that might be considered optimistic, depending on the state of your 
codebase!


Re: 5 minimums for any perl script?

2012-01-30 Thread Mark Fowler
On Mon, Jan 30, 2012 at 4:21 PM, Sam Kington s...@illuminated.co.uk wrote:

 If that makes perlcritic shut up, possibly.

Once you no longer need that to happen in your code (because it
happens automatically) you can remove the Perl::Critic policy that
complains about that for you.  As long as you're checking for your
global strictures module being present, you know you're good.

Mark.


Re: 5 minimums for any perl script?

2012-01-30 Thread Paul Johnson
On Mon, Jan 30, 2012 at 04:19:19PM +, Mark Fowler wrote:
 On Mon, Jan 30, 2012 at 3:40 PM, Sam Kington s...@illuminated.co.uk wrote:
 
  # Checking return values is a good thing. Checking the return value of
  # close or print STDERR is downright silly.
 
  In the code that we write at $WORK, any filehandle we close tends to be a 
  log file or something, so adding extra boilerplate to our close statements 
  would just be annoying.
 
 Why are you doing this by hand?  Why aren't you letting autodie handle
 this for you?

What we really need is for autodie to work on the implicit close on a
lexical filehandle going out of scope.

Someone please write that.

And then fix up all the little bits and bobs around the edges.

-- 
Paul Johnson - p...@pjcj.net
http://www.pjcj.net


Re: 5 minimums for any perl script?

2012-01-29 Thread Pedro Figueiredo

On 29 Jan 2012, at 21:02, Leo Lapworth wrote:

 Mine:
 
 1) use strict; use warnings;
 - obvious why
 
 2) all files to be perl tidied (ideally automatically)
 - it makes reading code easier, as long as there is a standard
 
 3) All variable names to be clear about what they contain, no short
 variable names unless in a small loop (e.g. $i)
 - But I know $e means doesn't help me in reading code
 
 4) use Path::Class and always keep files/dirs as Path::Class objects
 as long as possible
 - this is a strange one, but it's more about being consistent and having
  $file-slurp; $file-openw() $dir-mkpath(). It seems to make code
 cleaner, others have
  suggested IO::Any, but that still has missing / odd behaviour for my
 liking at the moment
 
 5) Always ask one other person to review your code
 
 What would yours be?

These, plus 

6) use App::Cmd (makes testing scripts a doozie, gives you getopt and help for 
free, and it's really easy to extend).

7) use Readonly.

8) *really* have a look in Task::Kensho.

Cheers,

Pedro


Re: 5 minimums for any perl script?

2012-01-29 Thread Greg McCarroll

I'm afraid i'm going to be boring and suggest some business requirements.

In comments or pod, note the following:

When you are doing this (even if version control can tell people), and who you 
are.

Why? if there is a long worded document/spec, at least give its name. Check it 
in under version control even if your BOFH growls at you.

Who for? Sales, accounting, etc.  Name them.

Concerns/risks.

Basically build up a context of why you are about to unleash this script on the 
world that today might be a one off, but next year might be a nightly cron job.

G.


On 29 Jan 2012, at 21:02, Leo Lapworth wrote:

 Hi,
 
 I've been asked what would be a good minimum to have as a coding police
 for a company that isn't focused on Perl, but uses it occasionally. So if
 Perl Best Practices is too much, and you could only have 5 rules for any
 perl script, what would they be?
 
 (let's assume recent 5.10+?)
 
 Mine:
 
 1) use strict; use warnings;
 - obvious why
 
 2) all files to be perl tidied (ideally automatically)
 - it makes reading code easier, as long as there is a standard
 
 3) All variable names to be clear about what they contain, no short
 variable names unless in a small loop (e.g. $i)
 - But I know $e means doesn't help me in reading code
 
 4) use Path::Class and always keep files/dirs as Path::Class objects
 as long as possible
 - this is a strange one, but it's more about being consistent and having
  $file-slurp; $file-openw() $dir-mkpath(). It seems to make code
 cleaner, others have
  suggested IO::Any, but that still has missing / odd behaviour for my
 liking at the moment
 
 5) Always ask one other person to review your code
 
 What would yours be?
 
 Leo




Re: 5 minimums for any perl script?

2012-01-29 Thread Damian Conway
 So if Perl Best Practices is too much, and you could only have 5 rules
 for any perl script, what would they be?

Can I have six, please Sir???

These are in decreasing order of bang for your buck
[and with PBP references, in case PBP *isn't* too much]...


1. Commenting: Code in commented paragraphs.
   [Ch2: Chunking]

2. Layout: Agree upon a single coherent layout style and automate it
with 'perltidy'.
   [Ch2: Automated Layout]

3. Strictures: Always 'use strict' (and 'use warnings' during development) and
   explicitly state your minimum Perl version requirement. (e.g. 'use v5.10')
   [Ch18: Strictures, Warnings]

4. Naming: Use grammatical templates of at least two words when forming
   identifiers (or at least those whose scope extends beyond a single block).
   (e.g. 'adj_noun' for vars, 'verb_noun' for subs)
   [Ch3: Identifiers]

5. Subroutine APIs: In a subroutine, always unpack @_ first (using named args
if there are more than three parameters), and always return via an
explicit 'return'.
   [Ch9: Argument Lists, Named Arguments, Implicit Returns]

6. Regexes: Always use the '/x' flag and named captures, and if the regex
   is complex, factor components out into independent named subpatterns.
   [Ch12: Extended Formatting, no refs for the named stuff (which
post-dates PBP)]


Damian


Re: 5 minimums for any perl script?

2012-01-29 Thread Joseph Werner
 So if Perl Best Practices is too much, and you could only have 5 rules
 for any perl script, what would they be?
  ...
 3. Strictures: Always 'use strict' (and 'use warnings' during development) and
   explicitly state your minimum Perl version requirement. (e.g. 'use v5.10')
   [Ch18: Strictures, Warnings]

I will agree with always 'use strict', I have never [yet] had to not
'use warnings' AFTER development.
Explicitly stating minimum Perl version requirement does not rise to
the same level of concern as  'use strict'  and 'use warnings'.  How
often do you regression test to know the minimum Perl version
requirement anyhow?

Grateful for the lessons in BPB in any event.

-- 
Best Regards,
[Joseph] Christian Werner Sr
C 360.920.7183
H 757.304.0502



Re: 5 minimums for any perl script?

2012-01-29 Thread David Alban
don't use subroutine prototypes unless you've read about them and know
what you're doing.

On Sun, Jan 29, 2012 at 3:34 PM, Joseph Werner telco...@gmail.com wrote:
 So if Perl Best Practices is too much, and you could only have 5 rules
 for any perl script, what would they be?

-- 
Live in a world of your own, but always welcome visitors.
***
Rule of law is for the little people.
http://www.amazon.com/Liberty-Justice-Some-Equality-Powerful/dp/0805092056


Re: 5 minimums for any perl script?

2012-01-29 Thread Damian Conway
Joseph Werner wrote:

 I will agree with always 'use strict', I have never [yet] had to not
 'use warnings' AFTER development.

If your test suite's code coverage is thorough and your tests closely
mimic your users' real-world usages, then I agree that leaving warnings
on in deployed code does no harm at all.

But if your testing doesn't meet those criteria, warnings in production
code can result in a horde of anxious users reporting ABSOLUTELY
CRITICAL Use of undefined value bugs, which results in needless
anxiety for everyone concerned.


 Explicitly stating minimum Perl version requirement does not rise to
 the same level of concern as  'use strict'  and 'use warnings'.  How
 often do you regression test to know the minimum Perl version
 requirement anyhow?

I'm not suggesting that you state *the* minimum version requirement,
I'm suggesting you state *your* minimum version requirement.

The easiest way not to be deluged with a bucketload of This doesn't
work under our current installation of Perl 5.6.1 is to document
and enforce whatever version you developed your code under as the
minimum version required.

This advice is mainly because there are still an absurd number of people
stuck on 5.8 (for perfectly good reasons), which version I now no longer
support. A simple 'use 5.010' in the code avoids an endless amount of
fruitless email discussion and cajoling about my decision to treat 5.10
(and soon, 5.12) as my minimal supported platform.

A 'use VERSION' is also future-proofing, given the changes in
behaviour that have been mooted for future versions of the compiler
(namely that, as far as possible, future versions of perl may
endeavour to provide the semantics of whichever Perl version
is explicitly specified in the source).

Damian



Re: 5 minimums for any perl script?

2012-01-29 Thread Damian Conway
 don't use subroutine prototypes unless you've read about them and know
 what you're doing.

Damn straight.

But I'd also add: even if you *have* read about them and think you know
what you're doing...think again. ;-)

Even when used correctly, prototypes change the behaviour of client code
in mostly invisible ways...which is almost never a good idea.

Using a (@) prototype to allow something like:

apply_functor { functor } @data

is okay, as the new semantics are explicitly marked by the block.

But almost any other prototype components are going to make
ordinary-looking client code silently magical, so that something like:

defenestrate_clients(@client_data)

has invisibly different semantics. That is not fine because now you
can't tell how that code behaves just by looking at it. :-(

Damian