Some comments on the "action at a distance" effect.
I guess this is why I have become more and more a fan of truly functional programming, especially for the lack of side effects. I try very hard to avoid all "action at a distance" coding
Explicitly I try to write code
- consisting only of functions i.e. the main script is as small as possible, work is handed off to a function in a module as soon as possible. Typically my main script is limited to reading and checking constraints on command line options
- I try really hard to not have a function refer to anything outside of its immediate scope.
- I can only use a module's services via its functional interface i.e. I cannot do $Some::Module::variable = 'ugh'; from anywhere except inside Some::Module
- I try to limit functions to using only the parameters they are passed. When absolutely required, I will access a variable in the modules scope, but outside the modules function e.g. I try to avoid
Package Some::Module;
...
my $some_state = 'something';
...
sub some_func {
...
$some_state = 'new state';
...
}
as much as possible.
- For objects, I also try to apply these principles - except where really required, I prefer to use $self->some_accessor() than $self->{some_attribute}
- When I do have to break these rules and effect an "action at a distance" , it is really clear that I have to. The reason may be bad design or bad implementation, but at some point I have to say "until I can think of a better way, lets mark this as a TODO, and keep coding". Once the job at hand is working, I try to come back to the one or two instances of "action at a distance" and try to find a way to remove them
I have found this approach has made my code much better structured, much less complex, more flexible and more reusable.
...it is better to be approximately right than precisely wrong. - Warren Buffet