Should I use common::sense or just stick with `use strict` and `use warnings`? - perl

I recently installed a module from CPAN and noticed one of its dependencies was common::sense, a module that offers to enable all the warnings you want, and none that you don't. From the module's synopsis:
use common::sense;
# supposed to be the same, with much lower memory usage, as:
#
# use strict qw(vars subs);
# use feature qw(say state switch);
# no warnings;
# use warnings qw(FATAL closed threads internal debugging pack substr malloc
# unopened portable prototype inplace io pipe unpack regexp
# deprecated exiting glob digit printf utf8 layer
# reserved parenthesis taint closure semicolon);
# no warnings qw(exec newline);
Save for undef warnings sometimes being a hassle, I've usually found the standard warnings to be good. Is it worth switching to common::sense instead of my normal use strict; use warnings;?

While I like the idea of reducing boiler-plate code, I am deeply suspicious of tools like Modern::Perl and common::sense.
The problem I have with modules like this is that they bundle up a group of behaviors and hide behid glib names with changeable meanings.
For example, Modern::Perl today consists of enabling some perl 5.10 features and using strict and warnings. But what happens when Perl 5.12 or 5.14 or 5.24 come out with great new goodies, and the community discovers that we need to use the frobnitz pragma everywhere? Will Modern::Perl provide a consistent set of behaviors or will it remain "Modern". If MP keeps with the times, it will break existing systems that don't keep lock-step with its compiler requirements. It adds extra compatibility testing to upgrade. At least that's my reaction to MP. I'll be the first to admit that chromatic is about 10 times smarter than me and a better programmer as well--but I still disagree with his judgment on this issue.
common::sense has a name problem, too. Whose idea of common sense is involved? Will it change over time?
My preference would be for a module that makes it easy for me to create my own set of standard modules, and even create groups of related modules/pragmas for specific tasks (like date time manipulation, database interaction, html parsing, etc).
I like the idea of Toolkit, but it sucks for several reasons: it uses source filters, and the macro system is overly complex and fragile. I have the utmost respect for Damian Conway, and he produces brilliant code, but sometimes he goes a bit too far (at least for production use, experimentation is good).
I haven't lost enough time typing use strict; use warnings; to feel the need to create my own standard import module. If I felt a strong need for automatically loading a set of modules/pragmas, something similar to Toolkit that allows one to create standard feature groups would be ideal:
use My::Tools qw( standard datetime SQLite );
or
use My::Tools;
use My::Tools::DateTime;
use My::Tools::SQLite;
Toolkit comes very close to my ideal. Its fatal defects are a bummer.
As for whether the choice of pragmas makes sense, that's a matter of taste. I'd rather use the occasional no strict 'foo' or no warnings 'bar' in a block where I need the ability to do something that requires it, than disable the checks over my entire file. Plus, IMO, memory consumption is a red herring. YMMV.
update
It seems that there are many (how many?) different modules of this type floating around CPAN.
There is latest, which is no longer the latest. Demonstrates part of the naming problem.
Also, uni::perl which adds enabling unicode part of the mix.
ToolSet offers a subset of Toolkit's abilities, but without source filters.
I'll include Moose here, since it automatically adds strict and warnings to the calling package.
And finally Acme::Very::Modern::Perl
The proliferation of these modules and the potential for overlapping requirements, adds another issue.
What happens if you write code like:
use Moose;
use common::sense;
What pragmas are enabled with what options?

I would say stick with warnings and strict for two main reasons.
If other people are going to use or work with your code, they are (almost certainly) used to warnings and strict and their rules. Those represent a community norm that you and other people you work with can count on.
Even if this or that specific piece of code is just for you, you probably don't want to worry about remembering "Is this the project where I adhere to warnings and strict or the one where I hew to common::sense?" Moving back and forth between the two modes will just confuse you.

