Re: 5 minimums for any perl script?
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?
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
[ANNOUNCE] London Perl M[ou]ngers October Social - 2012-02-02 - Somers Town Coffee House, Euston, NW1 1HS
Hi all, The London.pm February social will be on Thursday the 2nd, at the Somers Town Coffee House, just around the corner from Euston station (now under new management). Somers Town Coffee House 60 Chalton Street Euston, NW1 1HS http://london.randomness.org.uk/wiki.cgi?Somers_Town_Coffee_House,_NW1_1HS Unfortunately I can't make it, but don't let that stop you turning up, or maybe it will encourage more people to turn up, either way, have fun :) Standard blurb: Social meets are a chance for the various members of the group to meet up face to face and chat with each other about things - both Perl and (mostly) non-Perl - and newcomers are more than welcome. The monthly meets tend to be bigger than the other ad hoc meetings that take place at other times, and we make sure that they're in easy to get to locations and the pub serves food (meaning that people can eat in the bar if they want to). They normally start around 6.30pm (or whenever people get there after work) and a group tends to be left come closing time.
Re: 5 minimums for any perl script?
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?
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?
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?
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?
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?
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: [ANNOUNCE] London Perl M[ou]ngers October Social - 2012-02-02 - Somers Town Coffee House, Euston, NW1 1HS
[ANNOUNCE] London Perl M[ou]ngers October Social - 2012-02-02 - Somers Town Coffee House, Euston, NW1 1HS Gives a new interpretation to Template::Manual, heh :) That night's also my leaving dinner so if anyone fancies popping along to Wong Kei's beforehand 7pm or after for pints, do drop by: https://www.facebook.com/events/357889180907264/ Paul On Mon, Jan 30, 2012 at 12:41, Leo Lapworth l...@cuckoo.org wrote: Hi all, The London.pm February social will be on Thursday the 2nd, at the Somers Town Coffee House, just around the corner from Euston station (now under new management). Somers Town Coffee House 60 Chalton Street Euston, NW1 1HS http://london.randomness.org.uk/wiki.cgi?Somers_Town_Coffee_House,_NW1_1HS Unfortunately I can't make it, but don't let that stop you turning up, or maybe it will encourage more people to turn up, either way, have fun :) Standard blurb: Social meets are a chance for the various members of the group to meet up face to face and chat with each other about things - both Perl and (mostly) non-Perl - and newcomers are more than welcome. The monthly meets tend to be bigger than the other ad hoc meetings that take place at other times, and we make sure that they're in easy to get to locations and the pub serves food (meaning that people can eat in the bar if they want to). They normally start around 6.30pm (or whenever people get there after work) and a group tends to be left come closing time.
Re: [ANNOUNCE] London Perl M[ou]ngers October Social - 2012-02-02 - Somers Town Coffee House, Euston, NW1 1HS
On 30 Jan 2012, at 14:08, Paul Makepeace wrote: [ANNOUNCE] London Perl M[ou]ngers October Social - 2012-02-02 - Somers Town Coffee House, Euston, NW1 1HS Gives a new interpretation to Template::Manual, heh :) That night's also my leaving dinner so if anyone fancies popping along to Wong Kei's beforehand 7pm or after for pints, do drop by: https://www.facebook.com/events/357889180907264/ I believe the food at the Coffee House is quite good :)
Re: 5 minimums for any perl script?
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?
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?
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?
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?
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?
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: Tech Talk Slides
On Fri, Jan 27, 2012 at 1:11 PM, Leo Lapworth l...@cuckoo.org wrote: Those interested in this sort of thing might also want to check out https://metacpan.org/module/Test::WWW::Selenium::More (https://github.com/kablamo/Test-WWW-Selenium-More) Leo, this is awesome. Thanks! I've just switched our base class to it now. Is the canonical version in github? In other words if I fork and patch away (e.g. with some documentation?) that's good? Mark.
Re: 5 minimums for any perl script?
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?
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?
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?
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?
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.
The proper way to open()
What's a good way of opening a file as read-only, and failing if it doesn't exist? open() just returns a handle that's not obviously invalid, which strikes me as odd behaviour. At the moment I'm doing something like: open IN,$cfg; if (eof IN) { die bad config file $cfg\n; } R
Re: The proper way to open()
On Mon, Jan 30, 2012 at 04:46:00PM +, Roger Burton West wrote: What's a good way of opening a file as read-only, and failing if it doesn't exist? open() just returns a handle that's not obviously invalid, which strikes me as odd behaviour. At the moment I'm doing something like: open IN,$cfg; if (eof IN) { die bad config file $cfg\n; } die Bad config file $cfg unless open my $ih, , $cfg; Abigail
Re: 5 minimums for any perl script?
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: The proper way to open()
On 30 January 2012 16:46, Roger Burton West ro...@firedrake.org wrote: What's a good way of opening a file as read-only, and failing if it doesn't exist? open() just returns a handle that's not obviously invalid, which strikes me as odd behaviour. At the moment I'm doing something like: open IN,$cfg; if (eof IN) { die bad config file $cfg\n; } open IN, '', $cfg || handle_that_error_sub; # where sub handle_that_error itself calls die with $! . Also gives you some possibility of doing cleaningup. -- Nonnullus unus commodo reddo is mihi. ABC*D1EFGHIJK2.LMNO3*4PQRST*ITUBE-STANDARD-ANTI-BULLSHEIT-EMAIL*U.56X
Re: The proper way to open()
On 30 Jan 2012, at 16:46, Roger Burton West wrote: What's a good way of opening a file as read-only, and failing if it doesn't exist? open() just returns a handle that's not obviously invalid, which strikes me as odd behaviour. At the moment I'm doing something like: open IN,$cfg; if (eof IN) { die bad config file $cfg\n; } R -r $file (readability test) is a good start, and checking the return value of open is a solution (just using -r would of course introduce a race condition). Autodie is also brilliant for avoiding having to write this: open(...) or die(...) as it will implicitly write the latter half of that for you. Two things: - There is a 3 argument form of open -- open(FH,'',$file) -- which is a good idea to use. - Using a lexical filehandle as opposed to a bareword one makes everything shiny and nice /j
Re: The proper way to open()
On Mon, Jan 30, 2012 at 04:46:00PM +, Roger Burton West wrote: What's a good way of opening a file as read-only, and failing if it doesn't exist? open() just returns a handle that's not obviously invalid, which strikes me as odd behaviour. Why not just check the return value from open()? $ perl -e 'open(FOO, doesnt_exist) || die(Bad programmer, no bikkit!\n)' Bad programmer, no bikkit! But note that this is indistinguishable from it failing to open because, eg, you don't have permission, so also check $! which gives a useful string in string context and whatever C's errno is in numeric context. Or check for file existence / readability first, using -whatever. -- David Cantrell | A machine for turning tea into grumpiness Vegetarian: n: a person who, due to malnutrition caused by poor lifestyle choices, is eight times more likely to catch TB than a normal person
Re: The proper way to open()
Bah. Thanks to Abigail. I'd done it as open ... || die ... and that hadn't worked, but that was because the || was binding more tightly than the open; open (...) || die works perfectly well. I really must get that faster brain...
Re: The proper way to open()
On 30 Jan 2012, at 16:56, Dominic Thoreau wrote: open IN, '', $cfg || handle_that_error_sub; No, explicitly not. The || operator is far too high precedence binding. Use 'or' to remove your bug. /j
Re: The proper way to open()
On Mon, Jan 30, 2012 at 04:56:53PM +, Dominic Thoreau wrote: open IN, '', $cfg || handle_that_error_sub; OK, that's the same error I was making, so I'll point out that this will not fail as desired, but open (IN, '', $cfg) || handle_that_error_sub; will. R
Re: The proper way to open()
On 30 Jan 2012, at 17:05, Roger Burton West wrote: On Mon, Jan 30, 2012 at 04:56:53PM +, Dominic Thoreau wrote: open IN, '', $cfg || handle_that_error_sub; OK, that's the same error I was making, so I'll point out that this will not fail as desired, but open (IN, '', $cfg) || handle_that_error_sub; will. There is of course the argument that if this is Not Meant To Happen In Normal Behaviour, you should let autodie do its thing and catch it in a 'whoops, my program did weird shit' try/catch much higher up.
Re: The proper way to open()
On Mon, Jan 30, 2012 at 05:03:47PM +, James Laver wrote: On 30 Jan 2012, at 16:56, Dominic Thoreau wrote: open IN, '', $cfg || handle_that_error_sub; No, explicitly not. The || operator is far too high precedence binding. Use 'or' to remove your bug. No. The correct solution to buggy code caused by precedence is not to invent a new level of precedence, but to use parens. I do realise that it was the p5p gang who invented the new level of precedence, but that doesn't mean you should play along. -- David Cantrell | London Perl Mongers Deputy Chief Heretic What profiteth a man, if he win a flame war, yet lose his cool?
Re: The proper way to open()
Roger Burton West writes: What's a good way of opening a file as read-only, and failing if it doesn't exist? Like Leo (who mentioned it yesterday) I find it useful to use Path::Class for all dealings with filenames. open IN,$cfg; if (eof IN) { die bad config file $cfg\n; } I'd write that as: use Path::Class qwfile; my $in = (file $cfg)-openr; Then use $in instead of IN throughout the rest of the code. Path::Class is arguably overkill in this case -- where you aren't actually manipulating the file's path in any way -- but I've found it preferable to have the simplicity of standardizing on always using Path::Class everywhere (rather than to open files in different ways depending on where the filename came from). Cheers Smylers -- http://twitter.com/Smylers2
Re: Tech Talk Slides
On 30 January 2012 16:12, Mark Fowler m...@twoshortplanks.com wrote: On Fri, Jan 27, 2012 at 1:11 PM, Leo Lapworth l...@cuckoo.org wrote: Those interested in this sort of thing might also want to check out https://metacpan.org/module/Test::WWW::Selenium::More (https://github.com/kablamo/Test-WWW-Selenium-More) Leo, this is awesome. Thanks! I've just switched our base class to it now. Is the canonical version in github? In other words if I fork and patch away (e.g. with some documentation?) that's good? Yep - Eric (Kablamo) wanted to OS it (and also did all the development at work) - so that's the canonical repo, I'm sure pull requests would be very appreciated. Leo
Re: The proper way to open()
On Mon, Jan 30, 2012 at 9:12 AM, David Cantrell da...@cantrell.org.uk wrote: On Mon, Jan 30, 2012 at 05:03:47PM +, James Laver wrote: On 30 Jan 2012, at 16:56, Dominic Thoreau wrote: open IN, '', $cfg || handle_that_error_sub; No, explicitly not. The || operator is far too high precedence binding. Use 'or' to remove your bug. No. The correct solution to buggy code caused by precedence is not to invent a new level of precedence, but to use parens. I do realise that it was the p5p gang who invented the new level of precedence, but that doesn't mean you should play along. No. Use or for flow control and you won't find yourself fighting against Perl. Reserve use of || for non-flow control. (For the pedants, I define flow control as the operation being in void context or an argument to a flow control and/or operation.) Or always use parens with builtins. Some people advocate that anyway, but I don't care for it. And Larry, not p5p, AFAIK.
Re: The proper way to open()
On Mon, Jan 30, 2012 at 11:03 AM, James Laver james.la...@gmail.com wrote: On 30 Jan 2012, at 16:56, Dominic Thoreau wrote: open IN, '', $cfg || handle_that_error_sub; No, explicitly not. The || operator is far too high precedence binding. Use 'or' to remove your bug. This is the problem with TMTOWTDI. There should just be one way to do it. Then we wouldn't have this problem.
Re: The proper way to open()
On 31 Jan 2012, at 05:18, Avleen Vig wrote: This is the problem with TMTOWTDI. There should just be one way to do it. Then we wouldn't have this problem. :-) We'd also not have a language that attracts people who like to fly giant kites (Andy W. and a few others) and buy priests cassocks (Evil Dave and no other few others ;-) ), oh and i suspect Evil Dave will be pleased that the word cassock comes from the Turkish word quzzak meaning nomad/adventurer. G.