Followup to the majordomo issue
#82 Henry, Thursday, 03 March 2011 9:42 AM (Category: Email)
(Tags: majordomo)

While I was in the first phase of testing majordomo, I did find one other problem with the old Perl 4 coding of majordomo and the new version of Perl that I upgraded to. I saw this warning:

$* is no longer supported at majordomo.pl line 47.

I thought this might have been causing the original problem, so I dug into it and fixed it, and then found that it didn't fix my original problem.

In majordomo.pl, there is a function ParseMailHeader. This saves the state of two magic variables, changes them, then restores the state. One is still valid, but $* no longer works that way. It worked okay in Perl 4, and Perl 5 allowed it until recently. Now Perl complains about it.

sub main'ParseMailHeader  ## Public
{
    local($save1, $save2) = ($*, $/);
    local($FH, *array) =  @_;
    local ($keyw, $val);

    %array = ();

    # force unqualified filehandles into callers' package
    local($package) = caller;
    $FH =~ s/^[^':]+$/$package'$&/;

    ($*, $/) = (1, '');
    $array = $_ = <$FH>;
    s/\n\s+/ /g;

    @array = split('\n');
    foreach $_ (@array)
    {
        ($keyw, $val) = m/^([^:]+):s*(.*S)s*$/g;
        $keyw =~ y/A-Z/a-z/;
        if (defined($array{$keyw})) {
            $array{$keyw} .= ", $val";
        } else {
            $array{$keyw} = $val;
        }
    }
    ($*, $/) = ($save1, $save2);
}

I fixed it very roughly, by not using the $ magic variable. What they are trying to do is save the state of the magic variable that affects search in multi-line text variables, then change that variable so they can search through multi-line variables, then change it back again to the previously saved state. You don't need to do this anymore, because you can use the /m switch on the search to achieve the same result. So I removed the save of $, removed the setting to the new value, and removed the change back to the old state. In the search that uses it, I added the /m switch which does the same thing. The code now looks like this:

sub main'ParseMailHeader  ## Public
{
    local($save) = $/;
    local($FH, *array) =  @_;
    local ($keyw, $val);

    %array = ();

    # force unqualified filehandles into callers' package
    local($package) = caller;
    $FH =~ s/^[^':]+$/$package'$&/;

    $/ = '';
    $array = $_ = <$FH>;
    s/\n\s+/ /mg;

    @array = split('\n');
    foreach $_ (@array)
    {
        ($keyw, $val) = m/^([^:]+):s*(.*S)s*$/mg;
        $keyw =~ y/A-Z/a-z/;
        if (defined($array{$keyw})) {
            $array{$keyw} .= ", $val";
        } else {
            $array{$keyw} = $val;
        }
    }
    $/ = $save;
}

The same problem occurs in the digest program, but I don't use this, so I didn't bother fixing it there.

Over the years, my Perl programming has veered towards the simplistic. I write explicit code and have veered away from using all the magic variables except $. This experience with majordomo is pushing me to avoid using even $. You never know how long your code will be used for. If you are explicit and don't rely on magic variables, your code has a better chance of being understandable and fixable and changeable ten or twenty years later. On the other hand, the $ variable is so useful. On the third hand, if you don't have a good grasp of Perl and you come back years later, it's hard to understand what is happening when $ is not mentioned in the code but is implicitly used everywhere.

0 comments