There is one bit nobody else seems to have picked up on, and that's FATAL in the warnings list.
So as of 2.0, use common::sense is more akin to:
use strict;
use warnings FATAL => 'all'; # but with the specific list of fatals instead of 'all' that is
This is a somewhat important and frequently overlooked feature of warnings that ramps the strictness a whole degree higher. Instead of undef string interpolation, or infinite recursion just warning you and then keeping on going despite the problem, it actually halts.
To me this is helpful, because in many cases, undef string interpolation leads to further more dangerous errors, which may go silently unnoticed, and failing and bailing is a good thing.

I obviously have no common sense because I going more for Modern::Perl ;-)

The "lower memory usage" only works if you use no modules that load strict, feature, warnings, etc. and the "much" part is...not all that much.

Not everyone's idea of common sense is the same - in that respect it's anything but common.
Go with what you know. If you get undef warnings, chances are that your program or its input is incorrect.
Warnings are there for a reason. Anything that reduces them cannot be useful. (I always compile with gcc -Wall too...)

I have never had a warning that wasn't something dodgy/just plain wrong in my code. For me, it's always something technically allowed that I almost certainly don't want to do. I think the full suite of warnings is invaluable. If you find use strict + use warnings adequate for now, I don't see why you'd want to change to using a non-standard module which is then a dependency for every piece of code you write from here on out...

When it comes to warnings, I support the use of any module or built-in language feature that gives you the level of warnings that helps you make your code as solid and reliable as it can possibly be. An ignored warning is not helpful to anyone.
But if you're cozy with the standard warnings, stick with it. Coding to a stricter standard is great if you're used to it! I wouldn't recommend switching just for the memory savings. Only switch if the module helps you turn your code around quicker and with more confidence.

Many of peoples argues in a comments with what if the MP changes, it will break your code. While this can be an real threat, here is already MUCH things what are changes over time and break the code (sometimes after a deprecation cycle, sometimes not...).
Some other modules changed the API, so breaks things, and nobody care about them. E.g. Moose has at least two things what are deprecated now, and probably will be forbidden in some future releases.
Another example, years ago was allowed to write
for $i qw(some words)
now, it is deprecated. And many others... And this is a CORE language syntax.
Everybody survived. So, don't really understand why many of people argues againist helper modules. When they going to change, (probably) here will be a sort of deprecation cycle... So, my view is:
if you write programs to yourself, use any module you want ;)
if you write a program to someone, where someone others going to maintnanece it, use minimal nonstandard "pragma-like" modules (common::sense, modern::perl, uni::perl etc...)
in the stackoverflow questions, you can safely use common::sense or Modern::Perl etc. - most of users who will answer, your questions, knows them. Everybody understand than it is easier to write use 5.010; for enable strict, warnings and fearures with 10 chars as with 3 lines...

Related

Use or not to use the namespace::sweep and/or Modern::Perl

