Class: Settings::Cursor
- Inherits:
-
DslBuilder
- Object
- DslBuilder
- Settings::Cursor
- Defined in:
- lib/iron/settings/cursor.rb
Overview
Cursors handle navigating the settings hierarchy built by our Builder class, allowing getting and setting entry values and inspecting the hierarchy itself.
Instance Method Summary collapse
-
#[](key, &block) ⇒ Object
Array-like access to the entry value at the specified key.
-
#[]=(key, val) ⇒ Object
Array-like setter for entry values using the specified key.
-
#entry_keys(include_all = true) ⇒ Object
Returns all entry keys at the cursor’s current position, and optionally including all child keys.
-
#entry_values(include_all = true) ⇒ Object
Returns a hash of all entry keys to their values at the cursor’s current position, and optionally including all child keys.
-
#eval_in_context(text) ⇒ Object
:nodoc:.
-
#find_entries(include_all = true) ⇒ Object
Return Settings::Entry items for entries at this cursor level and optionally below it.
-
#find_item(key) ⇒ Object
Finds the item (group or entry) in the hierarchy matching the provided relative key.
-
#group_keys(include_all = false) ⇒ Object
Returns all group keys.
-
#initialize(group, values, context = nil) ⇒ Cursor
constructor
Start up our cursor bound to a given group in the settings hierarchy, with the value store holding the values for the current context.
-
#item_default_value(item) ⇒ Object
Calculates the default value for an entry, handling callable defaults.
-
#item_has_value?(item) ⇒ Boolean
When true, has non-default value set for the given entry.
-
#item_value(item) ⇒ Object
Calculates the value of the given entry item given the current value store and item default value.
-
#method_missing(method, *args, &block) ⇒ Object
Look for the next item from our current group pointer, returning a new cursor if the item is a sub-group, or the value of the requested entry if the item is a leaf in the hierarchy tree.
-
#respond_to_missing?(method, include_private = false) ⇒ Boolean
Counterpart to #method_missing.
-
#root ⇒ Object
Provides access to the root of the hierarchy, generally not useful during operations…
Constructor Details
#initialize(group, values, context = nil) ⇒ Cursor
Start up our cursor bound to a given group in the settings hierarchy, with the value store holding the values for the current context.
9 10 11 12 13 |
# File 'lib/iron/settings/cursor.rb', line 9 def initialize(group, values, context = nil) @group = group @values = values @context = context end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Look for the next item from our current group pointer, returning a new cursor if the item is a sub-group, or the value of the requested entry if the item is a leaf in the hierarchy tree.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/iron/settings/cursor.rb', line 94 def method_missing(method, *args, &block) method = method.to_s query = method.ends_with?('?') assignment = method.ends_with?('=') method.gsub!(/[=\?]+/,'') # Look up the item item = @group.find_item(method) if item.nil? # Unknown item name, whoops. if query # Querying for existence of key is fine if it's missing return false else # Setting or getting, GTFO raise RuntimeError.new("Unknown settings group or entry '#{method}' for settings path #{@group.key}") end elsif item.group? if query # Yes, this group exists return true else # Got asked for another group, so create a new cursor and do the right thing(tm) cursor = Settings::Cursor.new(item, @values) DslProxy::exec(cursor, &block) if block return cursor end elsif item.entry? if query # Return true if the given item has a non-nil value return !item_value(item).nil? else if args.empty? # No args means return the current value (or default if none) return item_value(item) else # With args, we set the current value of the item (if it parses correctly) val = Settings.parse(args.first, item.type) @values.set_value(item.key, val) return args.first end end end end |
Instance Method Details
#[](key, &block) ⇒ Object
Array-like access to the entry value at the specified key
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/iron/settings/cursor.rb', line 69 def [](key, &block) item = find_item(key) if item.group? # Got asked for another group, so create a new cursor and do the right thing(tm) cursor = Settings::Cursor.new(item, @values) DslProxy::exec(cursor, &block) if block cursor else item_value(item) end end |
#[]=(key, val) ⇒ Object
Array-like setter for entry values using the specified key
82 83 84 85 86 87 88 |
# File 'lib/iron/settings/cursor.rb', line 82 def []=(key, val) item = find_item(key) if item @values.set_value(item.key, Settings.parse(val, item.type)) end val end |
#entry_keys(include_all = true) ⇒ Object
Returns all entry keys at the cursor’s current position, and optionally including all child keys. If the cursor is at a sub-group node, keys will be relative to that node.
24 25 26 27 28 29 30 |
# File 'lib/iron/settings/cursor.rb', line 24 def entry_keys(include_all = true) keys = @group.entries(include_all).collect {|e| e.key } unless @group.key.blank? keys.collect! {|k| k.gsub(@group.key + '.', '') } end keys end |
#entry_values(include_all = true) ⇒ Object
Returns a hash of all entry keys to their values at the cursor’s current position, and optionally including all child keys. If the cursor is at a sub-group node, keys will be relative to that node.
35 36 37 38 |
# File 'lib/iron/settings/cursor.rb', line 35 def entry_values(include_all = true) keys = entry_keys(include_all) keys.convert_to_hash {|k| item_value(find_item(k)) } end |
#eval_in_context(text) ⇒ Object
:nodoc:
176 177 178 179 180 |
# File 'lib/iron/settings/cursor.rb', line 176 def eval_in_context(text) # :nodoc: proc = Proc.new {} binding = proc.binding eval(text, binding) end |
#find_entries(include_all = true) ⇒ Object
Return Settings::Entry items for entries at this cursor level and optionally below it
64 65 66 |
# File 'lib/iron/settings/cursor.rb', line 64 def find_entries(include_all = true) @group.entries(include_all) end |
#find_item(key) ⇒ Object
Finds the item (group or entry) in the hierarchy matching the provided relative key. Raises a RuntimeError on unknown keys.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/iron/settings/cursor.rb', line 51 def find_item(key) item = @group key = key.to_s parts = key.split(/\./) until parts.empty? item_key = parts.shift item = item.find_item(item_key) raise RuntimeError.new("Unknown settings group or entry '#{item_key}' in settings path #{[@group.key,key].list_join('.')}") if item.nil? end item end |
#group_keys(include_all = false) ⇒ Object
Returns all group keys
41 42 43 44 45 46 47 |
# File 'lib/iron/settings/cursor.rb', line 41 def group_keys(include_all = false) keys = @group.entries(include_all).collect {|e| e.key } unless @group.key.blank? keys.collect! {|k| k.gsub(@group.key + '.', '') } end keys end |
#item_default_value(item) ⇒ Object
Calculates the default value for an entry, handling callable defaults.
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/iron/settings/cursor.rb', line 163 def item_default_value(item) return nil if item.group? || item.default.nil? if item.default.respond_to?(:call) # Callable default, call in context of a root cursor, yielding our context (generally a # model instance) to the block. val = DslProxy.exec(Cursor.new(root, @values), @context, &(item.default)) val = Settings.parse(val, item.type) else val = item.default end Settings.restore(val, item.type) end |
#item_has_value?(item) ⇒ Boolean
When true, has non-default value set for the given entry
149 150 151 152 |
# File 'lib/iron/settings/cursor.rb', line 149 def item_has_value?(item) return false if item.group? @values.has_value?(item.key) end |
#item_value(item) ⇒ Object
Calculates the value of the given entry item given the current value store and item default value.
156 157 158 159 160 |
# File 'lib/iron/settings/cursor.rb', line 156 def item_value(item) return item_default_value(item) unless item_has_value?(item) val = @values.get_value(item.key) Settings.restore(val, item.type) end |
#respond_to_missing?(method, include_private = false) ⇒ Boolean
Counterpart to #method_missing
142 143 144 145 146 |
# File 'lib/iron/settings/cursor.rb', line 142 def respond_to_missing?(method, include_private = false) method = method.to_s.gsub(/[=\?]+/,'') item = @group.find_item(method) return !item.nil? end |