Interesting, the only Google result for "uninitialized value in subroutine exit" (with quotes) is currently this thread. Here's an SSCCE to reproduce:
#!perl -w
use warnings;
use strict;
use CGI;
print "$] $CGI::VERSION\n";
sub Foo::get_end_date { return undef }
my $pa = bless {}, 'Foo';
print CGI->new->textfield(-name=>"end_date",
-default=>substr($pa->get_end_date(),0,10)), "\n";
__END__
5.026000 4.36
Use of uninitialized value in subroutine exit at .../CGI.pm line 472.
<input type="text" name="end_date" />
And a minimal test case is
$ perl -wle 'sub x{@_} print x(substr undef,0)'
On Perl 5.6 thru 5.14, this dies with "Use of uninitialized value in substr at -e line 1. Modification of a read-only value attempted at -e line 1." (which also doesn't seem quite right to me), whereas on Perls 5.16 thru 5.26 it gives the warning "Use of uninitialized value in subroutine exit at -e line 1.". A bisect shows the behavior changed with commit a74fb2cdc8f2. <update> I'm not an expert on the internals so I don't know if that commit is a red herring, or if the change was an unintended side effect of that commit, there is another commit that explains the change better, or something else. See replies. </update> Perl v5.16 was also the release of the "substr lvalue revamp", so I suspect a lot of code related to substr was modified. The release notes also say:
Passing a substring of a read-only value or a typeglob to a function (potential lvalue context) no longer causes an immediate "Can't coerce" or "Modification of a read-only value" error. That error occurs only if the passed value is assigned to.
Like LanX I suspect the whole thing has to do with the fact that substr is magical and returns a special lvalue that can modify the original string, in combination with the elements of @_ being aliases to the original parameters (Update before posting: as also said here by dave_the_m, who has deep knowledge of the internals). <update> I don't know what's going on at subroutine exit that would trigger the warning, but this issue may even be worth mentioning on P5P. See replies. </update> A few more comments on your code:
You've already said that you changed your code to avoid this in the first place; my suggestion would be to add a method to your API next to get_end_date (or a parameter to that method) that returns the 10-character string you want to display (I assume YYYY-MM-DD or something similar), perhaps even using "proper" methods for date/time handling like the core Time::Piece, the powerful DateTime, or functions provided by the database.
Perhaps you want to consider avoiding calling functions in the arguments to CGI methods in general, there have even been some vulnerabilities related to that, although I don't want to spread any FUD here - substr will probably never return anything other than a single value, and your code may very well not use the affected pattern anywhere, I'm just pointing this out as something to keep in mind.
Personally, I like to code defensively and sometimes will intentionally write ''.substr(...) to force the return value to be turned into a regular string if I suspect a risk of strange things happening with the lvalue.
-
I suspect you have -w on your shebang line. Note that the Perl documentation includes a section "What's wrong with * w* and $^W" (emphasis mine):
Although very useful, the big problem with using -w on the command line to enable warnings is that it is all or nothing. Take the typical scenario when you are writing a Perl program. Parts of the code you will write yourself, but it's very likely that you will make use of pre-written Perl modules. If you use the -w flag in this case, you end up enabling warnings in pieces of code that you haven't written. ...
I recommend you just use warnings; in your code and remove the -w from the shebang line, there may be other places where using -w (or $^W) may trigger warnings in code you don't have control over.