Skip to content

Instantly share code, notes, and snippets.

@sesharim
Created March 9, 2015 10:59
Show Gist options
  • Save sesharim/26eebf8663ade1c6e236 to your computer and use it in GitHub Desktop.
Save sesharim/26eebf8663ade1c6e236 to your computer and use it in GitHub Desktop.
Dynamic config
# I was considering how I might want to further implement my gem and incorporate configuration settings for it. I wanted only one instance of my configuration and it needed to be part of my module. So I’ve come up with a solution I like that allows me to do this and even have a true “sense” of untouchable constants.
# I’ve found OpenStruct to be for my liking in this situation as it allows for any configuration (variable) to be set on it. I’ve also found I can set “unalterable” variables… at least through standard assignment options.
# The reason I created the class MyProject::MyConfig just to inherit OpenStruct is that I want my configuration to be identified by a class name that indicates it is a config object that belongs to my project. In module MyProject I use attr_reader for config because we are getting the OpenStruct instance handed back to us and we can still invoke method/value assignment on it. I use the single class variable @config for the internal singleton value because it’s not going anywhere (No need to use @@config). The method config is defined on the singleton instance of the module MyProject via the class << self. So to set any value all I need to do is MyProject.config.new_value = 42.
require 'ostruct'
class MyProject::MyConfig < OpenStruct
end
module MyProject
attr_reader :config
class << self
def config
@config ||= MyConfig.new
end
end
end
# EDITABLE
MyProject.config.new_value = 42
MyProject.config.new_value
# => 42
MyProject.config.hair = :awesome
MyProject.config.hair
# => :awesome
MyProject.config.hair = :bad_hair_day
MyProject.config.hair
# => :bad_hair_day
# If I want to set a constant value that I don’t want to change then all I have to do is define the method within the OpenStruct instance. You can do it in the class, or open it up with the singleton opener.
class MyProject::MyConfig < OpenStruct
def no_touchy
:always_this
end
end
x = MyProject::MyConfig.new
x.no_touchy
# => :always_this
x.no_touchy = 493872
x.no_touchy
# => :always_this
class << x
def also_no_touchy
:cant_touch_this
end
end
x.also_no_touchy
# => :cant_touch_this
x.also_no_touchy = :batman
x.also_no_touchy
# => :cant_touch_this
# If you want a default value that can be updated; then you may implement that method with a method_missing(:method_name) || :value . As soon as you assign a new value it will choose the updated value.
class MyProject::MyConfig < OpenStruct
def no_touchy
:always_this
end
end
x = MyProject::MyConfig.new
x.no_touchy
# => :always_this
x.no_touchy = 493872
x.no_touchy
# => :always_this
class << x
def also_no_touchy
:cant_touch_this
end
end
x.also_no_touchy
# => :cant_touch_this
x.also_no_touchy = :batman
x.also_no_touchy
# => :cant_touch_this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment