Syntactic Confectionery Delight | |
PerlMonks |
Beware of global! And bless the local!by alexander_lunev (Pilgrim) |
on Dec 12, 2019 at 08:40 UTC ( [id://11110005]=perlmeditation: print w/replies, xml ) | Need Help?? |
Hello monks. Today I found that a little negligence can cause a week-long debugging. I wrote a program that uses Crypt::OpenPGP module, and for a strange reason module works great when I simply initialize it with keyrings from file, but it crashes when i first read keyrings from files and combines them for my needs and then initialize module with constructed keyring objects. Terrible crashes of the Perl interpreter itself (sic!) was accompanied by cryptic messages like these:
I was wondering - what have i done to bring this punishment upon me? I compared objects that come out from keyring-file initialization and from keyring-objects initializations with Data::Dumper and couldn't find a difference. I even saved constructed keyring objects to files and initialize Crypt::OpenPGP with this newly created files - still all was crashing. The holy fear seized me and I decided to start my journey to the depth of module forest to find deliverance. I walk through Crypt::OpenPGP to Bytes::Random::Secure, to know that road leads - as it was told to me in the cryptic omen - to Crypt::Random::Seed, line 247, which was a Call to Win32::API function:
My journey comes to a dead end, for I didn't find deliverance there. And I started from the beginning of my code, turning lines of code off one by one. And I found it. This is the code that was a root of all misfortunes.
If you're enlightened enough, you will see my sin right away. I'm not enlightened enough to see it right away, but a doubt crawls into my mind - could it be the line $/ = undef;? I stared at this line for a minute and go search wisdom on the Internet. And then I found the Truth. And as always the Truth was under my nose all the time, but I couldn't see it. It should be local $/ = undef;! I don't know if it is clean and right way to read all file in a string, but even the great Gabor Szabo blesses slurp mode by setting $/ = undef;. But beware if you read his great article not thoroughly! The great misfortune awaits those who forget about local in a rush! Like me for example. You see? Setting $/ = undef; globally make things broken all the way up to the Perl interpreter itself, which was casting strange messages on his way to crash. But why would anyone write about it again, and again, and again? Because, as it said in every language: Repetitio mater studiorum est. Repetition is the mother of all learning. Wiederholen ist die Mutter des Studierens. La répétition est la mère de la science. Повторение - мать учения. Let my mistake will be a lesson to others. Using global variables is always a risky and erroneous path, local variables is the only way to enlightenment. But this is the Truth that we were told from the beginning and we are still making this silly mistakes. And while we code simple programs, errors are simple and debuggable. But when we become more mature - so are the errors that we cause by violation of a simple rules that we doesn't learned well from the start. Beware of global! And bless the local! Amen.
Back to
Meditations
|
|