In my last question #Borodin commented my question with:
You should start by removing Modern::Perl and namespace::sweep.
Modules that behave as pragma should be avoided.
I'm confused a bit, because:
in the LATEST Moose BestPractices manual recommending to use namespace::autoclean.
The use namespace::autoclean bit is simply good code hygiene, as it
removes imported symbols from your class's namespace at the end of
your package's compile cycle, including Moose keywords. Once the class
has been built, these keywords are not needed. (This is preferred to
placing no Moose at the end of your package).
In the Book Intermediate perl recommending to use the namespace::autoclean too.
Yes, I'm used the instead of the autoclean the sweep module - because again from the doccu
This pragma was written to address some problems with the excellent
namespace::autoclean. In particular, namespace::autoclean will remove
special symbols that are installed by overload, so you can't use
namespace::autoclean on objects that overload Perl operators.
...
...
In most cases, namespace::sweep should work as a drop-in replacement
for namespace::autoclean. Upon release, this pragma passes all of
namespace::autoclean's tests, in addition to its own.
And because I'm an perl beginner, i'm really confused. For me, when i reading: this module addressing some problems of another module - mean: use this one.
'Manual (where from I should learn) says "use it" and expert from stackoverflow teling: don't use it.
So please, can someone explain me:
it is correct to use namespace::sweep or I should use namespace::autoclean or none of them?
if none, why the BestPractices recommends it?
For the `ModernPerl'. Sure, I'm probably don't understand deeply and "exactly" what is does. What i know, (again from it's doccu)
This enables the strict and warnings pragmas, as well as all of the
features available in Perl 5.10. It also enables C3 method resolution
order as documented in perldoc mro and loads IO::File and IO::Handle
so that you may call methods on filehandles. In the future, it may
include additional core modules and pragmas.
Sure, don't deeply understand to mro, only think it is an answer to the "deadly diamond of death" problem in cases of multiple inheritance.
Up to today, i was really happy with it, because it is shorting for me the needed pragmas:
use strict;
use warnings;
use feature 'say';
So, what is a "status" of the "Modern::Perl" (and other similar cpanm modules)? Allowed to use, or not?
On your question about namespace::sweep:
Firstly, take note of the actual problem that namespace::sweep resolves.
In particular, namespace::autoclean will remove special symbols that are installed by overload, so you can't use namespace::autoclean on objects that overload Perl operators.
What this means is that if your class has overloaded operators they won't work if you also use namespace::autoclean. But this problem only occurs if you use overload. Other than that, namespace::autoclean will suffice.
Secondly, it says that namespace::sweep can be used instead of namespace::autoclean:
In most cases, namespace::sweep should work as a drop-in replacement for namespace::autoclean. Upon release, this pragma passes all of namespace::autoclean's tests, in addition to its own.
So to answer your question, "is it correct to use namespace::sweep or I should use namespace::autoclean or none of them?"
You should use at least one of them as recommended by Moose Best Practices.
It is generally ok to use namespace::sweep since it says it is designed to do so and it passes all of namespace::autoclean's tests.
In spite of point 2 above, if you don't use overload then you don't have a problem with using namespace::autoclean, so you could just use that in this case.
Specifying use 5.014; (or other version >= 5.011) will automatically do use strict; and enable all features of that version for you; IMO this is some of the reason Modern::Perl has not gained a whole lot of traction.
I've always disliked Modern::Perl because it doesn't describe what it does; it is someone else's idea of "modern" as of some fixed point in the past.

Perl 5.20 and the fate of smart matching and given-when

I just installed Perl 5.18, and I get a lot of warnings like this,
given is experimental at .\[...].pl line [...].
when is experimental at .\[...].pl line [...].
Smartmatch is experimental at C:/strawberry/perl/site/lib/[...] line [...].
Looking into these warnings -- which I've never heard mentioned anywhere -- I was only able to find this in two places,
perldelta for 5.18, which only really mentions insofar as to say that the feature has been downgraded to experimental?
this nntp.perl.org post
The Perl Delta still does the most to give mention as to what's happening with those features. It's halfway down buried in the pod,
Smart match, added in v5.10.0 and significantly revised in v5.10.1, has been a regular point of complaint. Although there are a number of ways in which it is useful, it has also proven problematic and confusing for both users and implementors of Perl. There have been a number of proposals on how to best address the problem. It is clear that smartmatch is almost certainly either going to change or go away in the future. Relying on its current behavior is not recommended. Warnings will now be issued when the parser sees ~~, given, or when.
I'm confused at how the most significant change in Perl in the past 10 years could be pulled. I've started using given, when, and smartmatch all over the place. Is there any more information about these futures? How is anyone finding them "confusing?" How are these features likely to change? Is there a plan to implement these features with a module?
There are problems with the design of smart-matching. The decision of what any given TYPE ~~ TYPE should do is most often unobvious, inconsistent and/or disputed. The idea isn't to remove smart matching; it's to fix it.
Specifically, ~~ will be greatly simplified, as you can see in a proposal by the 5.18 pumpking. Decisions as to how two things should match will be done with helpers such as those that already exist in Smart::Match.
... ~~ any(...)
It is much more readable, much more flexible (fully extensible), and solves a number of problems (such as "When should X be considered a number, and when should it be considered a string?").
Some insights might be gained by reading rjbs's proposed changes to smartmatch. He is the pumpking (Perl release manager) after all, so his comments and his view of the future is more relevant than most. There is also plenty of community comment on the matter; see here for instance. The 'experimental' status is in effect because, since things are likely to change in the future, it is responsible to inform users of that fact, even if we don't know what those changes will be.
Well, that's what's said in the description of the patch that downgraded this set of features to experimental:
The behavior of given/when/~~ are likely to change in perl 5.20.0:
either smart match will be removed or stripped down. In light of this,
users of these features should be warned. A category
"experimental::smartmatch" warning should be issued for these features
when they are used.
So while you can indeed turn these warnings off, with something like this (source):
no if $] >= 5.018, warnings => "experimental::smartmatch";
... it's just turning your eyes off the problem.

Is it necessary to use warnings when already use strict?

Code as follows:
use strict;
use warnings;
Is use warnings; necessary here?
Yes, it's necessary.
use strict and use warnings do different things.
From the strict module's manpage:
strict − Perl pragma to restrict unsafe constructs
From perlrun (for -w):
prints warnings about dubious
constructs, such as variable names
that are mentioned only once and scalar variables that are
used
before being set, redefined subroutines, references to
undefined
filehandles or filehandles opened read-only that you are
attempting to write on, values used as a number that don't
look
like numbers, using an array as though it were a scalar, if
your
subroutines recurse more than 100 deep, and innumerable other
things.
Yes. strict guards against a very limited number of things. warnings alerts you to a different and much wider set of problems.
This same question came up a few days ago here: Which safety net do you use in Perl?. That link leads to a discussion of strict, warnings, diagnostics, and other similar topics.
Yes, consider:
perl -le "use strict; my $f; my $z = $f*1"
strict doesn't let you know that $f is undefined, while adding warnings will:
perl -le "use strict; use warnings; my $f; my $z = $f*1"
Use of uninitialized value $f in multiplication (*) at -e line 1.
thus the advice to enable both.
It's not necessary in the actual meaning of that word. That is, a program doesn't require it to operate. People often forget what necessary means.
However, if your question is "Does strict enable warnings?", the answer is no. You can see what strict does by reading its documentation.
warnings are often useful in pointing out problems that you should fix. However, Perl's warnings don't require you to fix them, so your program can continue even though it emits warnings.
Some people will tell you to always use warnings, but they make that sort of rule so they don't have to think about it or explain it to people who won't think about it. It's an unpopular position to say anything other than "always use warnings".
warnings are a tool for developers, and if the people who see the warnings aren't going to know what they are or what to do about them, they are probably just going to cause annoyance or confusion. I've seen a few instances where new perls started to emit new warnings for programs, which then filled up disks as no one was monitoring the log files.
I have a much more nuanced rule "use warnings when you'll do something about them, and don't use them if you won't".
I don't even go as far as saying as "Always write warning-free code". There's plenty of code that I write that I will run exactly once, or from the command line, or in other situations where I don't care about the sloppiness. I don't like giving warning-dirty code to other people, but I don't obsess over it for little things I do for myself.
"What do you mean by necessary?" is my reply.
If you think strict and warnings are the same thing, you are wrong. Other people here have given very good answers as to each pragma does.
use warnings will in general make you a better coder. If learning is important, then my answer would be "Yes."
It will also help you avoid bugs, make your errors easier to understand.
In general, I would say that there are very few times when it is warranted to not use both strictand warnings. I even use warnings in my one-liners, e.g. > perl -we 'print "Hello world!"'
It takes a few seconds to type in, but will save you hours of needless work debugging.

Enable global warnings

I have to optimize an intranet written in Perl (about 3000 files). The first thing I want to do is enable warnings "-w" or "use warnings;" so I can get rid of all those errors, then try to implement "use strict;".
Is there a way of telling Perl to use warnings all the time (like the settings in php.ini for PHP), without the need to modify each script to add "-w" to it's first line?
I even thought to make an alias for /usr/bin/perl, or move it to another name and make a simple script instead of it just to add the -w flag (like a proxy).
How would you debug it?
Well…
You could set the PERL5OPT envariable to hold -w. See the perlrun manpage for details. I hope you’ll consider tainting, too, like -T or maybe -t, for security tracking.
But I don’t envy you. Retrofitting code developed without the benefit of use warnings and use strict is usually a royal PITA.
I have something of a standard boiler-plate I use to start new Perl programs. But I haven’t given any thought to one for CGI programs, which would likely benefit from some tweaks against that boiler-plate.
Retrofitting warnings and strict is hard. I don't recommend a Big Bang approach, setting warnings (let alone strictures) on everything. You will be inundated with warnings to the point of uselessness.
You start by enabling warnings on the modules used by the scripts (there are some, aren't there?), rather than applying warnings to everything. Get the core clean, then get to work on the periphery, one unit at a time. So, in fact, I'd recommend having a simple (Perl) script that simply finds a line that does not start with a hash and adds use warnings; (and maybe use strict; too, since you're going to be dealing with one script at a time), so you can do the renovations one script at a time.
In other words, you will probably be best off actually editing each file as you're about to renovate it.
I'd only use the blanket option to make a simple assessment of the scope of the problem: is it a complete and utter disaster, or merely a few peccadilloes in a few files. Sadly, if the code was developed without warnings and strict, it is more likely to be 'disaster' than 'minimal'.
You may find that your predecessors were prone to copy and paste and some erroneous idioms crop up repeatedly in copied code. Write a Perl script that fixes each one. I have a bunch of fix* scripts in my personal bin directory that deal with various changes - either fixing issues created by recalcitrant (or, more usually, simply long departed) colleagues or to accommodate my own changing standards.
You can set warnings and strictures for all Perl scripts by adding -Mwarnings -Mstrict to your PERL5OPT environment variable. See perlrun for details.

What's the modern way of declaring which version of Perl to use?

When it come to saying what version of Perl we need for our scripts, we've got options, oh, brother, we've got options:
use 5.010;
use 5.010_001;
use 5.10.0;
use v5.10;
use v5.10.0;
All seem to work. perlcritic complains about all but the first two. (It's unfortunate that the v strings seem to have such flaws, since Perl 6 expects you to do use v6; for your Perl 6 scripts...)
So, what should we be doing to indicate that we want to use a particular version of perl?
There are really only two options: decimal numbers and v-strings. Which form to use depends in part on which versions of Perl you want to "support" with a meaningful error message instead of a syntax error. (The v-string syntax was added in Perl 5.6.) The accepted best practice -- which is what perlcritic enforces -- is to use decimal notation. You should specify the minimum version of Perl that's required for your script to behave properly. Normally that means declaring a dependency on language features added in a major release, such as using the say function added in 5.10. You should include the patch level if it's important for your script to behave properly. For example, some of my code specifies use 5.008001 because it depends on the fix for a bug that 5.8.0 had which was fixed in 5.8.1.
I just use something like 5.010_001. I've grow weary of dealing with version string problems for something that should be mind-numbingly simple.
Since I mostly deal with build systems, I have the constant struggle of Module::Build's internal version.pm which is out of sync with the version.pm on CPAN. I think that's mostly better now, but I have better things to think about.
The best practice should always be to do the thing that commands the least of your attention, and certainly not take more attention than the value it gives back. In my opinion, v-strings and dotted decimals were a huge distraction with no additional benefit, wasting a lot of valuable programmer time just to get back to the starting point.
I should also note that Perl::Critic has often pushed questionable practices for the higher purpose of reducing the ways that people do things. However, those practices often cause problems, make them un-best. This is one of those cases. A more realistic best practice is to not make Perl::Critic compliance your goal. Use it where it is useful, but in cases like this, don't waste mental time on it.
The "modern" way is to use the forms starting with v. However, that may not necessarily be what you really want to do.
Critic complains because older versions of Perl won't understand and play nicely with the forms that start with v. However, if your version of Perl supports it, v is nicer to read because you can say:
use v5.10.1;
... rather than ...
use 5.010_001;
So, in the documentation for use, the following workaround is offered:
use 5.006; use v5.6.1;
NB: I think the documenation is in error here, as the v is omitted from the example at perldoc use.
Since the versions of Perl that don't support the v syntax will fail at the first use, they won't get to the second more specific and readable one.