Class: Construct
- Inherits:
-
Object
- Object
- Construct
- Defined in:
- lib/construct.rb
Constant Summary collapse
- APP_NAME =
Construct is extensible, persistent, structured configuration for Ruby and humans with text editors.
'Construct'
- APP_VERSION =
'0.1.3'
- APP_AUTHOR =
'Kyle Kingsbury'
- APP_EMAIL =
'[email protected]'
- APP_URL =
'http://aphyr.com'
- APP_COPYRIGHT =
'Copyright (c) 2009 Kyle Kingsbury <[email protected]>. All rights reserved.'
Class Attribute Summary collapse
-
.schema ⇒ Object
Returns the class schema.
Instance Attribute Summary collapse
-
#data ⇒ Object
Returns the value of attribute data.
-
#schema ⇒ Object
Returns the value of attribute schema.
Class Method Summary collapse
-
.define(key, schema) ⇒ Object
Define a schema for a key on the class.
-
.load(yaml) ⇒ Object
Load a construct from a YAML string.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #[](key) ⇒ Object
-
#[]=(key, value) ⇒ Object
Assign a value to a key.
-
#clear ⇒ Object
Clears the data in the construct.
-
#define(key, options = {}) ⇒ Object
Defines a new field in the schema.
-
#delete(key) ⇒ Object
delete simply removes the value from the data hash, but leaves the schema unchanged.
-
#include?(*args) ⇒ Boolean
Returns true if the construct has a value set for, or the schema defines, the key.
-
#initialize(data = {}, schema = {}) ⇒ Construct
constructor
A new instance of Construct.
-
#keys ⇒ Object
Returns the keys, both set in the construct and specified in the schema.
- #load(str) ⇒ Object
- #method_missing(meth, *args) ⇒ Object
-
#to_yaml(opts = {}) ⇒ Object
Dumps the data (not the schema!) of this construct to YAML.
Constructor Details
#initialize(data = {}, schema = {}) ⇒ Construct
Returns a new instance of Construct.
38 39 40 41 42 43 44 |
# File 'lib/construct.rb', line 38 def initialize(data = {}, schema = {}) @data = Hash.new data.each do |key, value| self[key] = value end @schema = self.class.schema.merge(schema) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/construct.rb', line 118 def method_missing(meth, *args) meth_s = meth.to_s if meth_s[-1..-1] == '=' # Assignment if args.size != 1 raise ArgumentError.new("#{meth} takes exactly one argument") end self[meth_s[0..-2]] = args[0] elsif include? meth self[meth] else raise NoMethodError.new("no such key #{meth} in construct") end end |
Class Attribute Details
.schema ⇒ Object
Returns the class schema
32 33 34 |
# File 'lib/construct.rb', line 32 def self.schema @schema ||= {} end |
Instance Attribute Details
#data ⇒ Object
Returns the value of attribute data.
36 37 38 |
# File 'lib/construct.rb', line 36 def data @data end |
#schema ⇒ Object
Returns the value of attribute schema.
36 37 38 |
# File 'lib/construct.rb', line 36 def schema @schema end |
Class Method Details
.define(key, schema) ⇒ Object
Define a schema for a key on the class. The class schema is used as the defaults on initialization of a new instance.
20 21 22 23 |
# File 'lib/construct.rb', line 20 def self.define(key, schema) key = key.to_sym if String === key @schema[key] = schema end |
.load(yaml) ⇒ Object
Load a construct from a YAML string
26 27 28 29 |
# File 'lib/construct.rb', line 26 def self.load(yaml) hash = YAML::load(yaml) new(hash) end |
Instance Method Details
#==(other) ⇒ Object
46 47 48 49 |
# File 'lib/construct.rb', line 46 def ==(other) other.respond_to? :schema and other.respond_to? :data and @schema == other.schema and @data == other.data end |
#[](key) ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/construct.rb', line 51 def [](key) key = key.to_sym if String === key if @data.include? key @data[key] elsif @schema.include? key and @schema[key].include? :default @schema[key][:default] end end |
#[]=(key, value) ⇒ Object
Assign a value to a key. Constructs accept only symbols as values, and will convert strings to symbols when necessary. They will also implicitly convert Hashes as values into Constructs when possible. Hence you can do:
construct.people = => ‘Awesome’, :joe => ‘suspicious’ construct.people.mary # => ‘Awesome’
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/construct.rb', line 68 def []=(key, value) key = key.to_sym if String === key raise ArgumentError.new('construct only accepts symbols (and strings) as keys.') unless key.is_a? Symbol # Convert suitable hashes into Constructs if value.is_a? Hash if value.keys.all? { |k| k.is_a? String or k.is_a? Symbol } value = Construct.new(value) end end @data[key] = value end |
#clear ⇒ Object
Clears the data in the construct.
85 86 87 |
# File 'lib/construct.rb', line 85 def clear @data.clear end |
#define(key, options = {}) ⇒ Object
Defines a new field in the schema. Fields are :default and :desc.
90 91 92 93 |
# File 'lib/construct.rb', line 90 def define(key, = {}) key = key.to_sym if String === key @schema[key] = end |
#delete(key) ⇒ Object
delete simply removes the value from the data hash, but leaves the schema unchanged. Hence the construct may still respond to include? if the schema defines that field. Use #schema.delete(:key) to remove the key entirely.
99 100 101 102 |
# File 'lib/construct.rb', line 99 def delete(key) key = key.to_sym if String === key @data.delete key end |
#include?(*args) ⇒ Boolean
Returns true if the construct has a value set for, or the schema defines, the key.
106 107 108 |
# File 'lib/construct.rb', line 106 def include?(*args) @data.include?(*args) or (@schema.include?(*args) and @schema[*args].include? :default) end |
#keys ⇒ Object
Returns the keys, both set in the construct and specified in the schema.
111 112 113 |
# File 'lib/construct.rb', line 111 def keys @data.keys | @schema.keys end |
#load(str) ⇒ Object
115 116 |
# File 'lib/construct.rb', line 115 def load(str) end |
#to_yaml(opts = {}) ⇒ Object
Dumps the data (not the schema!) of this construct to YAML. Keys are expressed as strings.
This gets a little complicated.
If you define a schema where the default is a Construct
conf.define :sub, :default => Construct
and then try to write to it:
conf.sub.opt = 2
That opt gets stored on the schema sub. Everything works fine… except that when it comes time to serialize there’s now data buried in the schema tree. Therefore, we write out schema objects as well when they are non-empty.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/construct.rb', line 151 def to_yaml(opts = {}) hash = {} @schema.each do |key, value| if value[:default].kind_of? Construct hashed = YAML::load(value[:default].to_yaml) next if hashed.empty? hash[key.to_s] = hashed end end @data.each do |key, value| hash[key.to_s] = value end hash.to_yaml(opts) end |