Even so, the difference between a core language feature and a language extension created and maintained and distributed outside of the core is immense. Certainly some code uses non-DBI database modules, but it's clear that DBI is the foundation of all modern and widespread database use in Perl 5 today. Similarly, try using a test module without Test::Builder. Moose hasn't quite taken over the CPAN yet, but it's a matter of time.
In other words, some language extensions become so prevalent that they might
as well be core parts of the language. (I realize not everyone uses the
feature in every Perl 5 file they write,
but enough do that writing the silly little Modern::Perl was a
worthwhile abstraction and encapsulation. One of my current projects has 41
Perl 5 files at the moment and some 1866 lines of code. 4.2% of my SLOC count
would be that boilerplate if it weren't for this pragma. Boilerplate adds
Unlike core language features, language extensions have no strong single authority to ensure that they interact appropriately. (There's always the post hoc bug report, with its finger pointing and blame and the end result of a Pragmatic if Horrifyingly unPlanned programming language.) Language designers can only do so much to encourage the developers of extensions to consider how to work well with each other.
If I'm right about the history and motives of the development of Perl 5, the fundamental unit of encapsulation in modern Perl is lexical scoping. If that's correct, the boundaries between various components of a Perl program must have their hard edges at lexical scopes.
In specific, the warnings pragma is friendlier than the
-w command-line argument to Perl 5 because it does not enforce global behavior for code outside of its lexical scope.
In specific, using global variables is dangerous because it ignores encapsulation boundaries. (Yes, the existence of so many magic superglobals in Perl 5 itself is a language flaw.)
In specific, using UNIVERSAL::isa() to check the class of a referent is an unneighborly design error because it does not allow the referent to control its own nature.
In specific, using direct dereferencing access for object attributes is a mistake because it bypasses any validation or indirection which you shouldn't even know exists in a well-designed system.
None of these should be surprises to experienced Perl 5 programmers, but the implications run deeper—especially when discussing CPAN distributions.
With the caveat that a pragma (autovivification or autodie) with well-defined semantics (and adherence to lexical scoping) is acceptable precisely for its side effects (which do not leak out), a well-behaved CPAN distribution both sets a strict lexical boundary around its encapsulation and does not interfere with other code by its existence.
Moose is yet again a good example: it does not subvert Perl 5's default OO and it interacts with Perl 5's default OO. (In truth, the single legitimate main gripe about the effect Moose has on programs is solely its effect on program startup time.)
You can see the flip side of this principle in other languages which encourage monkeypatching of core language features without regard for lexical scoping of changes. This has the potential to devolve into a squatter's rights free-for-all, with the battle to be the first, most widely used library to scribble all over core behavior with little regard for the needs of anyone else. You might think that in these cases core always wins, but by not defining a mechanism for these types of extensions to work correctly, core can't win.
Then again, you have to get scoping right before any of this has a chance of working correctly.