in reply to TDD of non-module code

Put (almost) everything in modules. This makes testing easy, but requires more exposure of subs than I want

I don't understand that point at all; maybe your definition of "exposure" is different than mine.

In Perl, every named subroutine can in principle be called from the outside, independently if it is defined in a script file or a module. (a script can do another script, and then access that second script's subs)

By convention, subs starting with an underscore are consider "private", so if you want to reduce exposure of a sub inside a module, simply mark it with an underscore.

as well as more linkages between modules

I don't see that as a problem either. You can write

# # do stuff 1 here

Or you can write

# use Module::That::Does::What::I::Want qw/doit/; doit(@ARGV); # file Module/That/does/What/I/ package Module::That::Does::What::I::Want; sub doit { # do stuff 1 here }

And have just one more level of indirection, but an easier time to test all the other subroutines from the module without running doit.

Of course that approach isn't very different from writing all the code in the script, no code in the mainline, and at the end of the script putting a

doit(@ARGV) unless caller;

That way you can also load the script as do '' without executing sub doit.

Replies are listed 'Best First'.
Re^2: TDD of non-module code
by davies (Prior) on Jan 24, 2012 at 14:51 UTC

    Your suggestion regarding do looks very interesting. But to go through your points in order:

    My concern about "exposure" (which might not be the best word) is that either I would have to use something like Exporter and end up with sub names in a namespace where I haven't planned for them to be (risking unintended consequences) or I have to use namespace::sub to call them. Maybe it's just prejudice on my part, but this doesn't appeal to me. I can't express my reservations clearly, but I feel uncomfortable doing it.

    As far as adding another level of indirection is concerned, I have no difficulty describing my reservations! :-) I am already passing references around in such a way that leads to code like if (defined $${$${$hashref}{'refTextAry'}}[0]) {. In a separate file, I have over 100 lines of code explaining to myself just why this works. "Just one more level of indirection" fills me with terror. I really wouldn't trust myself to be able to write working tests.

    I am definitely interested in do, though. Unfortunately, the docs seem confusing, at least at first glance.

    do EXPR

    Uses the value of EXPR as a filename and executes the contents of the file as a Perl script.

    do '';

    is just like

    eval `cat`;
    isn't a good start for me. The only time I've met cat is as the Unix equivalent of type, which seems to contradict "executes ... a Perl script". Your explanation seems far clearer, but I'll have to do some experimenting to find out what is and isn't possible.

    Thanks & regards,

    John Davies