Search code examples
perlperl-tidy

Convincing Perltidy to leave whitespace alone


I am using Perltidy to reformat a few of my old Perl files to a style that is closer to my current preferences. I encountered an issue with this snippet:

Fcntl::S_IRUSR & $mode

Perltidy insists on removing the space after the & token, resulting into this:

Fcntl::S_IRUSR &$mode

...which in my opinion is an eyesore. What can I do to convince Perltidy to leave that single space alone? I even tried the -fws option to no avail.

I am using Perltidy 20101217, which is apparently the latest version.

EDIT:

A few additional observations:

  • Using the --indent-only (-io) option does not remove the aforementioned space.

  • The following equivalent snippet is not affected by this issue:

    $mode & Fcntl::S_IRUSR
    

EDIT 2:

I ended up reversing the order of the & operator arguments, since that seems to work around the Perltidy issue for the time being. In addition this approach does not require adding extra parentheses or any other tokens that might help Perltidy do The Right Thing, but would certainly confuse me in the long run.

UPDATE:

I contacted Steve Hancock, the author of Perltidy, about this issue. From his response:

I checked and the problem is that the & is being mistokenized in this case as a function call sigil. The basic problem is that perltidy does not see prototypes for other modules, even built-in, so it has to guess when it comes to something like "Fcntl::S_IRUSR". In other words, it doesn't know if this is a function call or a constant, and has to guess. When you reversed the order it removed the ambiguity on the &.

Thanks for the note. I'll see if I can come up with a patch to fix this.


Solution

  • It surely incorrectly thinks

    Fcntl::S_IRUSR & $mode
    

    means

    Fcntl::S_IRUSR(&$mode)
    

    You can probably trick it by using

    (Fcntl::S_IRUSR) & $mode
    

    or

    Fcntl::S_IRUSR() & $mode