<pre>
Which is precisely why you are likely to commit a WTF. See Alex's
diatribe on "worse than failure", and how all of those people
thought they understood and were doing the right thing.
</pre>
Some of us test our software, which is what I was doing when I found this behaviour which I consider a misfeature. The autovivification came about owing to a error in my code which allowed a path to be taken which should only be taken under circumstances where the higher levels of the hash would exist. Later, the code processed each of the higher level items and was not prepared to find an empty hash for one of the keys. I tend to test my code and try to force it through the various execution paths, including error handling. But of course, I don't really know what I'm doing.
<pre>
Most of the really great front-page WTFs included a guy who kept
insisting "I know what I'm doing".
</pre>
Not from those people who test their code and discover that there is un- or ill documented behaviour in the tools they are using.
<pre>
It has to do with Perl's behaviour not matching the
documentation, since the documentation describes autovivification
in an lvalue context, which defined() is not.
See, that is what you are not understanding. The documentation is
accurate and Perl's behaviour matches it. You just don't understand
what it means, and you failed to even read my explanation of what
was happening. This has got nothing to do with the defined()
function. One last time, in case you still missed it:
</pre>
There you go again with your baseless assumptions. I read your explanation, I understood your explanation. I also understood what Perl was doing, otherwise I wouldn't have had the contrived example illustrating the issue.
<pre>
THIS HAS GOT NOTHING TO DO WITH THE defined FUNCTION.
</pre>
No, it has to do with autovivification in a non-lvalue context.
<pre>
There is an lvalue context here. Your example includes an lvalue
context which causes autovivification. The defined() function is not
that context. You apparently don't know what an "lvalue context"
means in perl.
</pre>
I dispute that this function invocation is an lvalue context. Perl's own man pages suggest that it probably isn't an lvalue (see below). Perl's implementation treats it as _though_ it were an lvalue context. That doesn't make it one.
<pre>
The fact that it may be in the camel book is not relevant.
The camel is an example of a place where you could learn perl. The
perl manpages are not such a place. The manpage text you quote is
entirely correct, but since it's designed as a reference for people
who already know perl, it doesn't take half a page to explain the
meaning in detail and therefore is not a suitable place for you to
learn how this works.
</pre>
What a surprise, I've read the camel book, in more than one edition. I actually do know Perl, although unlike you, I don't claim to know every corner case. I didn't use the manpages to learn perl, or to see if I could legitimately write the code which caused me to stumble over this behaviour. I looked at the manpages when I found that autovivification takes place in a context where I would not expect it to and found that the manpages don't suggest anything different than my expectations. Why do you continue to assume I learned perl from the man pages? Your multiple WTFs which you made in your responses (this is not necessarily a complete list) are to leap to completely unwarranted conclusions, such as:
<pre>
1) that I'm trying to learn Perl
2) that I'm trying to learn Perl from the manpages
3) that I didn't understand your description of what Perl actually does in the case under discussion
4) that I consider the example which illustrates the disputed behaviour as being a recommended coding practice since the perlfunc
man page on 'defined' doesn't say not to do this
5) that every Perl programmer should either be intimately familiar with every corner case of the language or should never write a Perl
program for production use
Your conclusion that if I wasn't aware of this I don't know Perl
well enough to be using it for serious applications is an
indictment either of your attitude or the usefulness of Perl.
Actually, it's an indictment of your knowledge of perl.
</pre>
Given that Perl does not have anything similar to the ANSI C standards, the only language reference will either be the man pages and or books by the Perl developers. Since it's neither practical nor desireable to publish a new book per point release, it's important that the man pages be a complete and accurate description of the release which contains those man pages, so a criticism that the man pages don't expressly point out that autovivification can occur when using 'defined' or that Perl will treat it as though it were an lvalue context is a legitimate point for criticism. It's also quite reasonable to question whether this behaviour is desireable. I'd be willing to bet that given a pool of experienced Perl programmers, a significant number of them would not be aware that testing defined($something{sub_level}->{sub_sub_level}) where $something{sub_level} does not exist would cause it to be created. Does that mean that all of those people should not be writing Perl programs? Even if, like me, they would never intentionally code such a test?
<pre>
Imagine an american tourist in france. He's lost his shoes. He says
to the nearest frenchman: "avez vous seen mon shoes?". The frenchman
stares at him like he's a moron, then walks off. The tourist goes
off on a rant about how useless french is and how unhelpful french
people are, despite his perfect understanding of the language.
You are being that tourist. The problem here is not the language.
(With apologies to Roald Dahl - I don't have a copy of the book, so
I probably missed a few details in writing it from memory)
</pre>
A straw man argument of the first order. The closest you could get with this rather poor analogy would be a tourist using a phrase book which had a mistranslation or failed to warn of local associations of a word; for example a British phrase book for visiting the US which included 'rubber' for eraser without pointing out the more common US usage of 'eraser' or the usual US meanings of the word 'rubber'. The tourist points out that the phrasebook is sub-optimal, which is hardly a rant, much less a rant against the populace of the US.
The point I raised before was that if the documentation for Perl doesn't match the behaviour of Perl, for those with exposure to multiple languages and the concept of lvalues as it is usually used.
Your attitude seems to be that only those who know both the documentation and the variances are fit to use the language is saying that Perl should not be used by anyone except those people who have explored all the darkest corners of the language. This doesn't match the description in the preface to the Camel book 'The Pursuit of Happiness', nor the
real world.
<pre>
If the language is only usable for people who are aware of what I
can only consider to be counter-intuitive behaviour, then it is not
fit for the purpose which it is most touted as serving.
There's no such thing as intuitive behaviour in programming
languages (or anything beyond "fight or flight", really). There is
only "familiar" and "unfamiliar". Perl is only usable for people who
are familiar with it, which you are obviously not. Everybody who is
familiar with perl understands autovivification.
</pre>
Nonsense of the first order. If a computer language has an underlying design, then the behaviour of parts not familiar to a programmer will not be surprisingly different to the behaviour already learned and will make sense as part of the overall design. Python's "everything is an object" and "variables are attached to objects, not the values of the objects" is a constant which carries through the language. A case where this were untrue would be counter-intuitive. Or imagine a language with integers, floats and complex types. You'd expect all 3 of those types to behave following the usual mathematical conventions and would find it counter-intuitive if addition, subtraction, multiplication and division of complex types followed the usual conventions but comparisions were done by saying 'complex X < complex Y if real(X) < real(Y) or (real(X) == real(Y) and imag(X) < imag(Y)).
Operations with surprising side effects are counter-intuitive.
<pre>
Sadly, many people write things in perl without being familiar with
it, resulting in a lot of really crappy code.
</pre>
And the relevance of this is?
<pre>
What, besides a rather snotty attitude, made you conclude that I was
learning or would attempt to learn a language from the man pages?
That would be your inability to find the explanation in the standard
text, and instead relying on your misunderstanding of the manpage. I
gave you the benefit of the doubt in assuming that you were trying
to learn the language, rather than trying to use it without learning
it (because that would be really stupid).
</pre>
You truly are an arrogant ass and I pity anyone having the misfortune of sharing office space with you. The question wasn't whether Perl does this, it clearly does, but rather a) if it's well documented - I suggest not - and b) if it's a good feature - I suggest not and the 'exists' entry also suggest not.
<pre>
What I do expect is that the manpages match the language, which I maintain they do not in this case.
Well, you're just wrong, and the manpage is right.
</pre>
Looking further, I find that perlfunc does mention this behaviour in perlfunc under 'exists', but not under 'defined'. And the text there suggests that it is a misfeature:
<pre>
This surprising autovivification in what does not at first--or even
second--glance appear to be an lvalue context may be fixed in a
future release.
</pre>