Update: I am informed that while I may imply a timeline which sees the pragma modules mentioned below taking action before Moose, time-wise Moose acted first and then the pragma modules came later
Last weekend in my first round comparison between Mojo and Dancer, I noted that neither project used strict or warnings.
At the time, I suspected this was done for clarity. After all, it can get annoying when use strict and use warnings to get in the way of having a nice a clean synopsis.
It was too my great surprise that I discovered both web frameworks had decided that use strict and use warnings were good enough for everybody and they would silently turn both of them on.
This makes them the third group of modules to decide how I should write my code.
First are your $Adjective::Perl style modules.
This I can live with and playing with pragmas seems quite reasonable, since it's a style pragma module itself. By saying "use perl5i" I'm explicitly buying into their view of what code should be written and formatted like.
Then Moose decided that they would turn on strict and warnings as well.
This makes me a bit uncomfortable, since I use Moose for it's object model. I don't really want it imposing it's views on how I should write the rest of my code.
I can hear you already saying "But wait! You can turn it off with no warnings, but you shouldn't do that because it's best practice (and Best Practice) to always have them both on, and anyway it's only enabled until you say "no Moose;"
Or is it? That alone is an interesting question.
Do Moose's views on strictness and warnings able to escape it's scope, and will be imposed on me even when I tell it to go away with no Moose;
Or if they do go away, does that mean I've accidentally been running a whole bunch of code without strict and warnings on by mistake?
But I digress, now where was I... oh right!
<rant>
I appreciate you are trying to be nice and save me two lines, but dammit I'm not paying you (metaphorically) for that, and now I have to THINK instead because the LACK of an option to your code can be meaningful. It's worse than meaningful whitespace, it's a meaningful unknown. And I can trivially automate the production of those "use strict;" or "use strict;\nuse warnings;" (as you prefer) lines in pretty much any hackable editor written in Perl. Automating the thinking you have to do when there ISN'T something in the code is much harder, or impossible.
This kind of thing with Exporter is one of the (four) provably impossible problems that prevent Perl being parsable. Gee thanks!
From a perception point of view it's the same kind of situation when a Media Company announces they are going to buy a Mining Company. Why? Because the Mining Company has a lot of cash but little revenue, and the Media Company has a lot of revenue but little cash, so they'd "Go well together".
Before I say any more, you should already be a bit suspicious. And it's probably no surprise when you find out that the part-owner boss of the Media Company is also a part-owner of the Mining Company.
But that kind of thing is an obvious form of Conflict Of Interest. Humans are almost universally tuned to spot that kind of thing and see it as a negative.
It's a much trickier situation when the conflict is between Doing Your Job and things like Trying To Be Nice, or things like Clearly You Probably Meant It, So I'll Just Silently Correct That For You. There's a variety of meme's in this situation, different mixed perceptions based on your own personal morality.
But that doesn't remove the technical issue that you've conflated two entirely different functions into one module.
So now with Moose if I don't want warnings, but I do want strict, I'm not sure if I need to do this...
use Moose; no warnings;or this...
...
no Moose;
use Moose;
# Lets say I'm nice and allow all my Moose definition code # to follow their warnings policy, because I like their rigourous approach.
no Moose; use strict; use warnings;
package Foo;
use MyWebFramework; no warnings;
use Moose; no warnings;
use Some::Random::Module; no warnings; # Can I really be sure they don't enable warnings? ...
use Carp (); use Cwd (); use File::Spec (); use File::HomeDir (); use List::Util (); use Scalar::Util (); use Getopt::Long (); use YAML::Tiny (); use DBI (); use DBD::SQLite ();Why do I need to do that stupid braces shit? Because the alternative is I have to audit every single dependency to make sure it doesn't export by default, and THEN I have to also trust/hope they don't start exporting by default in the future.
I don't think you've taken a controversial position at all there, you've hit the nail on the head.
Modules should stay the hell out of your namespace and application except to do the things you've actually asked them to do.
Warnings and logfiles: abso-bloody-lutely.
If you break something, you need to be told about it once, not 5 million times.
If someone else breaks something and doesn't pay attention that they're being told 5 million times, you don't want to find the 5 billion other messages first thing monday morning.
It's a horrible horrible mess, and anything that makes it worse needs stomping on fast.
Re:what about catching the warnings?
Illusori on 2010-04-08T12:32:32
Only works per-process.
Most webservers are multiple processes with a limited lifetime (they often get killed after a fixed number of requests).
Then there's the issue that most large sites have a server farm too...
Re:what about catching the warnings?
Tim Bunce on 2010-04-08T12:56:39
Yes, it only works per-process and per-server, but in my experience (with 80+ servers running many mod_perl processes) it is a very simple and effective way to eliminating the kinds of web-service log-storms you described. It changes an unmanageable flood into a very manageable stream. Highly recommended.Re:what about catching the warnings?
Illusori on 2010-04-08T17:55:44
Sorry, didn't mean to imply that it doesn't mitigate the problem, it does but it can only mitigate it.
Whether that turns the situation into a manageable one or not would depend on circumstance.
:) Re:what about catching the warnings?
mgrimes on 2010-04-08T20:14:43
Does this work? I get an error:
$ perl -Mwarnings -e'$SIG{WARN}=sub{}; my $a; my $b=$a+1;'
No such signal: SIGWARN at -e line 1.
Use of uninitialized value $a in addition (+) at -e line 1.
Re:what about catching the warnings?
mgrimes on 2010-04-08T20:18:44
Brain stopped working for a moment. Just remembered it's $SIG{__WARN__}.Re:what about catching the warnings?
gabor on 2010-04-08T20:24:43
yeah, sorry for the bug, I was in a hurryRe:what about catching the warnings?
mgrimes on 2010-04-08T20:38:41
I didn't mean to critique your post. I actually *just* ran into an undef warning being tossed by someone else's module. It was harmless, so I tried to use your code to catch it. Quite a coincidence.Re:what about catching the warnings?
jleader on 2010-04-16T20:38:45
That helps, except when the warning helpfully includes the data value causing the problem, which might be different every time.
Re:I don't get it
Illusori on 2010-04-08T12:41:13
There's several problems:
One, the module is doing something that isn't its advertised function and _really_ isn't neccessary to implement its core function.
Two, it's changing behaviour of the parent program, this is a bad thing to do even when it _is_ neccessary.
Three, it isn't clear in situations like the Moose one, just when to turn it off or on, consider the following sequence within a single scope:
You enable warnings/strict. You do some code. You turn off warnings/strict. You do some code. You use Moose. You do some code. You turn on warnings/strict again not realising Moose turned them on. You do some code. You turn Moose off.
What's the state of play now? Are warnings on or off? Is strict on or off?
That depends on the implementation of how Moose is tracking warnings/strict - is it reverting to what it saw when it started, or is it counting references? It gives different results depending on how they implemented it.
This is _entirely_ uneccessary and only obsfucates behaviour that _ought_ to be under the control of the programmer.
I fully agree. Warnings in production are a no-go. Except very specific and monitored cases maybe.
That's where "perl -X" is useful. Can one enable mod_perl running under -X yet ?
use warnings FATAL => 'all';
No one has commented on the necessity of empty import lists yet. How about a Critic policy that always requires an explicit import list (with configurable exceptions because the world's not perfect)? I certainly would like that.
Re: I don't want to be forced into your damned war
Alias on 2010-04-09T03:13:24
It would be nice, but a little tricky, since you need to exclude pragmas which use the import function to achieve their pragma effects.
It's doable though, and I'd happily enable that rule for Padre if someone wrote it.
I have to say I was greatly impressed that the Dancer guys have offered to implement some kind of configuration option so I can explicitly turn disable their Dancer-imposed warnings in production...
This quote makes me very suspicious about the whole contest, since the Mojolicious folks never even heard a single word about this before.
Nope
xsawyerx on 2010-04-08T12:50:22
I reckon this post was instigated mainly by me. When Adam turned up on the IRC channel after he read from our posts that strict and warnings are on by default, I tried to explain it's on purpose and asked what the problem with it was.
This started a whole discussion when Adam said there's no need for it in production and I countered it saying I do want it in production.
Then the discussion flowed between the rest of the programmers on letting the user be able to change the default warnings on.
This is also something that's a bit mentioned in my recent post on blogs.perl that mentions we learned that users might want to be able to turn off the warnings.
I reckon the whole discussion (which involved a lot of experience of Adam and me on being sysadmins) pushed Adam to finally write a "No warning on production, damn it!" post.
Re:Dancer favoritism?
Aristotle on 2010-04-08T21:36:13
Good ol’ Sebastian…
:-)
Just like that one text editor...
I often use an idiom that I try to fetch an item, and if successful I want to do something with it; if not successful, the code returns undef
(false).
Typically, the code goes something like this:
if(my $item = get_item(@params)) {
# do something with $item
print $item->{text};
}
but this text editor complains about it, stating, in a dialog box:
a single = in a conditional is usually a typo, use == or eq to compare.
Do you want to continue?
every. single. time. I run that script.
Goddamnit, I know already. It's not a typo. Just get out of my way already, and let me do as I please.
That text editor is Padre.
Re:Damn right!
runrig on 2010-04-08T15:20:01
You'd think that the "my" would be a clue that you intended to do it that way. And amy $foo ==
in an if statement would be a red flag.... where is your bug report?
gabor on 2010-04-08T15:38:38
It is a bug. You could report it (or at least ask on the Padre channels if this is a bug or a feature).We could tell you where to turn off the message until we fix the bug. By the way the the feature that is causing that error message is specifically designed to catch mistakes of beginners.
The idea is to catch bugs that can be caused by code like this:
if ($x =
/boo/) {
}which is valid perl but it is unlikely a beginner would know what it actually does. The example you gave probably should not trigger the error message and should be considered a bug in Padre.
Re:where is your bug report?
gabor on 2010-04-08T16:38:16
Oh and just to make a useful post as well, - after having dinner and being less grumpy - you can turn on/off the Perl beginner mode in "Edit/Preferences/Behaviour/Perl beginner mode" or "Tools/Preferences/Behaviour/Perl beginner mode" in newer versions of Padre.Also I think I have partially fixed that specific bug in 0.59 as it was also causing test failures in Padre where we also use similar constructs here and there.
I think it is still buggy and eventually it should be implemented as a plugin for Perl::Critic to make it more roboust but that is waiting for someone to have the necessary tuits.
... and this is why strictures will be the default in Perl. Modules have no business mucking with your namespace, as you say. Perl does.
Note that warnings won't be the default for various reasons.
Moose started this whole thing, not any $Adjective::Perl modules. Moose 0.10 (released 05 Jul 2006) turns on strict and warnings for you. Modern::Perl is circa 2009.
I think it was mst who came up with the trick.
Re:Just as a point of history
chromatic on 2010-04-08T18:49:52
I concur; I saw this in Moose before I wrote M::P.