title: How should I handle errors in Perl methods, and what should I return from the methods?
body: <p>I've wrapped Perl's <a href="http://search.cpan.org/perldoc?Net::SSH::Expect" rel="nofollow noreferrer">Net::SSH::Expect</a> with a small module to reduce the boilerplate code needed to write a new configuration script for use with our HP <a href="http://en.wikipedia.org/wiki/HP_Integrated_Lights-Out" rel="nofollow noreferrer">iLO</a> cards. While on one hand I want this wrapper to be as lean as possible, so non-programmer colleagues can use it, I also want it to be as well-written as possible.</p>
  
  <p>It's used like so:</p>
  
  <pre><code>my $ilo = iLO-&gt;new(host =&gt; $host, password =&gt; $password);
  $ilo-&gt;login;
  
  $ilo-&gt;command("cd /system1");
  $ilo-&gt;command("set oemhp_server_name=$system_name", 'status=0');
  </code></pre>
  
  <p>and this is <code>iLO::command()</code>:</p>
  
  <pre><code>sub command {
      my ($self, $cmd, $response) = @_;
  
      $response = 'hpiLO-&gt; ' unless defined($response);
  
      # $self-&gt;{ssh} is a Net::SSH::Expect object
      croak "Not logged in!\n" unless ($self-&gt;{ssh});
  
      $self-&gt;{ssh}-&gt;send($cmd);
      if ($self-&gt;{ssh}-&gt;waitfor($response, $self-&gt;{CMD_TIMEOUT}, '-re')) {
          return {
              before =&gt; $self-&gt;{ssh}-&gt;before(),
              match =&gt; $self-&gt;{ssh}-&gt;match(),
              after =&gt; $self-&gt;{ssh}-&gt;after(),
          };
      } else {
          carp "ERROR: '$cmd' response did not match /$response/:\n\n",
              $self-&gt;{ssh}-&gt;before()),
              "\n";
          return undef;
      }
  }
  </code></pre>
  
  <p>I have two related queries. First, how should I deal with responses that don't match the expected response? I guess what I'm doing now is satisfactory -- by returning <code>undef</code> I signal something broke and my <code>croak()</code> will output an error (though hardly gracefully). But it feels like a code smell. If Perl had exceptions I'd raise one and let the calling code decide whether or not to ignore it/quit/print a warning, but it doesn't (well, in 5.8). Perhaps I should return some other object (<code>iLO::response</code>, or something) that carries an error message and the contents of <code>$ilo-&gt;before()</code> (which is just Net::SSH::Expect's <code>before()</code>)? But if I do that -- and have to wrap every <code>$ilo-&gt;command</code> in a test to catch it -- my scripts are going to be full of boilerplate again.</p>
  
  <p>Secondly, what should I return for success? Again, my hash containing more-or-less the response from Net::SSH::Expect does the job but it doesn't feel 'right' somehow. Although this example's in Perl my code in other languages emits the same familiar smell: I'm never sure how or what to return from a method. What can you tell me?</p>