rconfig 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/ChangeLog +50 -0
  5. data/Credits +13 -0
  6. data/Gemfile +9 -0
  7. data/Gemfile.lock +30 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.rdoc +0 -0
  10. data/Rakefile +11 -0
  11. data/demo/application.conf +3 -0
  12. data/demo/demo.conf +13 -0
  13. data/demo/demo.rb +14 -0
  14. data/demo/demo.xml +13 -0
  15. data/demo/demo.yml +12 -0
  16. data/doc/classes/ClassVariables.html +111 -0
  17. data/doc/classes/ConfigError.html +120 -0
  18. data/doc/classes/ConfigHash.html +354 -0
  19. data/doc/classes/Constants.html +226 -0
  20. data/doc/classes/Hash.html +269 -0
  21. data/doc/classes/InvalidConfigPathError.html +119 -0
  22. data/doc/classes/Object.html +220 -0
  23. data/doc/classes/PropertiesFileParser.html +282 -0
  24. data/doc/classes/RConfig.html +1745 -0
  25. data/doc/created.rid +1 -0
  26. data/doc/files/README_rdoc.html +271 -0
  27. data/doc/files/lib/rconfig/class_variables_rb.html +107 -0
  28. data/doc/files/lib/rconfig/config_hash_rb.html +114 -0
  29. data/doc/files/lib/rconfig/constants_rb.html +101 -0
  30. data/doc/files/lib/rconfig/core_ext/hash_rb.html +114 -0
  31. data/doc/files/lib/rconfig/core_ext/object_rb.html +101 -0
  32. data/doc/files/lib/rconfig/core_ext_rb.html +114 -0
  33. data/doc/files/lib/rconfig/exceptions_rb.html +110 -0
  34. data/doc/files/lib/rconfig/properties_file_parser_rb.html +146 -0
  35. data/doc/files/lib/rconfig/rconfig_rb.html +186 -0
  36. data/doc/files/lib/rconfig_rb.html +117 -0
  37. data/doc/fr_class_index.html +35 -0
  38. data/doc/fr_file_index.html +37 -0
  39. data/doc/fr_method_index.html +75 -0
  40. data/doc/index.html +24 -0
  41. data/doc/rdoc-style.css +208 -0
  42. data/lib/generators/rconfig/install_generator.rb +13 -0
  43. data/lib/generators/rconfig/templates/rconfig.rb +82 -0
  44. data/lib/rconfig.rb +98 -32
  45. data/lib/rconfig/callbacks.rb +46 -0
  46. data/lib/rconfig/cascade.rb +56 -0
  47. data/lib/rconfig/config.rb +78 -0
  48. data/lib/rconfig/constants.rb +58 -0
  49. data/lib/rconfig/core_ext/array.rb +3 -0
  50. data/lib/rconfig/core_ext/hash.rb +56 -57
  51. data/lib/rconfig/core_ext/nil.rb +5 -0
  52. data/lib/rconfig/core_ext/string.rb +3 -0
  53. data/lib/rconfig/core_methods.rb +276 -0
  54. data/lib/rconfig/exceptions.rb +21 -8
  55. data/lib/rconfig/load_paths.rb +55 -0
  56. data/lib/rconfig/logger.rb +86 -0
  57. data/lib/rconfig/properties_file.rb +138 -0
  58. data/lib/rconfig/reload.rb +75 -0
  59. data/lib/rconfig/settings.rb +93 -0
  60. data/lib/rconfig/utils.rb +175 -0
  61. data/lib/tasks/gem.rake +14 -0
  62. data/lib/tasks/rdoc.rake +11 -0
  63. data/lib/tasks/spec.rake +25 -0
  64. data/rconfig.gemspec +33 -0
  65. data/spec/core_ext/object_spec.rb +44 -0
  66. data/spec/rconfig_spec.rb +7 -0
  67. data/spec/spec.opts +4 -0
  68. data/spec/spec_helper.rb +16 -0
  69. metadata +128 -32
  70. data/lib/rconfig/config_hash.rb +0 -105
  71. data/lib/rconfig/core_ext.rb +0 -6
  72. data/lib/rconfig/properties_file_parser.rb +0 -80
  73. data/lib/rconfig/rconfig.rb +0 -871
  74. data/test/rconfig_test.rb +0 -381
