Opened 5 years ago

Last modified 4 years ago

#279 new enhancement

Refactoring support: automatic global-to-lexical conversion

Reported by: tsee Owned by:
Priority: major Milestone:
Component: Refactoring Perl 5 Version: 0.29
Keywords: refactoring Cc:

Description

I recently had the non-fun experience of having to refactor a moderately large single-file program that was not strict-clean. No variable declarations anywhere.

In such programs, variables are still usually being used like lexicals. Very few variables are *really* global.

My experience was that getting the program strict clean and declaring all variables lexically in the tightest possible scope went a long way towards making the program more readable and accessible.

The way there, however, was paved with rather tedious hours of work. Therefore, I propose the ultimately useful refactoring feature:

In a similar fashion to the lexical-variable renaming, introduce a feature that finds the tightest scope in which a given variable could be declared lexically and then does so. Of course, this doesn't work for true globals, but honestly, I believe those can be identified rather easily in most cases.

This is not an easy task, however. The lexical rename walks the PPI tree upwards until it finds a scope in which (not including arbitrary sub-scopes, I hope) there is a declaration of the variable. This would have to do something remotely similar, but really the other way around. Starting from the top-level, recurse into all sub scopes and find out whether the variable is used there. If it's only used in one of them, go into that one and rinse, repeat. I'm sure there's something (apart from the trivial "this will be ugly to implement using PPI") I'm missing.

Of course, this feature won't work well for reused variable names such as $i for iteration. But it'd still be a start!

Change History (5)

comment:1 in reply to: ↑ description Changed 5 years ago by tsee

Of course, this feature won't work well for reused variable names such as $i for iteration. But it'd still be a start!

Thinking about it, one could actually determine whether the first use of the variable in a given scope is an unconditional assignment such as $i=0 and tighten the scope accordingly. Maybe. It would break if you want the result of the scope to propagate outwards. It's all heuristic anyway.

comment:2 Changed 5 years ago by szabgab

I'd recommend to open a thread about this on use.perl.org

My thought was probably influenced by #277 that I read just before reading this.

If we you can identify foreach loops and the loop variable in each of them
then declaring those with my could eliminate one set of visibly common variable which is actually always private.

comment:3 Changed 5 years ago by szabgab

  • Component changed from editor to advanced perl tools

comment:4 Changed 4 years ago by zenogantner

  • Keywords refactoring added

comment:5 Changed 4 years ago by szabgab

  • Component changed from advanced perl tools to Refactoring Perl 5
Note: See TracTickets for help on using tickets.