Loading ...
Sorry, an error occurred while loading the content.


Expand Messages
  • Rob Nagler
    Jul 29, 2002
    • 0 Attachment
      I'm trying to get an idea what people consider useful refactorings.

      The following refactoring is a very simple one, but I consider it
      useful to demonstrate how Perl statement modifiers can be used and to
      introduce the mechanism by which a document refactorings. The format
      is borrowed from Fowler's Refactoring book (which I highly recommend,

      I've got a number of other refactorings in my book, but some have said
      they are too complicated. I'll send out a few refactorings later
      after I've got some feedback on the format and what your own

      Thanks for the feedback.

      TITLE: Replace Conditional with Modifier


      You have an if statement with a one-line then clause.
      Use a Perl statement modifier to keep data flow on the left.

      unless (defined($value)) {
      return undef;


      return undef unless defined($value);


      This refactoring is controversial, if you aren't used to it.
      I find modifiers are a useful programming technique, when they are
      available. We use them in natural language prose where it makes
      sense. The preceding three sentences are completely normal in
      English even if they sound weird all in a row. The fact is on
      the left of a qualifying clause. It puts the action up front so
      you know what might happen, given a set of circumstances.

      It's common to use return, last, die, etc. in Perl. Early exits limit
      the nesting depth. This is a good thing. Modifiers take this one
      step further by eliminating all nesting, if possible. This keeps data
      flow on the left, which makes it easier to see the side effects, such
      as early exit.

      The roots of programming are based in logic, not in cooking recipes.
      It seems we often forget this. In mathematical theorems, statements
      are often followed by qualifying clauses such as such that and iff.
      Most functional languages put the conditional on the left, which is
      probably a historical artifact of Lisp, a prefix notation language.
      In Prolog, rules are expressed as a fact followed by a condition.
      This refactoring emulates the declarative style of Prolog.

      You shouldn't use this refactoring to slam as many separate statements
      into a single line as possible. For example, this is the wrong way to
      use this refactoring:

      $x = 39, delete($z{$y}) if $is_tuesday; # WRONG USAGE

      This line defeats the motivation of keeping the data flow on the left.
      Too much is happening in one line, and the data operations are
      complete unrelated. This example obfuscates the data flow instead of
      improving it.

      You can convert any if statement into a
      do-if, e.g.

      do { # WRONG USAGE
      $x = 39;
      } if $is_tuesday;

      This doesn't save nesting. There's more code than a simple if
      statement. We aren't trying to put all conditionals last. That's as
      unnatural as ending all conditional English statements with modifying


      1. If the conditional part declares a temporary
      my variable, move the declaration part out.

      2. Remove the braces from the statement and switch the conditional
      order. Do not change the conditional logic.


      Here's a method with two one-line if statements:

      sub from_literal {
      my(undef, $value) = @_;
      unless (defined($value)) {
      return undef;
      $value =~ s/^\s+|\s+$//g;
      unless (defined($value)) {
      return undef;
      return $value;

      We transform the two conditionals into modified statements:

      sub from_literal {
      my(undef, $value) = @_;
      return undef unless defined($value);
      $value =~ s/^\s+|\s+$//g;
      return undef unless length($value);
      return $value;
    • Show all 14 messages in this topic