My Sinatra In-Memory Datastore & Finding a Ruby Method Owner
After spending a week messing around with Sinatra configs, Singletons and class variables trying to set up the in-memory datastore for my app I finally found what I was looking for yesterday. Although I must have looked at the configuration section of the Sinatra README a dozen times, it was this Stack Overflow post that was explicit enough to hit me over the head with it. (It’s scenarios like this that make me feel like such a noob.)
Setting the Settings
Sinatra offers all sorts of settings that you can configure like port, protection, logging, environment...
and you just do it inside the configuration block in your main app file. For example, if you wanted to set the environment to test you just do this:
configure do
set :environment, :test
end
But, you can actually set any object you want in your configurations and it will attach itself to the ‘settings’ object that’s available throughout your app (which is of course, slightly dangerous, but for now it’s what I’m going with).
For example, if you want to set an object called examplevariable you could do it like this:
configure do
set(:examplevariable, "This is just a string but could be an anything you want")
end
Now, anywhere inside your app you can call settings.examplevariable
and it will return the string object “This is just a string but could be an anything you want”.
Now here’s a slightly simplified version of the code in my Foundry app that I used to set the datastore:
class Foundry < Sinatra::Application
configure do
set :datastore, MemoryDatastore.new
end
end
Now I can use commands like the ones below to access the datastore anywhere (even the views if I wanted to make a really bad design decision):
settings.datastore.save(user_object)
settings.datastore.find_by_id(id)
settings.datastore.delete(id)
settings.datastore.all
The one thing I wanted to figure out in order to properly test my app and be able to mock or stub out the datastore when necessary, was what exactly “owned” the settings. Where did they live?
Finding a Ruby method’s owner
I don’t know if this is something that I read once and forgot, or if it’s something that I just hadn’t discovered yet, but you can find any Ruby method’s owner with the following:
method(:method_name).owner
So by adding the following line to my test:
puts "The owner of settings is #{method(:settings).owner}"
I was able to discover that Sinatra::Delegator owns the settings method. That’s acceptable to me and much better than my previous class variable solution- which ended up on the Ruby Object class! I may be a noob, but even I know that’s definitely not the place for an in-memory database.
With all that out of the way, it’s time to knock out some stories on this app.