Be aware that if you use SimpleDelegator with Rails, you may see autoloading issues.
Specifically, if you have something like
then that class won’t be autoloaded. In a Rails console:
>> MyThing => MyThing >> MyThing::Subthing NameError: uninitialized constant Subthing >> require "my_thing/subthing" => true >> MyThing::Subthing => MyThing::Subthing
Both Rails (code) and SimpleDelegator (code) hook into
const_missing. Rails does it for autoloading. Since the
SimpleDelegator superclass is earlier in the inheritance chain than
Module (where Rails mixes it in), this breaks Rails autoloading.
How do you get around this?
You could stop using
require won’t work well – I think what happens is that the Rails development reloading magic undefines the constant when the file is changed. An explicit
require_dependency does appear to work:
1 2 3
Or you could override the
const_missing you get from
SimpleDelegator to do both what it used to do, and what Rails does:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
But keep in mind that this may vary with Rails versions and may break on Rails updates.
::Object.const_get(const_name) thing is explained in the
This is a tricky problem. Perhaps the best solution would be for Rails itself to monkeypatch
SimpleDelegator. That fixes the autoloading gotcha but may cause others – I once had a long debugging session when I refused to believe that Rails would monkeypatch the standard lib
ERB (but it does, for
This blog post is mainly intended to describe the problem – I’m afraid I don’t know of a great solution. If you have any insight, please share in a comment.