Class: Settings

Inherits:
Object
  • Object
show all
Defined in:
lib/iron/settings.rb,
lib/iron/settings/node.rb,
lib/iron/settings/root.rb,
lib/iron/settings/entry.rb,
lib/iron/settings/group.rb,
lib/iron/settings/cursor.rb,
lib/iron/settings/builder.rb,
lib/iron/settings/db_store.rb,
lib/iron/settings/class_level.rb,
lib/iron/settings/value_store.rb,
lib/iron/settings/static_store.rb,
lib/iron/settings/instance_level.rb

Overview

:nodoc:

Defined Under Namespace

Modules: ClassLevel, InstanceLevel Classes: Builder, Cursor, DBStore, DBValue, Entry, Group, Node, Root, StaticStore, ValueStore

Class Method Summary collapse

Class Method Details

.classesObject



123
124
125
126
# File 'lib/iron/settings.rb', line 123

def self.classes
  @classes ||= []
  @classes
end

.converter_for(type, mode) ⇒ Object

Returns the proper parser for a given type and mode (either :parse or :restore)

Raises:

  • (ArgumentError)


73
74
75
76
77
78
79
80
81
# File 'lib/iron/settings.rb', line 73

def self.converter_for(type, mode)
  if type.to_s.ends_with?('_list')
    type = type.to_s.gsub('_list','').to_sym
  end

  hash = data_type_map[type]
  raise ArgumentError.new("Unknown settings data type [#{type.inspect}]") if hash.nil?
  hash[mode]
end

.data_type_mapObject



60
61
62
63
# File 'lib/iron/settings.rb', line 60

def self.data_type_map
  @data_type_map ||= {}
  @data_type_map
end

.data_typesObject

Returns array of symbols for the supported data types for settings entries. You can add custom types using the #register_type method



68
69
70
# File 'lib/iron/settings.rb', line 68

def self.data_types
  data_type_map.keys
end

.default_timestamp_file(class_name) ⇒ Object



128
129
130
131
132
133
# File 'lib/iron/settings.rb', line 128

def self.default_timestamp_file(class_name)
  filename = class_name.gsub(/([a-z])([A-Z])/, '\1-\2').to_dashcase + '-settings.txt'
  defined?(Rails) ?
    File.join(RAILS_ROOT, 'tmp', filename) :
    File.join(Dir.tmpdir, filename)
end

.parse(val, type) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/iron/settings.rb', line 83

def self.parse(val, type)
  # Nil is always ok
  return nil if val.nil?
  
  # Check for lists
  parser = converter_for(type, :parse)
  if type.to_s.ends_with?('_list')
    # Gotta be an array, thanks
    raise ArgumentError.new("Must set #{type} settings to an array of values") unless val.is_a?(Array)

    # Parse 'em all
    return val if parser.nil?
    val.collect {|v| parser.call(v) } rescue raise ArgumentError.new("Values #{val.inspect} is not a valid #{type}")
  else
    # Single value
    return val if parser.nil?
    parser.call(val) rescue raise ArgumentError.new("Value [#{val.inspect}] is not a valid #{type}")
  end
end

.register_built_insObject

Registers initial set of built-in data types



52
53
54
55
56
57
58
# File 'lib/iron/settings.rb', line 52

def self.register_built_ins
  register_type(:int, parse: lambda {|val| val.is_a?(Fixnum) || (val.is_a?(String) && val.integer?) ? val.to_i : raise })
  register_type(:string, parse: lambda {|val| val.is_a?(String) ? val : raise })
  register_type(:symbol, parse: lambda {|val| val.is_a?(Symbol) ? val : raise })
  register_type(:bool, parse: lambda {|val| (val === true || val === false) ? val : raise })
  register_type(:var)
end

.register_type(type, options = {}) ⇒ Object

Registers a new data type for use in settings entries. Pass a symbol for the type, and a lambda that accepts an arbitrary value and either parses it into a value of the required type or raises.

For example, let’s say we had a project that commonly had to assign admin users (represented here by ActiveRecord models) on projects, tasks, etc. We could create a :user data type that would seamlessly allow setting and getting admin users as a native settings type:

Settings.register_type :user, 
  :parse => lambda {|val| val.is_a?(AdminUser) ? val.id : raise },
  :restore => lambda {|val| AdminUser.find_by_id(val) }

Now we can use the user type in our settings definitions:

class Project < ActiveRecord::Base
  instance_settings do
    user('lead')
  end
end

With our settings defined, we can get and set admin users to that setting entry:

@project = Project.new(:name => 'Lazarus')
@project.settings.lead = AdminUser.find_by_email('[email protected]')
@project.save

@project = Project.find_by_name('Lazarus')
# Will use our :restore lambda to restore the id as a full AdminUser model
@lead = @project.settings.lead
# Will print '[email protected]'
puts @lead.email

If you do not define either the parse or restore lambdas, they will act as pass-throughs. Also note that you do not need to handle nil values, which will always parse to nil and restore to nil.



47
48
49
# File 'lib/iron/settings.rb', line 47

def self.register_type(type, options = {})
  data_type_map[type] = {parse: options[:parse], restore: options[:restore]}
end

.restore(val, type) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/iron/settings.rb', line 103

def self.restore(val, type)
  # Nil restores to nil... always
  return nil if val.nil?
  
  # Check for lists
  restorer = converter_for(type, :restore)
  if type.to_s.ends_with?('_list')
    # Gotta be an array, thanks
    raise ArgumentError.new("Must set #{type} settings to an array of values") unless val.is_a?(Array)

    # Parse 'em all
    return val if restorer.nil?
    val.collect {|v| parser.call(v) } rescue raise ArgumentError.new("Unable to restore values #{val.inspect} to type #{type}")
  else
    # Single value
    return val if restorer.nil?
    restorer.call(val) rescue raise ArgumentError.new("Unable to restore value [#{val.inspect}] to type #{type}")
  end
end