Wednesday, July 29, 2009

How to module_eval

In my whole Ruby Metaprogrammer life I have never used any *_eval string.
This was a deliberate choice I made and I still believe that it was reasonable in the sense that it suits my style. Personally I was able to structure and refactor my metacode much better, well, I thought...

Now I am working on code that shall be used as a library, closely related to core, thus, hopefully widely used. I am not a fan of premature optimization. I often use methods like Enumerable#inject for there elegance not worrying at all about the speed.
This is the exception
But then there is this of course:

Monday, July 27, 2009

Why I use Verify

I was just "specing" up my Thread Safe Wrappers when I stumbled about methods on Array I had never seen before.Eg. #taguri=. Realizing that it ( and some others ) were introduced by rspec I had a choice between a rock and a hard place: Either not using introspection in my definitions of methods in the Array wrapper (and probably the same for Hash, String and friends), or deleting those methods manually.
The first choice is just impossible because it would mean lots and lots of typing, which is just unacceptable, and the second choice would mean that there would be code in the production code which is there for the sole purpose of not implementing methods from the Rspec framework.

It occurred to me than that Verify has been written for that exact reason by YHS. Not to step on the toes of the testee!

I immediately started to rewrite my *_spec.rb files into *_verify.rb files (not that this convention is enforced by Verify but it seems good practice ;). And it was just then that I realized I did not know my API (as lean as it is) by heart and I had to go into the examples folder of my GIT repository to find it.

That is unacceptable, we need this stuff on the web, right?

Here we go then:

 7 require 'mockify'
 8 require 'verify'
 9
10 Verify "Some Important Facts" do
11   verify "42 is true" do
12     42
13   end
14   refute "42 is pretty big" do
15     42 > 100_000
16   end
17   verify_exceptions NoMethodError do
18     42.unrelinguished!
19   end
20 end
21
22 Verify "With parameters" do
23   verify msg: "Everything is well", target: 42, actual: 21 * 2
24   refute msg: "But not too much",   target: 42, actual: 41
25 end
26
27 Verify "Capturing stdout" do
28   out = with_output do | o |
29     puts 42
30     verify target: "42\n", actual: o.string
31     puts
32     verify target: "42\n\n", actual: o.string
33   end
34   verify msg: "with_output converted out to an array of lines",
35     actual: out.map( &:chomp ),
36     target: [ "42", "" ]
37 end
38
39 Verify "Providing stdin" do
40   with_input %w{The Quick Brown Fox} do
41     verify %{first line is "The"} do
42       "The" == gets.chomp
43     end
44   end
45 end