From: "vidar.hokstad@..." Date: 2006-02-08T23:43:22+09:00 Subject: Re: Meta-Meta-Programming Daniel Nugent wrote: > Vidar, I think the question there is: Should I rely on a type/method > check to ensure that I don't get bad parameters or should I just write > some tests to make sure that the code in question fails in a sensible > way when those expectations aren't met. Those would be edge cases > after all, and you'd have to write the tests for them anyway. > > To me, it seems to be unDRY... To me the issue is to avoid surprises. If your function will need a specific method every few million times it is executed, or on specific dates, or when a specific race condition occurs, or when processing specific user input, it might require a lot of work for a user of your code to verify that their application works as expected through testing unless they know exactly what they need to test for. More importantly: Unless _they_ verify these preconditions in their test cases they will have to handle whatever you consider a "sensible way of failing". If your failure mode doesn't match their expectations, it might take a lot of work to set verify that there is actually a problem, and it can easily slip through. This is a pragmatic way of ensuring the least possibility of surprise, by forcing a failure as early as possible. The other alternative is to document these cases painstakingly and depend on the users of your code to test for them. But why put your users through that pain if you have an easy way of trapping the error early on that at the same time serves as explicit documentation of what your code expects? I am not saying it's always what you want, or that you'll always see benefits from it. But there are certainly cases where the potential problems caused by a failure are severe enough that it is better to cause a failure early on. If I am going to do batch database updates on a millions of rows for instance, I'd much prefer to find corner cases right away during testing, than risk having the code fail with a NoMethodError two days into a production run because I hit a bizarre corner case. It's not always a case of "just writing some unit tests" unless you first spend ages analysing the code you are calling to verify exactly how to trigger all corner cases. Simplifying unit tests is exactly one of the compelling uses for this - the earlier your methods explicitly check for and fail if preconditions are not met, the smaller the input set you need to test is likely to be. It is even more compelling because it can be easily adapted so that it is easy to turn off for production code if performance becomes an issue: As I suggested, you could easily make the wrapper do nothing unless $DEBUG is defined, for instance. Vidar