I agree with [@amon][1]'s answer for the most part. In addition, I propose an alternative implementation to eliminate this kind of duplicated logic:

>     if ($alignment eq SOME_ALIGNMENT) {
>         for my $line (@lines) {
>             my $padding = $max_length - length $line;
>             $line = PADDED_LINE
>         }
>     }

You can eliminate this duplication by putting the different alignment formatting functions into a map:

    sub align_left {
        my ($line, $padding) = @_;
        return $line . " " x $padding;
    }
    
    sub align_right {
        my ($line, $padding) = @_;
        return (" " x $padding) . $line;
    }
    
    sub align_center {
        my ($line, $padding) = @_;
        # we divide the $padding into two halves: $left and $right.
        # But what if $padding is an odd number?
        # Let's put the smaller padding $left.
        my $left = int($padding / 2);
        my $right = $padding - $left;
        return (" " x $left) . $line . (" " x $right);
    }
    
    my %align_fn = (
        left => \&align_left,
        right => \&align_right,
        center => \&align_center,
    );

This will simplify the main function a bit:

    sub align {
        my ($text_to_align, $alignment) = @_;
        my $fn = $align_fn{$alignment} || do {
            # this happens if an invalid $aligment was passed as argument.
            # Let's throw an error. We could use `die`, but that doesn't tell
            # an user of our function where *he* made an error. Instead, we use
            # the Carp module:
            require Carp;
            Carp::croak("Alignment must be one of left, right, center.");
        };
    
        my @lines = split /\n/, $text_to_align;
    
        # Trim whitespace, and find the longest line.
        # This is an OK use-case for the $_ variable.
        my $max_length = 0;
        for (@lines) {
            # I prefer \A and \z over ^ and $ because they always match at
            # string beginning and end, and are never influenced by /m.
            s{\A\s+}{};
            s{\s+\z}{};
            $max_length = length if length > $max_length;
        }
    
        # Perform the alignment, depending on the alignment type.
        # The alignment is performed in-place.
        for my $line (@lines) {
            my $padding = $max_length - length $line;
            $line = $fn->($line, $padding);
        }
    
        # join the lines back together again, and return
        return join "\n", @lines;
    }

  [1]: http://codereview.stackexchange.com/users/21609/amon