Currently, tilt uses the value of Hash#keys directly as the cache key. On ruby 1.8 this results in 2^N possible cache entries for the template, where N is the number of keys in locals, because Hash#keys returns the keys in an arbitrary order on 1.8. Even on 1.9, where Hash#keys returns the keys in entry order, this can cause similar issues unless user code always enters the keys in the hash in the same order. I chose to put this code in evaluate instead of compiled_method itself, because evaluate creates the array and can use sort! to sort it. If done in compiled_method, locals_keys is the argument, and mutating arguments is generally a bad API practice, so you'd have to use sort, which would cause an extra array allocation.
This avoids calling the block again with the same arguments and having it do some possibly expensive processing only to return nil again.
The default Docbook backend in Asciidoctor 1.5.0 has been changed to docbook5. The existing Docbook test in `tilt_asciidoctor_test.rb` expects Docbook 4.5 output, so it should use the `docbook45` backend. I added a new test with different expected output for the `docbook5` backend. There is no longer a test for the `docbook` backend since its output can change depending on the installed version of Asciidoctor.