Class: MmTool::MmUserDefaults

Inherits:
Object
  • Object
show all
Defined in:
lib/mm_tool/mm_user_defaults.rb

Overview

Handles application user defaults as a singleton. This is specific to MmTool, and is not meant to be a general purpose User Defaults system.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMmUserDefaults


Initialize




104
105
106
# File 'lib/mm_tool/mm_user_defaults.rb', line 104

def initialize
  @defaults = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object


Get and set defaults via methods.




207
208
209
210
211
212
213
214
215
# File 'lib/mm_tool/mm_user_defaults.rb', line 207

def method_missing(method, *args)
  if defines_default?(method) && args.empty?
    self[method]
  elsif method.to_s =~ /^(\w+)=$/ && args.size == 1
    self[Regexp.last_match(1).to_sym] = args[0]
  else
    super
  end
end

Class Method Details

.shared_user_defaultsObject


Singleton accessor.




94
95
96
97
98
99
# File 'lib/mm_tool/mm_user_defaults.rb', line 94

def self.shared_user_defaults
  unless @self
    @self = self.new
  end
  @self
end

Instance Method Details

#[](key) ⇒ Object


Return the value of a setting by key or nil.




188
189
190
191
# File 'lib/mm_tool/mm_user_defaults.rb', line 188

def [](key)
  result = default(key)
  result ? result.value : nil
end

#[]=(key, value) ⇒ Object


Set the value of a setting by key.




196
197
198
199
200
201
202
# File 'lib/mm_tool/mm_user_defaults.rb', line 196

def []=(key, value)
  if default(key)
    default(key).value = value
  else
    define_default(for_key:key, value:value)
  end
end

#all_defaultsObject


Returns all default instances as an array.




163
164
165
# File 'lib/mm_tool/mm_user_defaults.rb', line 163

def all_defaults
  @defaults.values.sort_by(&:name)
end

#argument_groupsObject


Utility: Return an array of argument groups. They will

be in the order that they were added to user defaults.



270
271
272
273
274
# File 'lib/mm_tool/mm_user_defaults.rb', line 270

def argument_groups
  @defaults.values
      .collect {|default| default.help_group}
      .uniq
end

#arguments_help_by_groupObject


Utility: get all of the argument help text by group, into

a simple hash with group names as keys.



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/mm_tool/mm_user_defaults.rb', line 235

def arguments_help_by_group

  table = {}

  argument_groups.each do |group|

    #noinspection RubyResolve
    key = "\n#{C.bold(group)}\n\n"
    table[key] = []

    @defaults.values.select { |default| default.help_group == group }
        .each do |default|
      width = example_args_by_length[-1].length
      arg = " %-#{width}.#{width}s   " % default.example_arg
      des = default.help_desc % default.value
      table[key] << arg + des
    end
  end
  table
end

#default(key) ⇒ Object


Get a single default instance.




181
182
183
# File 'lib/mm_tool/mm_user_defaults.rb', line 181

def default(key)
  @defaults[key]
end

#define_default(for_key:, value:) ⇒ Object


Creates a new user default object and add it to the collection.




120
121
122
# File 'lib/mm_tool/mm_user_defaults.rb', line 120

def define_default(for_key:, value:)
  @defaults[for_key] = MmUserDefault.new(key:for_key,value:value)
end

#defines_default?(key) ⇒ Boolean


Does the default exist?


Returns:

  • (Boolean)


227
228
229
# File 'lib/mm_tool/mm_user_defaults.rb', line 227

def defines_default?(key)
  @defaults.key?(key)
end

#example_args_by_lengthObject


Utility: get an array of argument examples, sorted by

length.



260
261
262
263
264
# File 'lib/mm_tool/mm_user_defaults.rb', line 260

def example_args_by_length
  @defaults.values
      .sort {|a,b| a.example_arg.length <=> b.example_arg.length}
      .collect {|d| d.example_arg}
end

#file_pathObject


The location on the filesystem where the file exists.




111
112
113
# File 'lib/mm_tool/mm_user_defaults.rb', line 111

def file_path
  PATH_USER_DEFAULTS
end

#hash_representationObject


Returns all default instances as a hash, with key and value only. If there’s no item label, assume that the default is a command and not an actual setting, and skip it.




173
174
175
176
# File 'lib/mm_tool/mm_user_defaults.rb', line 173

def hash_representation
  all_defaults.select {|d| d.item_label}
      .collect { |d| [d.name, d.value] }.to_h
end

#label_value_pairs {|result| ... } ⇒ Object


Returns an array of labels and the current matching value. Accepts a block to add your own pairs.


Yields:

  • (result)


280
281
282
283
284
285
# File 'lib/mm_tool/mm_user_defaults.rb', line 280

def label_value_pairs
  result = @defaults.values.select {|default| default.item_label}
                    .map {|default| ["#{default.item_label}:", default.value_printable]}
  yield result if block_given?
  result
end

#register_defaults(with_hash:) ⇒ Object


Sets up initial defaults from a large hash indicating all of the user defaults and attributes for the default. Also sets up the persistence system. If the file doesn’t exist, it will be created with the current key-value pairs. If it does exist, existing key-value pairs will be reconciled with current key-value pairs. Finally, values from the file will be applied.




133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/mm_tool/mm_user_defaults.rb', line 133

def register_defaults(with_hash:)

  # *Define* each of the possible defaults. These will have
  # default values. We're actually kind of good to go at
  # this point if we don't want to use the rc file.

  with_hash.each {|k,v| define_default(for_key:k, value:v) }

  # If the file doesn't exist, create it and add our current
  # key-value pairs to it. Otherwise, read the file, compare
  # it to our current set of key-value pairs, and make
  # adjustments, re-writing the file if necessary.

  if !File.file?(file_path)
    FileUtils.mkdir_p(File.dirname(file_path))
    File.open(file_path, 'w') { |file| file.write(hash_representation.to_yaml) }
  else
    #noinspection RubyResolve
    #@type [Hash] working
    working = YAML.load(File.read(file_path))
    new = working.select {|k,_| hash_representation.has_key?(k)} # only keeps working items if they are current.
    new = new.merge(hash_representation.select {|k,_| !new.has_key?(k)}) # select the new items.
    File.open(file_path, 'w') { |file| file.write(new.to_yaml) } unless working == new
    new.each {|k,v| self[k] = v }
  end
end

#respond_to?(method, include_private = false) ⇒ Boolean


Ensure that we account for our dynamic methods.


Returns:

  • (Boolean)


220
221
222
# File 'lib/mm_tool/mm_user_defaults.rb', line 220

def respond_to?(method, include_private = false)
  super || defines_default?(method) || (method =~ /^(\w+)=$/ && defines_default?(Regexp.last_match(1)))
end