Class: Settingslogic
- Inherits:
-
Hash
- Object
- Hash
- Settingslogic
- Defined in:
- lib/settingslogic.rb
Overview
A simple settings solution using a YAML file. See README for more information.
Defined Under Namespace
Classes: MissingSetting
Class Method Summary collapse
- .[](key) ⇒ Object
- .[]=(key, val) ⇒ Object
-
.get(key) ⇒ Object
Enables Settings.get(‘nested.key.name’) for dynamic access.
- .load! ⇒ Object
-
.name ⇒ Object
:nodoc:.
- .namespace(value = nil) ⇒ Object
- .reload! ⇒ Object
- .source(value = nil) ⇒ Object
- .suppress_errors(value = nil) ⇒ Object
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, val) ⇒ Object
-
#create_accessor_for(key, val = nil) ⇒ Object
Use instance_eval/class_eval because they’re actually more efficient than define_method{} stackoverflow.com/questions/185947/ruby-definemethod-vs-def bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/.
-
#create_accessors! ⇒ Object
This handles naming collisions with Sinatra/Vlad/Capistrano.
-
#initialize(hash_or_file = self.class.source, section = nil) ⇒ Settingslogic
constructor
Initializes a new settings object.
-
#method_missing(name, *args, &block) ⇒ Object
Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
- #missing_key(msg) ⇒ Object
Constructor Details
#initialize(hash_or_file = self.class.source, section = nil) ⇒ Settingslogic
Initializes a new settings object. You can initialize an object in any of the following ways:
Settings.new(:application) # will look for config/application.yml
Settings.new("application.yaml") # will look for application.yaml
Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
Settings.new(:config1 => 1, :config2 => 2)
Basically if you pass a symbol it will look for that file in the configs directory of your rails app, if you are using this in rails. If you pass a string it should be an absolute path to your settings file. Then you can pass a hash, and it just allows you to access the hash via methods.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/settingslogic.rb', line 105 def initialize(hash_or_file = self.class.source, section = nil) #puts "new! #{hash_or_file}" case hash_or_file when nil raise Errno::ENOENT, "No file specified as Settingslogic source" when Hash self.replace hash_or_file else hash = YAML.load(ERB.new(File.read(hash_or_file)).result).to_hash if self.class.namespace hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}") end self.replace hash end @section = section || self.class.source # so end of error says "in application.yml" create_accessors! end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used. Otherwise, create_accessors! (called by new) will have created actual methods for each key.
125 126 127 128 129 130 131 |
# File 'lib/settingslogic.rb', line 125 def method_missing(name, *args, &block) key = name.to_s return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? key value = fetch(key) create_accessor_for(key) value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value end |
Class Method Details
.[](key) ⇒ Object
47 48 49 |
# File 'lib/settingslogic.rb', line 47 def [](key) instance.fetch(key.to_s, nil) end |
.[]=(key, val) ⇒ Object
51 52 53 54 55 56 |
# File 'lib/settingslogic.rb', line 51 def []=(key, val) # Setting[:key][:key2] = 'value' for dynamic settings val = new(val, source) if val.is_a? Hash instance.store(key.to_s, val) instance.create_accessor_for(key, val) end |
.get(key) ⇒ Object
Enables Settings.get(‘nested.key.name’) for dynamic access
14 15 16 17 18 19 20 21 |
# File 'lib/settingslogic.rb', line 14 def get(key) parts = key.split('.') curs = self while p = parts.shift curs = curs.send(p) end curs end |
.load! ⇒ Object
58 59 60 61 |
# File 'lib/settingslogic.rb', line 58 def load! instance true end |
.name ⇒ Object
:nodoc:
9 10 11 |
# File 'lib/settingslogic.rb', line 9 def name # :nodoc: self.superclass != Hash && instance.key?("name") ? instance.name : super end |
.namespace(value = nil) ⇒ Object
31 32 33 34 35 36 37 |
# File 'lib/settingslogic.rb', line 31 def namespace(value = nil) if value.nil? @namespace else @namespace = value end end |
.reload! ⇒ Object
63 64 65 66 |
# File 'lib/settingslogic.rb', line 63 def reload! @instance = nil load! end |
.source(value = nil) ⇒ Object
23 24 25 26 27 28 29 |
# File 'lib/settingslogic.rb', line 23 def source(value = nil) if value.nil? @source else @source = value end end |
.suppress_errors(value = nil) ⇒ Object
39 40 41 42 43 44 45 |
# File 'lib/settingslogic.rb', line 39 def suppress_errors(value = nil) if value.nil? @suppress_errors else @suppress_errors = value end end |
Instance Method Details
#[](key) ⇒ Object
133 134 135 |
# File 'lib/settingslogic.rb', line 133 def [](key) fetch(key.to_s, nil) end |
#[]=(key, val) ⇒ Object
137 138 139 140 141 142 |
# File 'lib/settingslogic.rb', line 137 def []=(key,val) # Setting[:key][:key2] = 'value' for dynamic settings val = self.class.new(val, @section) if val.is_a? Hash store(key.to_s, val) create_accessor_for(key, val) end |
#create_accessor_for(key, val = nil) ⇒ Object
Use instance_eval/class_eval because they’re actually more efficient than define_method{} stackoverflow.com/questions/185947/ruby-definemethod-vs-def bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/settingslogic.rb', line 157 def create_accessor_for(key, val=nil) return unless key.to_s =~ /^\w+$/ # could have "some-setting:" which blows up eval instance_variable_set("@#{key}", val) if val self.class.class_eval <<-EndEval def #{key} return @#{key} if @#{key} return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? '#{key}' value = fetch('#{key}') @#{key} = value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value end EndEval end |
#create_accessors! ⇒ Object
This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set() helper that defines methods in Object, ANY method_missing ANYWHERE picks up the Vlad/Sinatra settings! So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, “host”), rather than the app_yml hash. Jeezus.
148 149 150 151 152 |
# File 'lib/settingslogic.rb', line 148 def create_accessors! self.each do |key,val| create_accessor_for(key) end end |
#missing_key(msg) ⇒ Object
170 171 172 173 174 |
# File 'lib/settingslogic.rb', line 170 def missing_key(msg) return nil if self.class.suppress_errors raise MissingSetting, msg end |