data/lib/rconfig.rb CHANGED
@@ -1,39 +1,105 @@
1
- #--
1
+ ##
2
+ #
2
3
  # Copyright (c) 2009 Rahmal Conda <rahmal@gmail.com>
4
+ # -------------------------------------------------------------------
5
+ # The complete solution for Ruby Configuration Management. RConfig is a Ruby library that
6
+ # manages configuration within Ruby applications. It bridges the gap between yaml, xml, and
7
+ # key/value based properties files, by providing a centralized solution to handle application
8
+ # configuration from one location. It provides the simplicity of hash-based access, that
9
+ # Rubyists have come to know and love, supporting your configuration style of choice, while
10
+ # providing many new features, and an elegant API.
11
+ #
12
+ # -------------------------------------------------------------------
13
+ # * Simple, easy to install and use.
14
+ # * Supports yaml, xml, and properties files.
15
+ # * Yaml and xml files supprt infinite level of configuration grouping.
16
+ # * Intuitive dot-notation 'key chaining' argument access.
17
+ # * Simple well-known hash/array based argument access.
18
+ # * Implements multilevel caching to reduce disk access.
19
+ # * Short-hand access to 'global' application configuration, and shell environment.
20
+ # * Overlays multiple configuration files to support environment, host, and
21
+ # even locale-specific configuration.
22
+ #
23
+ # -------------------------------------------------------------------
24
+ # The overlay order of the config files is defined by SUFFIXES:
25
+ # * nil
26
+ # * _local
27
+ # * _config
28
+ # * _local_config
29
+ # * _{environment} (.i.e _development)
30
+ # * _{environment}_local (.i.e _development_local)
31
+ # * _{hostname} (.i.e _whiskey)
32
+ # * _{hostname}_config_local (.i.e _whiskey_config_local)
33
+ #
34
+ # -------------------------------------------------------------------
35
+ #
36
+ # Example:
37
+ #
38
+ # shell/console =>
39
+ # export LANG=en
40
+ #
41
+ # demo.yml =>
42
+ # server:
43
+ # address: host.domain.com
44
+ # port: 81
45
+ # ...
3
46
  #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
47
+ # application.properties =>
48
+ # debug_level = verbose
49
+ # ...
50
+ #
51
+ # demo.rb =>
52
+ # require 'rconfig'
53
+ # RConfig.load_paths = ['$HOME/config', '#{APP_ROOT}/config', '/demo/conf']
54
+ # RConfig.demo[:server][:port] => 81
55
+ # RConfig.demo.server.address => 'host.domain.com'
56
+ #
57
+ # RConfig[:debug_level] => 'verbose'
58
+ # RConfig[:lang] => 'en'
59
+ # ...
60
+ #
61
+ require 'active_support'
62
+ require 'rconfig/core_ext/array'
63
+ require 'rconfig/core_ext/hash'
64
+ require 'rconfig/core_ext/nil'
23
65
 
24
- $:.unshift File.dirname(__FILE__)
66
+ module RConfig
67
+ VERSION = '0.4.0'
25
68
 
26
- require 'rubygems'
27
- require 'active_support'
28
- require 'active_support/core_ext'
29
- require 'active_support/core_ext/hash/conversions'
30
- require 'active_support/core_ext/hash/indifferent_access'
69
+ autoload :Socket, 'socket'
70
+ autoload :YAML, 'yaml'
71
+ autoload :ERB, 'erb'
72
+ autoload :Logger, 'logger'
73
+ autoload :Singleton, 'singleton'
74
+
75
+ autoload :Concern, 'active_support/concern'
76
+ autoload :Hash, 'active_support/core_ext/hash/conversions'
77
+ autoload :HashWithIndifferentAccess, 'active_support/core_ext/hash/indifferent_access'
31
78
 
