class Settings::Cursor

Cursors handle navigating the settings hierarchy built by our Builder class, allowing getting and setting entry values and inspecting the hierarchy itself.

Public Class Methods

new(group, values, context = nil) click to toggle source

Start up our cursor bound to a given group in the settings hierarchy, with the value store holding the values for the current context.

# File lib/iron/settings/cursor.rb, line 9
def initialize(group, values, context = nil)
  @group = group
  @values = values
  @context = context
end

Public Instance Methods

[](key, &block) click to toggle source

Array-like access to the entry value at the specified key

# 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) click to toggle source

Array-like setter for entry values using the specified key

# 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) click to toggle source

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.

# 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) click to toggle source

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.

# 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
find_entries(include_all = true) click to toggle source

Return Settings::Entry items for entries at this cursor level and optionally below it

# File lib/iron/settings/cursor.rb, line 64
def find_entries(include_all = true)
  @group.entries(include_all)
end
find_item(key) click to toggle source

Finds the item (group or entry) in the hierarchy matching the provided relative key. Raises a RuntimeError on unknown keys.

# 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) click to toggle source

Returns all group keys

# 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) click to toggle source

Calculates the default value for an entry, handling callable defaults.

# 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) click to toggle source

When true, has non-default value set for the given entry

# 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) click to toggle source

Calculates the value of the given entry item given the current value store and item default value.

# 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
method_missing(method, *args, &block) click to toggle source

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.

# 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
respond_to_missing?(method, include_private = false) click to toggle source

Counterpart to method_missing

# 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
root() click to toggle source

Provides access to the root of the hierarchy, generally not useful during operations… :-)

# File lib/iron/settings/cursor.rb, line 17
def root
  @group.root
end