This is actually a very complicated way of achieving the goal. It works, but it's not good from an economic point of view as it is more expensive in computational terms than a simpler OO alternative, which is to pass the size when you instantiate the MegaLotto::Drawing object.<p>For example, compare the proposed solution:<p><pre><code> MegaLotto.configure do |config|
config.drawing_count = 10
end
MegaLotto::Drawing.new.draw
</code></pre>
With the alternative:<p><pre><code> MegaLotto::Drawing.new(10).draw
</code></pre>
If you want to make it extensible, you can use keyword arguments:<p><pre><code> MegaLotto::Drawing.new(size: 10).draw
</code></pre>
The interface and the implementation are simpler, but also the performance is better because there are less method calls. If you look at the code of both implementations, you will find the simpler one easier to understand. As a side effect, you will also get simpler stack traces if anything goes wrong.
I wish people would stop doing this.<p>It generally means down the road I find myself wanting to use two different configurations and everything explodes in my face because the author of the gem thought there would always be exactly one configuration.<p>What is wrong with<p><pre><code> MegaLotto.new do |lotto|
lotto.drawing_count = 10
end
</code></pre>
and just wrapping it in a "default_megalotto" factory method?
This is a great approach for setting config variables. I also like to enable the user to add custom functionality to the gem by accepting a block that is called with any relevant variables for the user to access.<p>For example, in Exceptionally[1], the user can add an initializer that looks like:<p><pre><code> Exceptionally::Handler.before_render do |message, status, error, params|
# put any code here
end
</code></pre>
In the gem, this translates to:<p><pre><code> def self.before_render(&block)
&&callback = Proc.new(&block)
end
</code></pre>
The gem can then call the user's block and give it access to the same variables the rest of the gem does. This approach is a lot simpler than setting up an entire Middleware stack, as suggested in the blog, and makes more sense for simpler gems.<p>1: <a href="https://github.com/neilgupta/exceptionally" rel="nofollow">https://github.com/neilgupta/exceptionally</a>
Check out my configuration gem.<p><a href="https://github.com/GeorgeErickson/bonfig/" rel="nofollow">https://github.com/GeorgeErickson/bonfig/</a>