If have an array, and at some point in my code I want to check if it contains anything,
I'm not sure why you are throwing in "defined" in this scenario. Your scenario makes perfect sense for a Boolean test but, indeed, there was often confusion with "defined" related to your stated purpose:
$ perl -del
> x defined @a
''
> @a = (1..3)
> x defined @a
1
> @a = ()
> x defined @a
1
That is, people were often asking "defined @a" when they meant "is @a empty". The mistake was so common (you appear to have just made that mistake yourself) that "defined @a" was made to complain.
But that seems mostly a distraction from your original question, which should be restricted to ||= (since //= doesn't mean what you thought it did).
So why doesn't @a ||= (1..3); work? Well, the definition of ||= implies that such should be the same as @a = @a || (1..3). But you never wrote that as an alternative... because it doesn't work, either.
@a = @a || (1..3); doesn't "work" because the left side of || is in a scalar context so it is the same as @a = 0+@a || (1..3);. Which means it changes @a when @a isn't empty. (FYI, I'm sure BrowserUk knew this, so I'm just explaining that for other readers.)
I'm certainly sympathetic to the argument that it makes sense to special-case @a ||= ... so that it will DWYM. I can see somebody arguing against it because they worry it will make it more likely for people to mistakenly write @a || .... Or because it breaks the rules about how ||= was defined.
I find both sides of that argument roughly equally persuasive.
My response as to why @a ||= ... doesn't work is simply that nobody has taken the time to special-case it to make it DWYM instead of making it match @a = @a || ...
I'll suggest the following alternative idiom:
@a or @a = (1..3);
Maybe that will lead to somebody adding an or= operator so you can then write @a or= (1..3);?
|