http://qs1969.pair.com?node_id=481465

The newbie has questions... the wise old monks have answers... but all too often newbie can't communicate the question, and the wise old monks fall over each other trying to guess what the newbie might have meant -- perhaps what merlyn meant when he wrote "the only personality trait Perl programmers have in common is that they're all pathologically helpful" (Programming Perl, "Perl Culture"). Examples of this happen all the time -- see for instance the recent post at Regex doubt.

Well, pathological helpfulness (or xp greed :) ) has its bright side as a cultural feature, but enough is enough.

With this series of posts I want to help everyone save time, newbies and wise old owls alike, by providing templates for how to ask certain common types of questions. This is intended to be an alternative place to point newbies to, rather than the (also very helpful, but in a more general way) How (Not) To Ask A Question.

As a bonus feature, newbies learning this will also learn Test::More, a powerful tool every monk should incorporate into their life.

The first example will be short. My comments are in ~ . Here goes.

******************BEGIN QUESTION TEMPLATE************************

O Wise Monks, I am having a problem I hope you can help me with.

As you can see, in the following code, my zero test for the "multiplies_by_seven" function fails. ~the problem is isolated~

I tried googling on "perldoc shift" but no dice. Am I searching with the wrong search terms? ~the newbie tried to help himself first before going to the perlmonks~

What the heck am I doing wrong?

~The novice now posts his code using code tags: see Writeup Formatting Tips~

# use strict; #~the newbie has used the strictures~ use warnings; use Test::More qw(no_plan); my ($result, $expected); # ~convenient way to structure your input and expected output is to ~ # ~suck in the test data, which is everything after the __DATA_ line.~ while (<DATA>) { #~splits a string on spaces by default; see perldoc -f split~ my ($input, $expected) = split; my $output = multiply_by_seven($input); is($output, $expected, "testing $input"); } sub multiply_by_seven { my $number = shift or die "no number"; return $number*7; } #~convenient way to structure your input and expected output, #assuming that you can use whitespace as the delimiter. __DATA__ 1 7 2 14 3 21 0 0
I'm on Windows XP system using the standard ActiveState perl distribution. ~The novice mentions what system he is on.~

I got both standard and error output out of my test, into one output file, by running this with perl multiplyBySeven.pl > output.txt 2>&1 output.txt. ~Enables newbie to communicate his test result with a minimum of putzing around~

The output is:

ok 1 - testing 1 ok 2 - testing 2 ok 3 - testing 3 no number at multiplyBySeven.pl line 18, <DATA> line 4. 1..3 # Looks like your test died just after 3.

Any ideas? Thanks very much in advance, o wise monks :)

******************END QUESTION TEMPLATE************************

That's basically it. Why the 0 test fails is left as an exercise for the reader :)


Update: More tutorials in this series to come. See tphyahoo's homenode for tutorials under construction :)

Replies are listed 'Best First'.
Re: How to Ask a Question (With Test::More) (repost, now with Sitedocclan approval.)
by BrowserUk (Patriarch) on Aug 06, 2005 at 10:41 UTC

    How is this better than?

    Why does this shappen?
    #! perl -slw use strict; sub times7 { my $number = shift or die "no number"; return $number*7; } print "times7( $_ ) returned:", times7( $_ ) for 1, 2, 3, 0; __END__ P:\test>junk times7( 1 ) returned:7 times7( 2 ) returned:14 times7( 3 ) returned:21 no number at P:\test\junk.pl line 5.

    Seems to me that you are trying to address peoples inability to explain their problem, but asking them to learn to use a module that they almost certainly know nothing about, and serves no good purpose but to complicate the issue?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
      Point taken browseruk, but I still believe in my tutorial.

      I think testing is a whole mindset, and it is a mindset it would have done me good to pick up earlier in the learning curve. Being encouraged to do this early on would have been a good thing.

      Maybe the example I used could have been better though. You think it would be better if one of the tests fails, rather than just dying? I am thinking of changing my post along these lines.

        Quite frankly, I think that in most instances, it is simple better to allow Perl to detect these kind of trivial errors, It most times does a better job of reporting the nature of the problem than the programmer will:

        #! perl -slw use strict; sub times7 { return $_[ 0 ] * 7; } print "times7( $_ ) returned:", times7( $_ ) for 1, 2, 3, 0, undef, 'f +red'; __END__ P:\test>junk times7( 1 ) returned:7 times7( 2 ) returned:14 times7( 3 ) returned:21 times7( 0 ) returned:0 Use of uninitialized value in concatenation (.) or string at P:\test\j +unk.pl line 8. Use of uninitialized value in multiplication (*) at P:\test\junk.pl li +ne 5. times7( ) returned:0 Argument "fred" isn't numeric in multiplication (*) at P:\test\junk.pl + line 5. times7( fred ) returned:0


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
Re: How to Ask a Question (With Test::More)
by CharlesClarkson (Curate) on Oct 20, 2005 at 10:36 UTC
    1.  everything after the __DATA_ line.~

      Should read:

       everything after the __DATA__ line below.~

      Perhaps it should read like this, but it may also confuse.

       everything after the __DATA__ (or __END__) line below.~
    2. I don't understand which part of this is template and which is your comment. In fact, I'm not sure I even understand the comment.

      #~convenient way to structure your input and expected output, #assuming that you can use whitespace as the delimiter.

      I think you meant to do this.

      #~convenient way to structure your input and expected output,~ #~assuming that you can use whitespace as the delimiter.~

      But that still sounds like I (the newbie) cannot use this method on pipe delimited data. I (the advanced beginner) realize you don't mean that, but you need to put yourself in your student's heads. The student sees this example and wonders how they can adapt there script to look like this one. "But wait," they think, "I don't have a script which opens a file."

      You haven't explained to them how to use Test::More. You have not shown them how to test their data with test cases and you haven't showed them what your example script looked like before you started testing.

    3. Have you read the Test::More docs recently?

      STOP! If you're just getting started writing tests, have a look at Test::Simple first. This is a drop in replacement for Test::Simple which you can switch to once you get the hang of basic testing.

      So, here is our lowly newbie taking the high road and looking for some clue on how to ask questions before posting to Perl Monks. She sees your tutorial and starts reading. She gets to the module you want her to use and thinks: "I have no clue how to use a module. And just where in blazes is the is() subroutine coming from?" Let me go read the Test::More docs and (wham!), she finds she now must go learn yet another module (actually two more modules-see below).

      There's just too many points at which she can bail out and ask her question anonymously or worse, not ask any question at all. Just giving up on Perl altogether.

      I would gently introduce the reader to the Test::More module and then show the reader templates for asking questions. Perhaps their question will be answered in the test setup. Perhaps not. Either way, they now have another tool for solving their future perl problems.

      Oh and BTW, the Test::Simple module begins with ** If you are unfamiliar with testing read Test::Tutorial first! ** Test::Tutorial is part of a module's (Test::Simple) documentation. Which means http://search.cpan.org/ can't find it (and it isn't linked from the module docs). Heck, I'm ready to bolt! It's like you had to throw this tutorial together on a deadline.

    4. I associate a template with a fancy (or plain) fill in the blank form. I am asked questions and the answers are entered into the template. Then some magic happens and my question is ready to be asked. I don't see that association from your template.

    I guess I'm saying (as gently as possible) that you need to be a bit more long winded. Explain each step to the student. Don't assume she already knows Test::More and Test::Simple and Test::Tutorial and how to find the docs for further reading. Assume she has no freaking clue how to properly ask a question on Perl monks and assume she is ready to bolt from your class for the slimmest reasons.

    HTH,
    Charles