Randy W. Sims wrote:

> Florian Gross wrote:
>> I've coded up test-extract which lets you embed some of your 
>> test-cases cloaked as sample code into your RDoc strings.
>>
>> It looks like this in practice:
>>
>>>     # Creates a Regexp which matches a literal string. In this
>>>     # string any special regular expression meta-characters will
>>>     # be escaped automatically.
>>>     #
>>>     #   # This creates a Regexp which will match 3 "foo"s.
>>>     #   re = Regexp::English.literal("foo" * 3)
>>>     #   re.match("foofoofoo")[0] # => "foofoofoo"
>>>     def literal(text); Node::Literal.new(text); end
>>
>>
>>
>> (Sample from Regexp::English)
> 
> 
> I very much like the idea of being able to test examples embedded in the 
> source file's documentation. A couple of suggestions:
> 
> 1. Is there some way to allow set-up code that is not part of the 
> viewable documentation? This would make for clearer examples. Eg. the 
> above might be changed to something like:
> 
>   #--
>   # Init:
>   #   foo = Foo.new(blah, blah);
>   #++
>   #
>   # An example of using Foo.bar()
>   #
>   #   foo.bar(blek)
> 
>   def bar(); ...
> 
> Well, that's not real pretty, but... the idea is that the example is 
> more focused for documentation purposes, and all the setup-code is 
> hidden away.

This sounds like a quite good idea -- currently the setup needs to be 
done in the example -- this is okay for most cases, but you don't want 
to set up a new instance in every piece of sample code for Classes that 
need other resources to be instantiated.

If support for this were to be added to RDoc it would be nice if there 
were some kind of marker like "[Setup code hidden]" that could be 
clicked to blend in the rest of the code. I think I've seen something 
similar used in an online Ruby book already.

Can you think of a way to do this that would not need changes of the 
RDoc Ruby code parser? I'll be willing to add support to test-extract, 
but I think it is useless when the syntax doesn't work with RDoc. (If we 
can't find a way to hide the setup code from RDoc we could maybe make 
the syntax self-explanatory so that it can be understood even without 
knowing about it.)

> 2. In addition to showing how something works, it is sometimes 
> instructive to show what doesn't work. Being able to create examples 
> that are expected to fail would be useful.

This is possible already: (Sorry for the long sample.)

   # Causes a pattern which would otherwise match
   # greedily to match non-greedily.
   #
   # This can only be applied to #count and #optional
   # based constructs.
   #
   #   re_greedy = Regexp::English.new do
   #     literal("<") + something + literal(">")
   #   end
   #   re_non_greedy = Regexp::English.new do
   #     literal("<") + something.minimal + literal(">")
   #   end
   #   str = "<html><body>"
   #   re_greedy.match(str)[0]     # => "<html><body>"
   #   re_non_greedy.match(str)[0] # => "<html>"
   #
   # This method will do nothing when applied to a Node
   # which is already minimal:
   #
   #   re_minimal = Regexp::English.something.minimal
   #   re_minimal.minimal == re_minimal # => true
   #
   # However, it will raise a NameError Exception when
   # you try to call it on a Regexp Node that can't be
   # made non-greedy:
   #
   #   re = Regexp::English.literal("foo")
   #   re.minimal # raises NameError
   def minimal
     if self.is_a?(Repeat)
       if self.minimal_flag
         return self
       else
         result = self.clone
         result.minimal_flag = true
         return result
       end
     else
       raise(NameError, "Can't apply minimal")
     end
   end

You can use the following notations:

#  obj.method # raises Exception
#  obj.method # raise Exception
#  obj.method # ~> Exception

I think the first one is the most clear one.

Another notation that I might add in the future is this one:

# puts "foo" # outputs "foo"

or maybe:

# puts "foo" # outputs foo

I'm not sure about it yet and it will need a bit more work than the 
other specification methods, but I think it can be quite useful.

Thanks a lot for giving me feedback on this. It would be great if sample 
code as test cases would be commonly adapted.

Regards,
Florian Gross