cushion_defaults 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6be31769619d31078b95f3ce90c4dbe1e23948d0
4
- data.tar.gz: 0f883a5d3b1721e29abc6588ee4fc5be86d9a7a2
3
+ metadata.gz: 5ee8cdd20d451d7e48d28f67f87161138e5b4c87
4
+ data.tar.gz: beccbd9d7f439691d120f23e74512be56d480b96
5
5
  SHA512:
6
- metadata.gz: f71ace7a7cd19e962f49333ad57192acf18fa82752e93bab345ce5f89321091e4df00cb8c7778d4da650b19632e238d57a2bd38364fe5acf299fbbee043ca92d
7
- data.tar.gz: f65b07dfb5c5d58e8220c16c0d47fa1968b19269d9fdcf923d94ccc7f0d988afae8fe426452c2dd6132d4e7d8e3fe4516c8179f215a1b2bb2545682f8443b4f1
6
+ metadata.gz: 240abcc508735adc2eec294ccb1851609b2925e6f90d280b9108d6860c50cf50d064a37cc7df5dea5f269e690e7ec84dea9cee7d8c5117c566958139c624053a
7
+ data.tar.gz: 0f12017c5d6b9aa2076fff84c69cb343bc3466102f275e13f5077c70df6236d74f132c36c6bc80eb2437de91dd3f60bdc49ecd3c0e3d0da0da6cf4b9e2bddba6
@@ -7,10 +7,9 @@ module CushionDefaults
7
7
 
8
8
  # Either set up or wipe @defaults. Should not usually be called directly.
9
9
  def initialize_defaults_hash
10
-
11
10
  if @defaults
12
11
  # We need to maintain the identity of the hash, as child classes may have stored a reference to it
13
- @defaults.delete_if { true }
12
+ @defaults.clear
14
13
  else
15
14
  @defaults = DefaultsHash.new(self)
16
15
  end
@@ -25,7 +24,9 @@ module CushionDefaults
25
24
  def defaults=(replacement_hash)
26
25
  # Need to copy over keys/vals to ensure @defaults remains a DefaultsHash and retains identity
27
26
 
