rconfig 0.3.3 → 0.4.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.
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