In my rails app I've decided to use singleton to create some sort of factory to get objects properly.
config/initializers/registry.rb:
registry = Registry.instance
registry.define_lazy :period_predictor do
PeriodPredictor.new(NotificationBuilder.new, 28, 4, 3)
end
registry.define_lazy :notification_sender do
NotificationSender.new
end
lib/registry.rb:
# Registry class which is singleton and stores values.
class Registry
include Singleton
# Define simple value. Like a constant.
#
# @param key [Symbol]
# @param value
def define(key, value)
container[key] = value
end
# Define value (block required) which will be calculated when it will be need.
# It will calculate it every time when it will be needed.
#
# @param key [Symbol]
# @param block [Proc]
def define_lazy(key, &block)
container[key] = LazyValue.new(&block)
end
# Get value.
#
# @param key [Symbol]
#
# @return
def get(key)
value = container[key]
if value.is_a?(LazyValue)
value = value.call
end
value
end
# Get value (hash access).
#
# @param key [Symbol]
#
# @return
def [](key)
get(key)
end
# Export all the values.
# Replacing values of returned hash won't change registry.
#
# @return [Hash]
def export
container.clone
end
# Import hash data to registry
#
# @param data [Hash]
def import(data)
data.each do |key, value|
@container[key] = value
end
end
private
# Get container.
#
# @return [Hash]
def container
@container ||= {}
end
# Class to store lazy value.
class LazyValue
def initialize(&block)
@block = block
end
def call
@block.call
end
end
end
Everything works fine in production. But when I change something (even add space somewhere), I can't get data from singleton anymore in controllers.
Registry.instance became just fresh instance of registry and Registry.instance[:period_predictor] became nil
Same thing happens when I just go away with singleton and make class methods.
It does not do this thing only if I turn off singleton and create a constant:
registry = Registry.new
registry.define_lazy :period_predictor do
PeriodPredictor.new(NotificationBuilder.new, 28, 4, 3)
end
registry.define_lazy :notification_sender do
NotificationSender.new
end
REGISTRY = registry
Rails version 4.2.5.1
Do someone have any ideas why this is happening?
I've figured out, that it happenes because Rails refreshes autoloaded constants. http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#constant-reloading
I've added line require "#{Rails.root}/lib/registry" at the beggining of initializer and everything is OK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With