Austin said:
Aye, so I'll start. If you're going to extend core or standard library
classes, you should:
1. Do so only at the user's request.
I disagree. requiring a library should extend stuff in the standard
library if that is proper behavior for the library. E.g. require 'foo'
might well inject a parsing ctor into String as String#to_foo, if it
made sense to do so. I don't see any difference between a library and a
framework extending Fixnum with #day as per Rails. I agree strongly
with documenting it in a very loud tone of voice, however.
1.1 Do not change existing behavior of external classes or modules.
1.1.1 If you reopen an external class and redefine an existing method,
should Ruby issue a warning? Is there a safe_level that will prevent a
library from touching external classes?
1.1.2 Before adding a new method to a class or method, consider testing
with respond_to? to see if it really is a new method, and raising a
warning if it isn't.
4. In a library, never change existing behavior of code outside the
library. If I have a set of unit tests for a class, and I require your
library, all of the unit tests for my class must still pass.
It would be really useful if there were an idiomatic way of testing the
Core, StdLib and any modules the library required. Then a sanity test
could be run against the library verifying that all is as it should be.
This wouldn't be a short unit test, but something akin to the exhaustive
setup test you can run after building Ruby. It would be useful before
*publishing* a library to validate its sanity. Perhaps if you propose
to publish a module called foo, you may put test_foo.rb in the same
directory, or in ../test/test_foo.rb, and for any modules you require
that also provide a test_*.rb module, the sanity checker would run them
as well. Finally, modules in the RAA or other major repositories could
have the sanity checker's output placed alongside, letting the user know
to what extent it has been tested.
-dB