cushion_defaults 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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