develooper Front page | perl.perl5.porters | Postings from February 2012

Re: defined(@arr), defined (%hash)

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
February 2, 2012 03:12
Subject:
Re: defined(@arr), defined (%hash)
Message ID:
20120202111158.GU9069@plum.flirble.org


On Wed, Jan 25, 2012 at 01:08:52PM -0500, Matthew Horsfall (alh) wrote:
> On Wed, Jan 25, 2012 at 12:34 PM, Nicholas Clark <nick@ccl4.org> wrote:
> > and aaargh, yes, this is starting to seem like the same thing that caused
> > bugs with the in-place sort optimisation - that the LHS of a list
> > assignment is a list, even if it just looks like an array.
> >
> > So you're starting to make me doubt whether the patch is correct, because
> > I'm starting to wonder whether the warning is correct for assignment,
> > given that what's actually being tested isn't the array (or hash), but
> > the list in scalar context:
> >
> 
> Hmm, okay. I misunderstood what was getting evaluated during an OP_ASSIGN
> inside of defined(). Thanks everyone for explaining. :)

Actually, I think I was misunderstanding it too. Or at least, not clear
in my head. If it had been clear in my head, I would have remembered the
sort optimisation bug. I think I'm right in saying, there is no array
assignment. What looks like array assignment is list assignment, where the
list contains an array, and the array will slurp the rest of the list.

On Wed, Jan 25, 2012 at 11:39:56AM -0600, Jesse Luehrs wrote:

> Yeah, I don't think the patch is correct as-is, but I think it would
> still be reasonable to warn in this case (if we can detect that
> defined() is what is providing scalar context to the list). It should
> have an entirely separate warning though, since it doesn't involve any
> actual arrays or hashes.

We are already warning:

$ perl5.12.3 -le 'print if defined(($a, $b) = (1, 2))'
defined(@array) is deprecated at -e line 1.
        (Maybe you should just omit the defined()?)


Just not with the correct message.

I think that the "correct" patch might be something this:

diff --git a/op.c b/op.c
index a9296f3..3feead6 100644
--- a/op.c
+++ b/op.c
@@ -8246,9 +8246,14 @@ Perl_ck_defined(pTHX_ OP *o)		/* 19990527 MJD */
 
     if ((o->op_flags & OPf_KIDS)) {
 	switch (cUNOPo->op_first->op_type) {
+	case OP_AASSIGN:
+	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+			   "defined on a list assignment expression is deprecated");
+	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+			   "\t(Maybe you should just omit the defined()?)\n");
+	    break;
 	case OP_RV2AV:
 	case OP_PADAV:
-	case OP_AASSIGN:		/* Is this a good idea? */
 	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
 			   "defined(@array) is deprecated");
 	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),


[not complete - needs to fix the warnings tests too]

which changes the message for the above code to:

$ ./perl -le 'print if defined(($a, $b) = ())'
defined on a list assignment expression is deprecated at -e line 1.
        (Maybe you should just omit the defined()?)

but (obviously) also

$ ./perl -le 'print if defined(%h = ())'
defined on a list assignment expression is deprecated at -e line 1.
        (Maybe you should just omit the defined()?)
$ ./perl -le 'print if defined((%h, @a) = ())'
defined on a list assignment expression is deprecated at -e line 1.
        (Maybe you should just omit the defined()?)



For reference, a list *assignment* is valid as the argument to defined.
A list is not:

$ perl5.12.3 -le 'print if defined(($a, $b) = ())'
defined(@array) is deprecated at -e line 1.
        (Maybe you should just omit the defined()?)

$ perl5.12.3 -le 'print if defined(($a, $b))'
Too many arguments for defined operator at -e line 1, near "))
"
Execution of -e aborted due to compilation errors.


I'm sure there's a logical reason for this in the grammar, but sometimes it
does feel like "Perl as a language has less a design than a thousand special
features flying in close formation." is valid. Although it's clearly effective
formation flying as there are lot of businesses using it to make money. eg

  http://news.perlfoundation.org/2012/01/craigslist-charitable-fund-don.html

Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About