title: Perl Subroutine Prototyping -- The correct way to do it
body: <p>I have a subroutine called <code>debug</code> I use in my code. It basically allows me to see what's going on, etc.</p>
  
  <pre><code>sub debug {
      my $message      = shift;
      my $messageLevel = shift;
  
      our $debugLevel;
      $messageLevel = 1 if not defined $messageLevel;
      return if $messageLevel &gt; $debugLevel;
      my $printMessage = "    " x $messageLevel . "DEBUG: $message\n";
      print STDERR $printMessage;
      return $printMessage;
  }
  </code></pre>
  
  <p>I want to prototype this, so I can do things like this:</p>
  
  <pre><code>debug "Here I am! And the value of foo is $foo";
  </code></pre>
  
  <p>or</p>
  
  <pre><code>debug "I am in subroutine foo", 3;
  </code></pre>
  
  <p>At the same time, I like putting subroutine definitions at the bottom of my program, so you don't have to wade 1/2 way through the code to find the meat of the program.</p>
  
  <p>I'd like to do this:</p>
  
  <pre><code>sub debug($;$);  #Prototype debug subroutine
  
  /Here goes the main program code/
  
  sub debug {      #The entire subroutine goes here
     /Here goes the debug subroutine code/
  }
  </code></pre>
  
  <p>However, I get a warning when I do this:</p>
  
  <pre><code>Prototype mismatch: sub main::debug ($;$) vs none at foo.pl line 249.
  </code></pre>
  
  <p>So, I'm stuck putting the prototype definition in both places. What is the correct way to do something like this?</p>
  
  <hr>
  
  <h1>RESPONSE</h1>
  
  <blockquote>
    <p>Stop! Module time. – Chris Lutz</p>
  </blockquote>
  
  <p>A module? You mean create a separate file? That adds a bit of complication without solving the issue I'm trying to solve: Removing the need for parentheses around this particular subroutine.</p>
  
  <blockquote>
    <p>our $debugLevel; should not be in the sub body anyway, but I agree with Chris on this. – Sinan Ünür 3 hours ago</p>
  </blockquote>
  
  <p>The <code>our $debugLevel</code> does not have to be there in this case, but if I defined a class and I want to use this subroutine in my class for debugging, I need it. I can put it in my class as <code>::debug</code></p>
  
  <blockquote>
    <p>Surprisingly, <a href="http://perlmonks.org/?node_id=861966" rel="nofollow noreferrer">Far more than everything you ever wanted to know about prototypes in Perl</a> doesn't address this, but I believe you cannot avoid writing the prototype in both places.</p>
  </blockquote>
  
  <p>I was hoping for an easy way to avoid it. There is a way as Eric Strom showed. Unfortunately, it's longer than my <code>debug</code> routine.</p>
  
  <blockquote>
    <p>I used to use prototypes, but I've developed the habit of not writing separate declarations for subroutines and using parentheses on all calls: debug("I am in subroutine foo", 3);. It's been suggested that prototypes really aren't a good idea. TMTOWTDI – Keith Thompson 3 hours </p>
  </blockquote>
  
  <p>Except I'll tend to do:</p>
  
  <pre><code>debug (qq(The value of Foo is "$foo"), 3);
  </code></pre>
  
  <p>which can be less clear when reading, and can be a pain to type. Whenever you double up parenthese, you're asking for trouble. The last thing I want to do is debug my debug statements.</p>
  
  <blockquote>
    <p>Why do you want prototypes? See this question <a href="https://stackoverflow.com/q/8124138/">How to pass optional parameters to a Perl function</a> – TLP</p>
  </blockquote>
  
  <p>Yes, there are lots of problems with prototyping. The main problem is that it simply doesn't do what people think it should do: Declare the variable types for the parameters you're passing to your function.</p>
  
  <p>This is not the reason I'm using prototyping here.</p>
  
  <p>I rarely use prototypes. In fact, this is probably the only case in all of my code where I do.</p>