Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
We are all familiar with the standard advice. Use strict.pm. It catches typos.

But have you noticed that most other scripting languages don't agree with us? If you look at JavaScript, PHP, Ruby and Python you will look in vain for any corresponding piece of standard advice that makes variable declarations required. Why is this?

My theory is that it is an over-reaction to statically typed languages. When you come from a world where you are used to typing:

FooBar fooBar = new FooBar();
over and over again it is easy to overreact to the realization that constantly declaring types gave you no real benefit. It is more convenient to not declare the types at all, so why not go all of the way and remove the declaration entirely?

As we all know, the answer is that the answer is that the apparent convenience is misleading. Required declarations automatically catch a class of real bugs for you. Not requiring declarations forces eternal vigilance. As I noted in Re: Avoiding silly programming mistakes, eternal vigilance is a bad thing.

However it seems to me that Perl programmers have less cause to be smug than might appear. It seems to me that as a culture we have internalized the practice, but not the principle.

Let me give a simple example that many of us have experienced. Have you ever written any logfile processing? It is pretty straightforward. You parse lines into hash refs, then work with the hash refs. Not exactly hard, and you've likely done it.

Did you think of using Hash::Util's lock_keys function to catch typos in your hash access? I will confess that for years I did not. For me the moment of revelation was when I read Damian Conways PBP and he argued against using Hash::Util because it wasn't secure. And I argued back at the page, "Of course it isn't secure! It isn't supposed to be! It is a strict declaration for hashes!" Then I decided to use it the next time the opportunity came up to see if it was helpful.

When that opportunity arose I found that there is a serious performance penalty, but while developing the log processing I caught 2 bugs that would have otherwise taken me much longer to catch. And found that once developed I could avoid the speed penalty by commenting out one line. I've been using the technique ever since.

Let's move on to argument processing. Most of us know that using named arguments to functions is a good thing. It is common to see people pass hashes into functions, and then process them for exactly that reason. You've probably done it. (If not, then consider it.) But how many of you have a check to find when named arguments are passed in that are not on the list of allowed arguments? I do that, and frequently catch errors where I pass in baz and should have passed in bar. Those errors would otherwise be much harder to catch because to see it you have to carefully compare the function call and definition which are in different pieces of code.

Now let me give a somewhat more bothersome example, which is what prompted this meditation.

Not long ago I had to prepare a small Catalyst site as a code sample. In the process of doing that I was quite surprised to find that if a template variable called a method that wasn't there, you had missing data but no error message to help you track it down. Luckily Template::Stash::Context doesn't suffer from that bug.

But that stash does not catch the use of template variables that were not passed in. But I already had a piece of code for that. Which took more work to produce when I needed it than it really should have. (Sorry, highly non-reusable code for reasons that are mostly out of my control. For Catalyst I also added a few variables that were OK to not pass in.)

And there we have it. The most popular web framework in Perl, using the most popular templating solution, defaults to silently swallowing the most egregious possible signs of error. And unless you really know what you're doing you're not going to find the option of making it helpfully give you a hint of what you did wrong.

So the next time you sit down to write some Perl, pause and give thought to this issue. Think through in different contexts what a "declaration" looks like, and how you might automatically catch things that were not properly declared. The first bug that you automatically catch will likely be your own.


In reply to The value of declarations by tilly

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-23 13:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found