32
- require 'rconfig/core_ext'
33
- require 'rconfig/config_hash'
34
- require 'rconfig/properties_file_parser'
35
- require 'rconfig/rconfig'
79
+ autoload :Config, 'rconfig/config'
80
+ autoload :Logger, 'rconfig/logger'
81
+ autoload :Exceptions, 'rconfig/exceptions'
82
+ autoload :Utils, 'rconfig/utils'
83
+ autoload :Constants, 'rconfig/constants'
84
+ autoload :Settings, 'rconfig/settings'
85
+ autoload :ConfigError, 'rconfig/exceptions'
86
+ autoload :LoadPaths, 'rconfig/load_paths'
87
+ autoload :Cascade, 'rconfig/cascade'
88
+ autoload :Callbacks, 'rconfig/callbacks'
89
+ autoload :Reload, 'rconfig/reload'
90
+ autoload :CoreMethods, 'rconfig/core_methods'
91
+ autoload :PropertiesFile, 'rconfig/properties_file'
92
+ autoload :InstallGenerator, 'generators/rconfig/install_generator'
36
93
 
37
- # Create global reference to RConfig instance
38
- $config = RConfig.instance
94
+ extend ActiveSupport::Concern
39
95
 
96
+ extend Utils
97
+ extend Constants
98
+ extend Settings
99
+ extend Exceptions
100
+ extend LoadPaths
101
+ extend Cascade
102
+ extend Callbacks
103
+ extend Reload
104
+ extend CoreMethods
105
+ end
@@ -0,0 +1,46 @@
1
+ module RConfig
2
+ module Callbacks
3
+
4
+ ##
5
+ # Register a callback when a config has been reloaded. If no config name
6
+ # is specified, the callback will be registered under the name :ANY. The
7
+ # name :ANY will register a callback for any config file change.
8
+ #
9
+ # Example:
10
+ #
11
+ # class MyClass
12
+ # self.my_config = { }
13
+ # RConfig.on_load(:cache) do
14
+ # self.my_config = { }
15
+ # end
16
+ # def my_config
17
+ # self.my_config ||= something_expensive_thing_on_config(RConfig.cache.memory_limit)
18
+ # end
19
+ # end
20
+ #
21
+ def on_load(*args, &blk)
22
+ args << :ANY if args.empty?
23
+ proc = blk.to_proc
24
+
25
+ # Call proc on registration.
26
+ proc.call()
27
+
28
+ # Register callback proc.
29
+ args.each do |name|
30
+ (self.callbacks[name.to_s] ||= []) << proc
31
+ end
32
+ end
33
+
34
+ ##
35
+ # Executes all of the reload callbacks registered to the specified config name,
36
+ # and all of the callbacks registered to run on any config, as specified by the
37
+ # :ANY symbol.
38
+ def fire_on_load(name)
39
+ procs = (self.callbacks['ANY'] || RConfig::EMPTY_ARRAY) + (self.callbacks[name] || RConfig::EMPTY_ARRAY)
40
+ procs.uniq!
41
+ logger.debug "fire_on_load(#{name.inspect}): callbacks[#{procs.inspect}]" unless procs.empty?
42
+ procs.each { |proc| proc.call() }
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,56 @@
1
+ module RConfig
2
+ module Cascade
3
+ include Constants
4
+
5
+ ##
6
+ # Sets a custome overlay for
7
+ def overlay=(value)
8
+ reload(false) if self.overlay != value
9
+ self.overlay = value && value.dup.freeze
10
+ end
11
+
12
+ ##
13
+ # Returns a list of suffixes to try for a given config name.
14
+ #
15
+ # A config name with an explicit overlay (e.g.: 'name_GB')
16
+ # overrides any current _overlay.
17
+ #
18
+ # This allows code to specifically ask for config overlays
19
+ # for a particular locale.
20
+ #
21
+ def suffixes_for(name)
22
+ name = name.to_s
23
+ self.suffixes[name] ||= begin
24
+ ol = overlay
25
+ name_x = name.dup
26
+ if name_x.sub!(/_([A-Z]+)$/, '')
27
+ ol = $1
28
+ end
29
+ name_x.freeze
30
+ result = if ol
31
+ ol_ = ol.upcase
32
+ ol = ol.downcase
33
+ x = []
34
+ SUFFIXES.each do |suffix|
35
+ # Standard, no overlay:
36
+ # e.g.: database_<suffix>.yml
37
+ x << suffix
38
+
39
+ # Overlay:
40
+ # e.g.: database_(US|GB)_<suffix>.yml
41
+ x << [ol_, suffix]
42
+ end
43
+ [name_x, x.freeze]
44
+ else
45
+ [name.dup.freeze, SUFFIXES.freeze]
46
+ end
47
+ result.freeze
48
+
49
+ logger.debug "suffixes(#{name}) => #{result.inspect}"
50
+
51
+ result
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,78 @@
1
+ ##
2
+ # Copyright (c) 2009 Rahmal Conda <rahmal@gmail.com>
3
+ #
4
+ # Config is a special class, derived from HashWithIndifferentAccess.
5
+ # It was specifically created for handling config data or creating mock
6
+ # objects from yaml files. It provides a dotted notation for accessing
7
+ # embedded hash values, similar to the way one might traverse a object tree.
8
+ #
9
+ module RConfig
10
+ class Config < ::HashWithIndifferentAccess
11
+
12
+ ##
13
+ # HashWithIndifferentAccess#default is broken in early versions of Rails.
14
+ # This is defined to use the hash version in Config#default
15
+ define_method(:hash_default, Hash.instance_method(:default))
16
+
17
+ ##
18
+ # Dotted notation can be used with arguments (useful for creating mock objects)
19
+ # in the YAML file the method name is a key, argument(s) form a nested key,
20
+ # so that the correct value is retrieved and returned.
21
+ #
22
+ # For example loading to variable foo a yaml file that looks like:
23
+ # customer:
24
+ # id: 12345678
25
+ # verified:
26
+ # phone: verified
27
+ # :address: info_not_available
28
+ # ? [name, employer]
29
+ # : not_verified
30
+ #
31
+ # Allows the following calls:
32
+ # foo.customer.id => 12345678
33
+ # foo.customer.verified.phone => verified
34
+ # foo.customer.verified("phone") => verified
35
+ # foo.customer.verified(:address) => info_not_available
36
+ # foo.customer.verified("name", "employer") => not_verified
37
+ #
38
+ # Note that :address is specified as a symbol, where phone is just a string.
39
+ # Depending on what kind of parameter the method being mocked out is going
40
+ # to be called with, define in the YAML file either a string or a symbol.
41
+ # This also works inside the composite array keys.
42
+ def method_missing(method, *args)
43
+ method = method.to_s
44
+ return if method == 'default_key'
45
+ value = self[method]
46
+ case args.size
47
+ when 0 # e.g.: RConfig.application.method
48
+ value
49
+ when 1 # e.g.: RConfig.application.method(one_arg)
50
+ value.send(args[0])
51
+ else # e.g.: RConfig.application.method(arg_one, args_two, ...)
52
+ value[args]
53
+ end
54
+ end
55
+
56
+ ##
57
+ # Allow hash.default => hash['default']
58
+ # without breaking Hash's usage of default(key)
59
+ def default(key = self.default_key)
60
+ key = key.to_s if key.is_a?(Symbol)
61
+ if key == self.default_key
62
+ self['default'] if key?('default')
63
+ else
64
+ hash_default(key)
65
+ end
66
+ end
67
+
68
+ protected
69
+
70
+ ##
71
+ # Override HashWithIndifferentAccess#convert_value
72
+ # return instance of Config for Hash values.
73
+ def convert_value(value)
74
+ value.is_a?(Hash) ? self.class.new(value).freeze : super
75
+ end
76
+
77
+ end # class Config
78
+ end
@@ -0,0 +1,58 @@
1
+ module RConfig
2
+ module Constants
3
+
4
+ # Sets CONFIG_ROOT to RAILS_ROOT/config unless it has already
5
+ # been defined (i.e. in rails env, or calling ruby app).
6
+ CONFIG_ROOT = File.join(::Rails.root || '', 'config').gsub(/^\//, '').gsub(/\/$/,'') if defined?(::Rails) && !defined?(CONFIG_ROOT)
7
+
8
+ # ENV TIER i.e. (development, integration, staging, or production)
9
+ # Defaults to RAILS_ENV if running in Rails, otherwise, it checks
10
+ # if ENV['TIER'] is present. If not, it assumes production.
11
+ ENV_TIER = (defined?(RAILS_ENV) ? RAILS_ENV : (ENV['TIER'] || 'production')) unless defined? ENV_TIER
12
+
13
+ # yml, yaml => yaml files, parsable by YAML library
14
+ YML_FILE_TYPES = [:yml, :yaml].freeze unless defined? YML_FILE_TYPES
15
+
16
+ # xml => self-explanatory
17
+ XML_FILE_TYPES = [:xml].freeze unless defined? XML_FILE_TYPES
18
+
19
+ # conf, properties => <key=value> based config files
20
+ CNF_FILE_TYPES = [:cnf, :conf, :config, :properties].freeze unless defined? CNF_FILE_TYPES
21
+
22
+ # The type of file used for config. Valid choices
23
+ # include (yml, yaml, xml, conf, config, properties)
24
+ CONFIG_FILE_TYPES = (YML_FILE_TYPES + XML_FILE_TYPES + CNF_FILE_TYPES).freeze unless defined? CONFIG_FILE_TYPES
25
+
26
+ # Use CONFIG_HOSTNAME environment variable to
27
+ # test host-based configurations.
28
+ HOSTNAME = ENV['CONFIG_HOSTNAME'] || Socket.gethostname unless defined? HOSTNAME
29
+
30
+ # Short Hostname: removes all chars from HOSTNAME, after first "."
31
+ # Used to specify machine-specific config files.
32
+ HOSTNAME_SHORT = HOSTNAME.sub(/\..*$/, '').freeze unless defined? HOSTNAME_SHORT
33
+
34
+ # This is an array of filename suffixes facilitates cascading
35
+ # configuration overrides (i.e. 'services_local', 'services_development').
36
+ # These files get loaded in the order of the array. Meaning the last file
37
+ # loaded overrides everything before it. So config files suffixed with
38
+ # hostname has the highest precedence, and therefore overrides everything.
39
+ # Example:
40
+ # database_local.yml overrides database.yml
41
+ # database_staging.yml overrides database_local.yml
42
+ # database_appsvr01.yml overrides database_integration.yml
43
+ SUFFIXES = [
44
+ nil, # Empty suffix, used for default config file (i.e. database.yml).
45
+ :local, # Allows user to create 'local' overrides (i.e. database_local.yml), primarily used for development.
46
+ :config, :local_config,
47
+ ENV_TIER, [ENV_TIER, :local], # Environment configs (i.e. development, test, production).
48
+ HOSTNAME_SHORT, [HOSTNAME_SHORT, :config_local], # Short hostname (i.e. appsvr01), for server-specific configs.
49
+ HOSTNAME, [HOSTNAME, :config_local] # Hostname (i.e. appsvr01.acme.com), for server/domain-specific configs.
50
+ ] unless defined? SUFFIXES
51
+
52
+ # Used in place of undefined but expected arrays,
53
+ # to prevent creating a bunch of unecesary arrays
54
+ # in memory. See ConfigCore.fire_on_load
55
+ EMPTY_ARRAY = [].freeze unless defined? EMPTY_ARRAY
56
+
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ class Array
2
+ alias_method :blank?, :empty?
3
+ end
@@ -1,5 +1,4 @@
1
-
2
- #++
1
+ ##
3
2
  # source: http://rubyforge.org/projects/facets/
4
3
  # version: 1.7.46
5
4
  # license: Ruby License
@@ -7,12 +6,12 @@
7
6
  # BUG: weave is destructive to values in the source hash that are arrays!
8
7
  # (this is acceptable for RConfig's use as the basis for weave!)
9
8
  #
10
- #--
9
+ #
11
10
  class Hash
12
11
 
13
12
  ##
14
13
  # Weaves the contents of two hashes producing a new hash.
15
- def weave(other_hash, dont_clobber = true)
14
+ def weave(other_hash, clobber=false)
16
15
  return self unless other_hash
17
16
  unless other_hash.kind_of?(Hash)
18
17
  raise ArgumentError, "RConfig: (Hash#weave) expected <Hash>, but was <#{other_hash.class}>"
@@ -24,68 +23,68 @@ class Hash
24
23
 
25
24
  self_dup[key] =
26
25
 
27
- if self_node = self_dup[key]
26
+ if self_node = self_dup[key]
28
27
 
29
- case self_node
30
- when Hash
28
+ case self_node
29
+ when Hash
31
30
 
32
- # hash1, hash2 => hash3 (recursive +)
33
- if other_node.is_a?(Hash)
31
+ # hash1, hash2 => hash3 (recursive +)
32
+ if other_node.is_a?(Hash)
34
33
 
35
- self_node.weave(other_node, dont_clobber)
34
+ self_node.weave(other_node, clobber)
36
35
 
37
- # hash, array => error (Can't weave'em, must clobber.)
38
- elsif other_node.is_a?(Array) && dont_clobber
36
+ # hash, array => error (Can't weave'em, must clobber.)
37
+ elsif other_node.is_a?(Array) && !clobber
39
38
 
40
- raise(ArgumentError, "RConfig: (Hash#weave) Can't weave Hash and Array")
39
+ raise(ArgumentError, "RConfig: (Hash#weave) Can't weave Hash and Array")
41
40
 
42
- # hash, array => hash[key] = array
43
- # hash, value => hash[key] = value
44
- else
45
- other_node
46
- end
41
+ # hash, array => hash[key] = array
42
+ # hash, value => hash[key] = value
43
+ else
44
+ other_node
45
+ end
47
46
 
48
- when Array
49
-
50
- # array, hash => array << hash
51
- # array1, array2 => array1 + array2
52
- # array, value => array << value
53
- if dont_clobber
54
- case other_node
55
- when Hash
56
- self_node << other_node
57
- when Array
58
- self_node + other_node
59
- else
60
- self_node << other_node
61
- end
62
-
63
- # array, hash => hash
64
- # array1, array2 => array2
65
- # array, value => value
66
- else
67
- other_node
68
- end
47
+ when Array
48
+
49
+ # array, hash => array << hash
50
+ # array1, array2 => array1 + array2
51
+ # array, value => array << value
52
+ unless clobber
53
+ case other_node
54
+ when Hash
55
+ self_node << other_node
56
+ when Array
57
+ self_node + other_node
58
+ else
59
+ self_node << other_node
60
+ end
61
+
62
+ # array, hash => hash
63
+ # array1, array2 => array2
64
+ # array, value => value
65
+ else
66
+ other_node
67
+ end
68
+
69
+ else
69
70
 
70
- else
71
+ # value, array => array.unshift(value)
72
+ if other_node.is_a?(Array) && !clobber
73
+ other_node.unshift(self_node)
71
74
 
72
- # value, array => array.unshift(value)
73
- if other_node.is_a?(Array) && dont_clobber
74
- other_node.unshift(self_node)
75
+ # value1, value2 => value2
76
+ else
77
+ other_node
78
+ end
75
79
 
76
- # value1, value2 => value2
77
- else
78
- other_node
79
- end
80
-
81
- end # case self_node
80
+ end # case self_node
82
81
 
83
- # Target hash didn't have a node matching the key,
84
- # so just add it from the source hash.
85
- # !self_dup.has_key?(key) => self_dup.add(key, other_node)
86
- else
87
- other_node
88
- end
82
+ # Target hash didn't have a node matching the key,
83
+ # so just add it from the source hash.
84
+ # !self_dup.has_key?(key) => self_dup.add(key, other_node)
85
+ else
86
+ other_node
87
+ end
89
88
 
90
89
  } # other_hash.each
91
90
 
@@ -95,8 +94,8 @@ class Hash
95
94
  ##
96
95
  # Same as self.weave(other_hash, dont_clobber) except that it weaves other hash
97
96
  # to itself, rather than create a new hash.
98
- def weave!(other_hash, dont_clobber = true)
99
- weaved_hash = self.weave(other_hash, dont_clobber)
97
+ def weave!(other_hash, clobber=false)
98
+ weaved_hash = self.weave(other_hash, clobber)
100
99
  self.merge!(weaved_hash)
101
100
  end
102
101