27
+ CushionDefaults.log("Old defaults deleted for #{self}:#{@defaults.reduce(''){|s,(k,v)| s+"\n\t\t#{k}: #{v}"}}", :info) unless @defaults.empty?
28
28
  @defaults.replace(replacement_hash)
29
+ CushionDefaults.log("New defaults added for #{self}:#{@defaults.reduce(''){|s,(k,v)| s+"\n\t\t#{k}: #{v}"}}", :info)
29
30
  @defaults.keys.each do |key|
30
31
  unless key.is_a? Symbol
31
32
  @defaults[key.to_sym] = @defaults[key].delete!
@@ -54,15 +55,18 @@ module CushionDefaults
54
55
 
55
56
  yaml = YAML::load(File.open(yaml_path)) rescue {}
56
57
 
57
- if yaml.empty? && CushionDefaults::configuration.whiny_yaml
58
- warn "No YAML configuration for class #{self} found at #{yaml_path}"
58
+ if yaml.empty?
59
+ CushionDefaults.log("No YAML configuration for class #{self} found at #{yaml_path}", CushionDefaults.conf.whiny_yaml ? :warn : :debug)
59
60
  end
60
61
 
61
62
  initialize_defaults_hash
63
+ log_str = "New defaults added for #{self}:"
62
64
  # If automatic readers and writers are enabled, this will set them up as a consequence.
63
65
  yaml.each do |key, val|
66
+ log_str << "\n\t\t#{key}: #{val}"
64
67
  @defaults[key.to_sym] = val
65
68
  end
69
+ CushionDefaults.log(log_str, :info)
66
70
  end
67
71
 
68
72
  # Sets up a conditional getter method for each :sym in +syms+.
@@ -77,16 +81,17 @@ module CushionDefaults
77
81
  sym = sym.to_sym
78
82
  sym_str = sym.to_s
79
83
  if self_or_parent_instance_method?(sym)
80
- warn "#{self} or a parent class already has what looks like a getter method for #{sym_str}"
84
+ CushionDefaults.log("#{self} or a parent class already has what looks like a getter method for #{sym_str}", :warn)
81
85
  end
82
86
  instance_variable_string = "@#{sym_str}"
83
87
  define_method(sym) do
84
- if defaults.not_pushy?(sym) && instance_variable_defined?(instance_variable_string)
88
+ if instance_variable_defined?(instance_variable_string) && (CushionDefaults.conf.no_pushies? || defaults.not_pushy?(sym))
85
89
  instance_variable_get(instance_variable_string)
86
90
  else
87
91
  defaults[sym]
88
92
  end
89
93
  end
94
+ CushionDefaults.log("cushion_reader #{sym} established for #{self}")
90
95
  end
91
96
  end
92
97
 
@@ -94,7 +99,7 @@ module CushionDefaults
94
99
  syms.each do |sym|
95
100
  method_name = "#{sym}="
96
101
  if self_or_parent_instance_method?(method_name)
97
- warn "#{self} or a parent class already has what looks like a setter method for #{sym}"
102
+ CushionDefaults.log("#{self} or a parent class already has what looks like a setter method for #{sym}", :warn)
98
103
  end
99
104
 
100
105
  instance_variable_string = "@#{sym}"
@@ -102,26 +107,33 @@ module CushionDefaults
102
107
  define_method(method_name) do |y|
103
108
  if CushionDefaults.nilish? y
104
109
  if CushionDefaults.conf.whiny_ignores
105
- warn "You are attempting to set a nilish value for #{sym}. This will not be recorded, and any value set will be deleted."
110
+ CushionDefaults.log("You are attempting to set a nilish value for #{sym}. This will not be recorded, and any value set will be deleted.", :warn)
106
111
  end
107
112
  remove_instance_variable(instance_variable_string) if instance_variable_defined?(instance_variable_string)
108
113
  else
109
- if defaults.pushy?(sym)
110
- warn "You are setting a value for #{sym}, but this is a pushy default and this value will not be returned by any cushion_readers."
114
+ if CushionDefaults.conf.we_have_a_pushy? && defaults.pushy?(sym)
115
+ CushionDefaults.log("You are setting a value for #{sym}, but this is a pushy default and this value will not be returned by any cushion_readers.", :warn)
111
116
  end
112
117
  instance_variable_set(instance_variable_string, y)
113
118
  end
114
119
  end
120
+ CushionDefaults.log("cushion_writer #{sym}= established for #{self}")
115
121
  end
116
122
  end
117
123
 
118
124
  def remove_reader(sym)
119
- undef_method(sym) if self_has_method?(sym)
125
+ if self_has_method?(sym)
126
+ undef_method(sym)
127
+ CushionDefaults.log("cushion_reader #{sym} removed from #{self}", :info)
128
+ end
120
129
  end
121
130
 
122
131
  def remove_writer(sym)
123
132
  write_sym = "#{sym}=".to_sym
124
- undef_method(write_sym) if self_has_method?(write_sym)
133
+ if self_has_method?(write_sym)
134
+ undef_method(write_sym)
135
+ CushionDefaults.log("cushion_writer #{sym}= removed from #{self}", :info)
136
+ end
125
137
  end
126
138
 
127
139
  # Sets up both +conditional_getters+ and normal +attr_writer+ for +syms+.
@@ -156,6 +168,7 @@ module CushionDefaults
156
168
  # - #cushion_readers_for_defaults
157
169
  def cushion_defaults
158
170
  cushion *defaults.keys
171
+ CushionDefaults.log("cushions established for #{self}'s defaults': #{defaults.keys.join(', ')}", :info)
159
172
  end
160
173
 
161
174
  def make_pushy(*syms)
@@ -1,12 +1,20 @@
1
+ require 'logger'
2
+
1
3
  # Effectively a singleton class, +Configuration+ keeps track of various configuration options for +CushionDefaults+.
4
+ #
5
+ # In addition, it also keeps track of certain state data for +CushionDefaults+.
2
6
  class Configuration # :nodoc:
3
7
  # adapted from http://brandonhilkert.com/blog/ruby-gem-configuration-patterns/
4
8
 
5
- attr_accessor :update_readers, :update_writers, :auto_load_from_yaml, :yaml_source_folder, :yaml_source_full_path, :whiny_yaml, :whiny_ignores, :cushion_child_defaults_in_parent, :ignore_attempts_to_set_nil, :blank_str_is_nil
9
+ attr_accessor :update_readers, :update_writers, :auto_load_from_yaml, :yaml_source_folder, :yaml_source_full_path
10
+ attr_accessor :record_in_log, :whiny_yaml, :whiny_ignores, :cushion_child_defaults_in_parent, :ignore_attempts_to_set_nil
11
+ attr_accessor :blank_str_is_nil
12
+ attr_reader :logger
6
13
 
7
14
  # Initializes with +#defaults+
8
15
  def initialize
9
16
  defaults!
17
+ @we_have_a_pushy = false
10
18
  end
11
19
 
12
20
  # Returns or computes the folder where class-specific yaml files are expected to reside.
@@ -18,9 +26,15 @@ class Configuration # :nodoc:
18
26
  #
19
27
  # +loaded_config+ :: hash from which options will be derived
20
28
  def from_hash(loaded_config)
29
+ log_str = 'Loading configuration options from hash...'
21
30
  loaded_config.each do |key, val|
22
- instance_variable_set("@#{key.to_sym}", val) if instance_variable_defined? "@#{key.to_sym}"
31
+ log_str << "\n\t\t#{key}: #{val}"
32
+ # We need to be able to use some of the checks and responses in the custom setter methods
33
+ writer_sym = "#{key}=".to_sym
34
+ send writer_sym, val if respond_to? writer_sym
35
+ #instance_variable_set("@#{key.to_sym}", val) if instance_variable_defined? "@#{key.to_sym}"
23
36
  end
37
+ CushionDefaults.log(log_str, :info)
24
38
  end
25
39
 
26
40
  # Defines default configuration settings
@@ -30,6 +44,9 @@ class Configuration # :nodoc:
30
44
  self.auto_load_from_yaml = true
31
45
  self.yaml_source_folder = 'config/cushion_defaults/'
32
46
  self.yaml_source_full_path = nil
47
+ self.record_in_log = true
48
+ self.logger = Logger.new $stdout
49
+ self.log_lvl = Logger::INFO
33
50
  self.whiny_yaml = false
34
51
  self.whiny_ignores = false
35
52
  self.ignore_attempts_to_set_nil = true
@@ -40,6 +57,21 @@ class Configuration # :nodoc:
40
57
  defaults!
41
58
  self.whiny_yaml = true
42
59
  self.whiny_ignores = true
60
+ self.log_lvl = Logger::DEBUG
61
+ end
62
+
63
+ def logger=(new_logger, should_assign_formatter=true)
64
+ if new_logger.nil?
65
+ self.record_in_log = false
66
+ @logger = nil
67
+ else
68
+ if new_logger.respond_to? :info
69
+ @logger = new_logger
70
+ assign_formatter_to_logger if should_assign_formatter
71
+ else
72
+ CushionDefaults.log("config.logger not set to #{new_logger}, as it does not appear to implement standard logging methods.", :error)
73
+ end
74
+ end
43
75
  end
44
76
 
45
77
  def underscore(s)
@@ -53,4 +85,35 @@ class Configuration # :nodoc:
53
85
  def yaml_file_for(klass)
54
86
  "#{CushionDefaults::configuration.yaml_source_full_path}#{underscore(klass.to_s)+'.yaml'}"
55
87
  end
88
+
89
+ def log_lvl=(lvl)
90
+ if @logger
91
+ @logger.level = lvl
92
+ end
93
+ end
94
+
95
+ def we_have_a_pushy?
96
+ @we_have_a_pushy
97
+ end
98
+
99
+ def no_pushies?
100
+ # Note that if you add a pushy, and then remove it, this will still return false. Basically, the method returns
101
+ # whether there was, at any point in time, a pushy default.
102
+ #
103
+ # The whole handling of pushies can and will be improved in the future.
104
+ !@we_have_a_pushy
105
+ end
106
+
107
+ def we_have_a_pushy!
108
+ @we_have_a_pushy = true
109
+ puts "Just set pushy!. Did it work? #{we_have_a_pushy?}"
110
+ end
111
+
112
+ protected
113
+
114
+ def assign_formatter_to_logger
115
+ logger.formatter = proc do |severity, time, progname, msg|
116
+ "\nCUSHIONDEFAULTS: #{severity}\n\t\##{progname ? "#{progname} at" : "At"} #{time.strftime('%d %b %Y, %H:%M:%S%p')}\n\t#{msg}\n"
117
+ end
118
+ end
56
119
  end
@@ -26,7 +26,12 @@ module CushionDefaults
26
26
  # If +key+ is in +self+ and +y+, then the value of +y+ will replace that in +self+ in the resulting +Hash+.
27
27
  # +y+ :: Hash (of any length) whose key/values will be added to this +DefaultsHash+.
28
28
  def +(y)
29
- y.each {|key, val| self[key] = val}
29
+ y.each do |key, val|
30
+ if has_key? key
31
+ CushionDefaults.log("As #{@owner} already has the default #{key} defined, this call to + is overwriting it.", :info)
32
+ end
33
+ self[key] = val
34
+ end
30
35
  self
31
36
  end
32
37
 
@@ -62,6 +67,7 @@ module CushionDefaults
62
67
  @pushy_defaults.delete(key)
63
68
  @polite_defaults.delete(key)
64
69
  super(key)
70
+ CushionDefaults.log("Default for #{key} in #{@owner} deleted.")
65
71
  end
66
72
 
67
73
  # Custom clear method. We need to check whether or not we should delete the methods associated with the keys, and we
@@ -73,6 +79,7 @@ module CushionDefaults
73
79
  @pushy_defaults.clear
74
80
  @polite_defaults.clear
75
81
  super
82
+ CushionDefaults.log("All defaults cleared for #{@owner}.", :info)
76
83
  end
77
84
 
78
85
  # Custom clear method. We need to check whether or not we should delete the methods associated with the key.
@@ -112,13 +119,16 @@ module CushionDefaults
112
119
  end
113
120
 
114
121
  def pushy!(sym)
122
+ CushionDefaults.conf.we_have_a_pushy!
115
123
  @pushy_defaults.add(sym)
116
124
  @polite_defaults.delete(sym)
125
+ CushionDefaults.log(":#{sym} in #{@owner} is now pushy.")
117
126
  end
118
127
 
119
128
  def not_pushy!(sym)
120
129
  @pushy_defaults.delete(sym)
121
130
  @polite_defaults.add(sym)
131
+ CushionDefaults.log("#{sym} in #{@owner} is now polite.")
122
132
  end
123
133
 
124
134
  def pushy?(sym)
@@ -10,25 +10,14 @@ require 'cushion_defaults/defaults_hash'
10
10
  # +Klass+.
11
11
  module CushionDefaults
12
12
 
13
- VERSION = '0.0.3'
14
-
15
- # CONFIG
13
+ VERSION = '0.1.0'
16
14
 
17
15
  # Location CushionDefaults looks for (optional) config file
18
16
  CALLING_PATH = File.expand_path(File.dirname($0)) + '/'
19
17
 
20
18
  CONFIG_LOCATION = CALLING_PATH + 'config/cushion_defaults.yaml'
21
19
 
22
- # If set to true, will automatically look at +YAML_PATH+ for each class that includes +CushionDefaults+ to try to
23
- # load defaults from yaml file located at the result of +YAML_PROC+. By default, this would be 'config/klass.yaml'.
24
-
25
- # Relative folder path to yaml file used both automatically if +AUTO_LOAD_FROM_YAML+ and with unparam'd manual calls
26
- # to +#defaults_from_yaml+.
27
-
28
- # If true, will complain (i.e., throw a warning) if a yaml file cannot be found for a class, whether called because of
29
- # AUTO_LOAD_FROM_YAML or via a manual call to +#defaults_from_yaml+.
30
-
31
- # Create or return a cached (singleton) +Configuration+ object.
20
+ # Create or return a cached (effectively singleton) +Configuration+ object.
32
21
  def self.configuration
33
22
  @configuration ||= Configuration.new
34
23
  end
@@ -37,6 +26,44 @@ module CushionDefaults
37
26
  self.configuration
38
27
  end
39
28
 
29
+ def self.preliminary_setup
30
+ local_conf_path = CALLING_PATH + configuration.yaml_source_folder + 'cushion_defaults.yaml'
31
+ if File.exists?(CONFIG_LOCATION)
32
+ t = File.open(CONFIG_LOCATION)
33
+ log("Found and opened config file at #{CONFIG_LOCATION}", :info)
34
+ elsif File.exists?(local_conf_path)
35
+ t = File.open(local_conf_path)
36
+ log("Found and opened config file at #{local_conf_path}", :info)
37
+ else
38
+ t = nil
39
+ log("No config file found. Looked at #{CONFIG_LOCATION} and #{local_conf_path}.", :info)
40
+ end
41
+
42
+ conf.from_hash(YAML::load(t)) if t
43
+ end
44
+
45
+ def self.log(str, level=:debug)
46
+ return unless conf.record_in_log
47
+ caller_method_name = caller_locations(1,1)[0].label.to_s
48
+ conf.logger.progname = caller_method_name
49
+ case level
50
+ when :debug
51
+ conf.logger.debug {str}
52
+ when :fatal
53
+ conf.logger.fatal {str}
54
+ when :error
55
+ conf.logger.error {str}
56
+ when :warn
57
+ conf.logger.warn {str}
58
+ when :info
59
+ conf.logger.info {str}
60
+ else
61
+ conf.logger.unknown {str}
62
+ end
63
+ end
64
+
65
+ self.preliminary_setup
66
+
40
67
  def self.nilish?(y)
41
68
  if conf.ignore_attempts_to_set_nil
42
69
  y.nil? || (conf.blank_str_is_nil && y.eql?(''))
@@ -48,36 +75,29 @@ module CushionDefaults
48
75
  # Yield the configuration object to a block.
49
76
  #
50
77
  # The following configuration methods are available with the returned object:
51
- # - #maintain_getters (boolean) :: If true, cushion_getters will be added/removed automatically as defaults are added/removed.
52
- # - #maintain_writers (boolean) :: If true, cushion_setters will be added/removed automatically as defaults are added/removed.
78
+ # - #update_readers (boolean) :: If true, cushion_readers will be added/removed automatically as defaults are added/removed. Def: false.
79
+ # - #update_writers (boolean) :: If true, cushion_writers will be added/removed automatically as defaults are added/removed. Def: false.
53
80
  # - #auto_load_from_yaml (boolean) :: Specifies whether we should attempt to automatically load defaults from class-specific yaml files. Def: true.
54
81
  # - #yaml_source_folder (string) :: Specifies the folder that contains class-specific yaml files. Def: 'config/cushion_defaults/'.
55
82
  # - #yaml_source_full_path (string) :: Specifies the full path for class-specific yaml files. Def: +nil+.
83
+ # - #record_in_log (boolean) :: If true, module will write to config.logger as appropriate. Def: true.
84
+ # - #logger (Logger) :: Any object that responds to logging methods. Def: Logger.new
56
85
  # - #whiny_yaml (boolean) :: If true, a warning will be issued if a class-specific yaml file cannot be found. Def: false.
57
86
  # - #whiny_ignores (boolean) :: If true, a warning will be issued when a variable is not set (or is undefined) due to being nilish. Def: false.
58
- # - #cushion_child_defaults_in_parent (boolean) :: If true, then if SubKlass < Klass and getters/setters are added for a default specified in Subklass, then a getter that returns nil will be added to Klass as well. Def: false.
59
87
  # - #ignore_attempts_to_set_nil (boolean) :: If true, then if a cushion_writer has been added for :x, then calling var.x = nil will instead remove_instance_variable(x) on var, effectively making it so that var.x will return the default value for x. Def: true.
60
88
  # - #blank_str_is_nil (boolean) :: If true (and if #ignore_attempts_to_set_nil), the setter works like Rail's #blank method: if it isn't blank, the instance variable is set. Def: true.
61
89
  def self.configure
62
90
  yield(configuration)
63
91
  end
64
92
 
65
- if File.exists?(CONFIG_LOCATION)
66
- t = File.open(CONFIG_LOCATION)
67
- elsif File.exists?(CALLING_PATH + configuration.yaml_source_folder + 'cushion_defaults.yaml')
68
- t = File.open(CALLING_PATH + configuration.yaml_source_folder + 'cushion_defaults.yaml')
69
- else
70
- t = nil
71
- end
72
-
73
- conf.from_hash(YAML::load(t)) if t
74
-
75
93
  # Add class methods and set up +DefaultsHash+ when the module is included in a class.
76
94
  #
77
95
  # If +AUTO_LOAD_FROM_YAML+, then it also searches for a yaml configuration file for the class in the path specified
78
96
  # in the config variables.
79
97
  def self.included(base)
80
98
 
99
+ log("CushionDefaults has been included in #{base}.")
100
+
81
101
  base.extend(ClassMethods)
82
102
 
83
103
  if configuration.auto_load_from_yaml
@@ -115,6 +135,8 @@ module CushionDefaults
115
135
  if !has_specified? key || (act_if_nilish && CushionDefaults.nilish?(instance_variable_get("@#{key}")))
116
136
  default_value = default(key)
117
137
  instance_variable_set("@#{key}", default_value)
138
+ else
139
+ log("Did not update #{key}")
118
140
  end
119
141
  end
120
142
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cushion_defaults
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Mitchell