### Home Classes Methods

### In Files

- lib/chef/mixin/deep_merge.rb

### Namespace

- CLASS Chef::Mixin::DeepMerge::InvalidParameter

### Methods

- #clear_or_nil
- #deep_merge
- #deep_merge!
- #merge
- #overwrite_unmergeables
- #role_merge

### Files

- LICENSE
- README.rdoc

### Class/Module Index

Quicksearch

- Chef
- Chef::ApiClient
- Chef::Application
- Chef::Application::Client
- Chef::Application::Knife
- Chef::Application::Solo
- Chef::Application::Wakeup
- Chef::Application::WindowsService
- Chef::Certificate
- Chef::Checksum
- Chef::Checksum::Storage
- Chef::Checksum::Storage::Filesystem
- Chef::ChecksumCache
- Chef::Client
- Chef::Config
- Chef::Cookbook
- Chef::Cookbook::Chefignore
- Chef::Cookbook::CookbookVersionLoader
- Chef::Cookbook::FileSystemFileVendor
- Chef::Cookbook::FileVendor
- Chef::Cookbook::Metadata
- Chef::Cookbook::MinimalMetadata
- Chef::Cookbook::RemoteFileVendor
- Chef::Cookbook::SyntaxCheck
- Chef::CookbookCacheCleaner
- Chef::CookbookCollection
- Chef::CookbookLoader
- Chef::CookbookSiteStreamingUploader
- Chef::CookbookSiteStreamingUploader::MultipartStream
- Chef::CookbookSiteStreamingUploader::StreamPart
- Chef::CookbookSiteStreamingUploader::StringPart
- Chef::CookbookSynchronizer
- Chef::CookbookUploader
- Chef::CookbookVersion
- Chef::CookbookVersionSelector
- Chef::CouchDB
- Chef::Daemon
- Chef::DataBag
- Chef::DataBagItem
- Chef::EncryptedDataBagItem
- Chef::EncryptedDataBagItem::DecryptionFailure
- Chef::EncryptedDataBagItem::Decryptor
- Chef::EncryptedDataBagItem::Decryptor::Version0Decryptor
- Chef::EncryptedDataBagItem::Decryptor::Version1Decryptor
- Chef::EncryptedDataBagItem::UnsupportedCipher
- Chef::EncryptedDataBagItem::UnsupportedEncryptedDataBagItemFormat
- Chef::Environment
- Chef::EventDispatch
- Chef::EventDispatch::Base
- Chef::EventDispatch::Dispatcher
- Chef::Exceptions
- Chef::Exceptions::AmbiguousRunlistSpecification
- Chef::Exceptions::Application
- Chef::Exceptions::AttributeNotFound
- Chef::Exceptions::CannotDetermineNodeName
- Chef::Exceptions::CannotWritePrivateKey
- Chef::Exceptions::CommandTimeout
- Chef::Exceptions::ConfigurationError
- Chef::Exceptions::CookbookFrozen
- Chef::Exceptions::CookbookNotFound
- Chef::Exceptions::CookbookNotFoundInRepo
- Chef::Exceptions::CookbookVersionConflict
- Chef::Exceptions::CookbookVersionNameMismatch
- Chef::Exceptions::CookbookVersionSelection
- Chef::Exceptions::CookbookVersionSelection::InvalidRunListItems
- Chef::Exceptions::CookbookVersionSelection::UnsatisfiableRunListItem
- Chef::Exceptions::CouchDBNotFound
- Chef::Exceptions::Cron
- Chef::Exceptions::DsclCommandFailed
- Chef::Exceptions::EnclosingDirectoryDoesNotExist
- Chef::Exceptions::Env
- Chef::Exceptions::ErlCall
- Chef::Exceptions::Exec
- Chef::Exceptions::FileNotFound
- Chef::Exceptions::Group
- Chef::Exceptions::GroupIDNotFound
- Chef::Exceptions::Ifconfig
- Chef::Exceptions::IllegalChecksumRevert
- Chef::Exceptions::InsufficientPermissions
- Chef::Exceptions::InvalidCommandOption
- Chef::Exceptions::InvalidCookbookVersion
- Chef::Exceptions::InvalidDataBagItemID
- Chef::Exceptions::InvalidDataBagName
- Chef::Exceptions::InvalidDataBagPath
- Chef::Exceptions::InvalidEnvironmentRunListSpecification
- Chef::Exceptions::InvalidHomeDirectory
- Chef::Exceptions::InvalidPrivateKey
- Chef::Exceptions::InvalidRemoteGitReference
- Chef::Exceptions::InvalidResourceReference
- Chef::Exceptions::InvalidResourceSpecification
- Chef::Exceptions::InvalidVersionConstraint
- Chef::Exceptions::Link
- Chef::Exceptions::MissingLibrary
- Chef::Exceptions::MissingParentDirectory
- Chef::Exceptions::MissingRole
- Chef::Exceptions::Mount
- Chef::Exceptions::ObsoleteDependencySyntax
- Chef::Exceptions::Override
- Chef::Exceptions::Package
- Chef::Exceptions::PrivateKeyMissing
- Chef::Exceptions::QueryParseError
- Chef::Exceptions::RecipeNotFound
- Chef::Exceptions::RedirectLimitExceeded
- Chef::Exceptions::RequestedUIDUnavailable
- Chef::Exceptions::ResourceNotFound
- Chef::Exceptions::RoleNotFound
- Chef::Exceptions::Route
- Chef::Exceptions::SearchIndex
- Chef::Exceptions::Service
- Chef::Exceptions::ShellCommandFailed
- Chef::Exceptions::SolrConnectionError
- Chef::Exceptions::UnresolvableGitReference
- Chef::Exceptions::UnsupportedAction
- Chef::Exceptions::User
- Chef::Exceptions::UserIDNotFound
- Chef::Exceptions::ValidationFailed
- Chef::Exceptions::Win32APIError
- Chef::Exceptions::Win32APIFunctionNotImplemented
- Chef::FileAccessControl
- Chef::FileAccessControl::Unix
- Chef::FileAccessControl::Windows
- Chef::FileAccessControl::Windows::Security
- Chef::FileCache
- Chef::Formatters
- Chef::Formatters::APIErrorFormatting
- Chef::Formatters::Base
- Chef::Formatters::Doc
- Chef::Formatters::ErrorDescription
- Chef::Formatters::ErrorInspectors
- Chef::Formatters::ErrorInspectors::CompileErrorInspector
- Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector
- Chef::Formatters::ErrorInspectors::CookbookSyncErrorInspector
- Chef::Formatters::ErrorInspectors::NodeLoadErrorInspector
- Chef::Formatters::ErrorInspectors::RegistrationErrorInspector
- Chef::Formatters::ErrorInspectors::ResourceFailureInspector
- Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector
- Chef::Formatters::ErrorMapper
- Chef::Formatters::Minimal
- Chef::Formatters::NullFormatter
- Chef::Formatters::Outputter
- Chef::Formatters::UnknownFormatter
- Chef::Handler
- Chef::Handler::ErrorReport
- Chef::Handler::JsonFile
- Chef::IndexQueue
- Chef::IndexQueue::AmqpClient
- Chef::IndexQueue::Consumer
- Chef::IndexQueue::Consumer::ClassMethods
- Chef::IndexQueue::Indexable
- Chef::IndexQueue::Indexable::ClassMethods
- Chef::JSONCompat
- Chef::Knife
- Chef::Knife::Bootstrap
- Chef::Knife::ClientBulkDelete
- Chef::Knife::ClientCreate
- Chef::Knife::ClientDelete
- Chef::Knife::ClientEdit
- Chef::Knife::ClientList
- Chef::Knife::ClientReregister
- Chef::Knife::ClientShow
- Chef::Knife::Configure
- Chef::Knife::ConfigureClient
- Chef::Knife::CookbookBulkDelete
- Chef::Knife::CookbookCreate
- Chef::Knife::CookbookDelete
- Chef::Knife::CookbookDownload
- Chef::Knife::CookbookList
- Chef::Knife::CookbookMetadata
- Chef::Knife::CookbookMetadataFromFile
- Chef::Knife::CookbookSCMRepo
- Chef::Knife::CookbookShow
- Chef::Knife::CookbookSiteDownload
- Chef::Knife::CookbookSiteInstall
- Chef::Knife::CookbookSiteList
- Chef::Knife::CookbookSiteSearch
- Chef::Knife::CookbookSiteShare
- Chef::Knife::CookbookSiteShow
- Chef::Knife::CookbookSiteUnshare
- Chef::Knife::CookbookSiteVendor
- Chef::Knife::CookbookTest
- Chef::Knife::CookbookUpload
- Chef::Knife::Core
- Chef::Knife::Core::BootstrapContext
- Chef::Knife::Core::GenericPresenter
- Chef::Knife::Core::NodeFormattingOptions
- Chef::Knife::Core::NodePresenter
- Chef::Knife::Core::ObjectLoader
- Chef::Knife::Core::ObjectLoader::ObjectType
- Chef::Knife::Core::TextFormatter
- Chef::Knife::DataBagCreate
- Chef::Knife::DataBagDelete
- Chef::Knife::DataBagEdit
- Chef::Knife::DataBagFromFile
- Chef::Knife::DataBagList
- Chef::Knife::DataBagShow
- Chef::Knife::EnvironmentCreate
- Chef::Knife::EnvironmentDelete
- Chef::Knife::EnvironmentEdit
- Chef::Knife::EnvironmentFromFile
- Chef::Knife::EnvironmentList
- Chef::Knife::EnvironmentShow
- Chef::Knife::Exec
- Chef::Knife::Help
- Chef::Knife::IndexRebuild
- Chef::Knife::NodeBulkDelete
- Chef::Knife::NodeCreate
- Chef::Knife::NodeDelete
- Chef::Knife::NodeEdit
- Chef::Knife::NodeEditor
- Chef::Knife::NodeFromFile
- Chef::Knife::NodeList
- Chef::Knife::NodeRunListAdd
- Chef::Knife::NodeRunListRemove
- Chef::Knife::NodeShow
- Chef::Knife::RecipeList
- Chef::Knife::RoleBulkDelete
- Chef::Knife::RoleCreate
- Chef::Knife::RoleDelete
- Chef::Knife::RoleEdit
- Chef::Knife::RoleFromFile
- Chef::Knife::RoleList
- Chef::Knife::RoleShow
- Chef::Knife::Search
- Chef::Knife::Ssh
- Chef::Knife::Status
- Chef::Knife::SubcommandLoader
- Chef::Knife::TagCreate
- Chef::Knife::TagDelete
- Chef::Knife::TagList
- Chef::Knife::UI
- Chef::Log
- Chef::Log::Formatter
- Chef::MinimalCookbookVersion
- Chef::Mixin
- Chef::Mixin::CheckHelper
- Chef::Mixin::Checksum
- Chef::Mixin::Command
- Chef::Mixin::Command::Unix
- Chef::Mixin::Command::Windows
- Chef::Mixin::ConvertToClassName
- Chef::Mixin::CreatePath
- Chef::Mixin::DeepMerge
- Chef::Mixin::DeepMerge::InvalidParameter
- Chef::Mixin::Deprecation
- Chef::Mixin::Deprecation::DeprecatedInstanceVariable
- Chef::Mixin::Deprecation::DeprecatedObjectProxyBase
- Chef::Mixin::EnforceOwnershipAndPermissions
- Chef::Mixin::FileClass
- Chef::Mixin::FromFile
- Chef::Mixin::GetSourceFromPackage
- Chef::Mixin::Language
- Chef::Mixin::Language::PlatformDependentValue
- Chef::Mixin::Language::PlatformFamilyDependentValue
- Chef::Mixin::LanguageIncludeAttribute
- Chef::Mixin::LanguageIncludeRecipe
- Chef::Mixin::ParamsValidate
- Chef::Mixin::PathSanity
- Chef::Mixin::RecipeDefinitionDSLCore
- Chef::Mixin::Securable
- Chef::Mixin::ShellOut
- Chef::Mixin::Template
- Chef::Mixin::Template::ChefContext
- Chef::Mixin::Template::TemplateError
- Chef::Mixin::WhyRun
- Chef::Mixin::WhyRun::ConvergeActions
- Chef::Mixin::WhyRun::ResourceRequirements
- Chef::Mixin::WhyRun::ResourceRequirements::Assertion
- Chef::Mixin::WhyRun::ResourceRequirements::Assertion::AssertionFailure
- Chef::Mixin::XMLEscape
- Chef::Mixin::XMLEscape::FastXS
- Chef::Mixin::XMLEscape::PureRuby
- Chef::Node
- Chef::Node::Attribute
- Chef::OpenIDRegistration
- Chef::Platform
- Chef::Provider
- Chef::Provider::Breakpoint
- Chef::Provider::CookbookFile
- Chef::Provider::Cron
- Chef::Provider::Cron::Solaris
- Chef::Provider::Deploy
- Chef::Provider::Deploy::Revision
- Chef::Provider::Deploy::Timestamped
- Chef::Provider::Directory
- Chef::Provider::Env
- Chef::Provider::Env::Windows
- Chef::Provider::ErlCall
- Chef::Provider::Execute
- Chef::Provider::File
- Chef::Provider::Git
- Chef::Provider::Group
- Chef::Provider::Group::Aix
- Chef::Provider::Group::Dscl
- Chef::Provider::Group::Gpasswd
- Chef::Provider::Group::Groupadd
- Chef::Provider::Group::Groupmod
- Chef::Provider::Group::Pw
- Chef::Provider::Group::Suse
- Chef::Provider::Group::Usermod
- Chef::Provider::Group::Windows
- Chef::Provider::HttpRequest
- Chef::Provider::Ifconfig
- Chef::Provider::Link
- Chef::Provider::Log
- Chef::Provider::Log::ChefLog
- Chef::Provider::Mdadm
- Chef::Provider::Mount
- Chef::Provider::Mount::Mount
- Chef::Provider::Mount::Windows
- Chef::Provider::Ohai
- Chef::Provider::Package
- Chef::Provider::Package::Apt
- Chef::Provider::Package::Dpkg
- Chef::Provider::Package::EasyInstall
- Chef::Provider::Package::Freebsd
- Chef::Provider::Package::Ips
- Chef::Provider::Package::Macports
- Chef::Provider::Package::Pacman
- Chef::Provider::Package::Portage
- Chef::Provider::Package::Rpm
- Chef::Provider::Package::Rubygems
- Chef::Provider::Package::Rubygems::AlternateGemEnvironment
- Chef::Provider::Package::Rubygems::CurrentGemEnvironment
- Chef::Provider::Package::Rubygems::GemEnvironment
- Chef::Provider::Package::SmartOS
- Chef::Provider::Package::Solaris
- Chef::Provider::Package::Yum
- Chef::Provider::Package::Yum::RPMDb
- Chef::Provider::Package::Yum::RPMDbPackage
- Chef::Provider::Package::Yum::RPMDependency
- Chef::Provider::Package::Yum::RPMPackage
- Chef::Provider::Package::Yum::RPMProvide
- Chef::Provider::Package::Yum::RPMRequire
- Chef::Provider::Package::Yum::RPMUtils
- Chef::Provider::Package::Yum::RPMVersion
- Chef::Provider::Package::Yum::YumCache
- Chef::Provider::Package::Zypper
- Chef::Provider::RemoteDirectory
- Chef::Provider::RemoteFile
- Chef::Provider::ResourceUpdate
- Chef::Provider::Route
- Chef::Provider::RubyBlock
- Chef::Provider::Script
- Chef::Provider::Service
- Chef::Provider::Service::Arch
- Chef::Provider::Service::Debian
- Chef::Provider::Service::Freebsd
- Chef::Provider::Service::Gentoo
- Chef::Provider::Service::Init
- Chef::Provider::Service::Insserv
- Chef::Provider::Service::Invokercd
- Chef::Provider::Service::Macosx
- Chef::Provider::Service::Redhat
- Chef::Provider::Service::Simple
- Chef::Provider::Service::Solaris
- Chef::Provider::Service::Systemd
- Chef::Provider::Service::Upstart
- Chef::Provider::Service::Windows
- Chef::Provider::Subversion
- Chef::Provider::Template
- Chef::Provider::User
- Chef::Provider::User::Dscl
- Chef::Provider::User::Pw
- Chef::Provider::User::Useradd
- Chef::Provider::User::Windows
- Chef::REST
- Chef::REST::AuthCredentials
- Chef::REST::CookieJar
- Chef::REST::NoopInflater
- Chef::REST::RESTRequest
- Chef::Recipe
- Chef::ReservedNames
- Chef::ReservedNames::Win32
- Chef::ReservedNames::Win32::API
- Chef::ReservedNames::Win32::API::Error
- Chef::ReservedNames::Win32::API::File
- Chef::ReservedNames::Win32::API::File::BY_HANDLE_FILE_INFORMATION
- Chef::ReservedNames::Win32::API::File::FILETIME
- Chef::ReservedNames::Win32::API::File::REPARSE_DATA_BUFFER
- Chef::ReservedNames::Win32::API::File::REPARSE_DATA_BUFFER_GENERIC
- Chef::ReservedNames::Win32::API::File::REPARSE_DATA_BUFFER_MOUNT_POINT
- Chef::ReservedNames::Win32::API::File::REPARSE_DATA_BUFFER_SYMBOLIC_LINK
- Chef::ReservedNames::Win32::API::File::REPARSE_DATA_BUFFER_UNION
- Chef::ReservedNames::Win32::API::File::SECURITY_ATTRIBUTES
- Chef::ReservedNames::Win32::API::File::WIN32_FIND_DATA
- Chef::ReservedNames::Win32::API::Macros
- Chef::ReservedNames::Win32::API::Memory
- Chef::ReservedNames::Win32::API::PSAPI
- Chef::ReservedNames::Win32::API::PSAPI::PROCESS_MEMORY_COUNTERS
- Chef::ReservedNames::Win32::API::Process
- Chef::ReservedNames::Win32::API::Security
- Chef::ReservedNames::Win32::API::Security::ACE_HEADER
- Chef::ReservedNames::Win32::API::Security::ACE_WITH_MASK_AND_SID
- Chef::ReservedNames::Win32::API::Security::ACLStruct
- Chef::ReservedNames::Win32::API::Security::LUID
- Chef::ReservedNames::Win32::API::Security::LUID_AND_ATTRIBUTES
- Chef::ReservedNames::Win32::API::Security::TOKEN_PRIVILEGES
- Chef::ReservedNames::Win32::API::System
- Chef::ReservedNames::Win32::API::System::OSVERSIONINFOEX
- Chef::ReservedNames::Win32::API::Unicode
- Chef::ReservedNames::Win32::Error
- Chef::ReservedNames::Win32::File
- Chef::ReservedNames::Win32::File::Info
- Chef::ReservedNames::Win32::Handle
- Chef::ReservedNames::Win32::Memory
- Chef::ReservedNames::Win32::Process
- Chef::ReservedNames::Win32::Security
- Chef::ReservedNames::Win32::Security::ACE
- Chef::ReservedNames::Win32::Security::ACL
- Chef::ReservedNames::Win32::Security::SID
- Chef::ReservedNames::Win32::Security::SecurableObject
- Chef::ReservedNames::Win32::Security::SecurityDescriptor
- Chef::ReservedNames::Win32::Security::Token
- Chef::ReservedNames::Win32::Unicode
- Chef::ReservedNames::Win32::Version
- Chef::Resource
- Chef::Resource::AptPackage
- Chef::Resource::Bash
- Chef::Resource::Breakpoint
- Chef::Resource::ChefGem
- Chef::Resource::Conditional
- Chef::Resource::CookbookFile
- Chef::Resource::Cron
- Chef::Resource::Csh
- Chef::Resource::Deploy
- Chef::Resource::DeployBranch
- Chef::Resource::DeployRevision
- Chef::Resource::Directory
- Chef::Resource::DpkgPackage
- Chef::Resource::EasyInstallPackage
- Chef::Resource::Env
- Chef::Resource::ErlCall
- Chef::Resource::Execute
- Chef::Resource::File
- Chef::Resource::FreebsdPackage
- Chef::Resource::GemPackage
- Chef::Resource::Git
- Chef::Resource::Group
- Chef::Resource::HttpRequest
- Chef::Resource::Ifconfig
- Chef::Resource::IpsPackage
- Chef::Resource::Link
- Chef::Resource::Log
- Chef::Resource::MacportsPackage
- Chef::Resource::Mdadm
- Chef::Resource::Mount
- Chef::Resource::Notification
- Chef::Resource::Ohai
- Chef::Resource::Package
- Chef::Resource::PacmanPackage
- Chef::Resource::Perl
- Chef::Resource::PlatformMap
- Chef::Resource::PortagePackage
- Chef::Resource::Python
- Chef::Resource::RemoteDirectory
- Chef::Resource::RemoteFile
- Chef::Resource::Route
- Chef::Resource::RpmPackage
- Chef::Resource::Ruby
- Chef::Resource::RubyBlock
- Chef::Resource::Scm
- Chef::Resource::Script
- Chef::Resource::Service
- Chef::Resource::SmartOSPackage
- Chef::Resource::SolarisPackage
- Chef::Resource::Subversion
- Chef::Resource::Template
- Chef::Resource::TimestampedDeploy
- Chef::Resource::User
- Chef::Resource::YumPackage
- Chef::ResourceCollection
- Chef::ResourceCollection::StepableIterator
- Chef::ResourceDefinition
- Chef::ResourceDefinitionList
- Chef::ResourceReporter
- Chef::ResourceReporter::ResourceReport
- Chef::Role
- Chef::RunContext
- Chef::RunList
- Chef::RunList::RunListExpansion
- Chef::RunList::RunListExpansionFromAPI
- Chef::RunList::RunListExpansionFromCouchDB
- Chef::RunList::RunListExpansionFromDisk
- Chef::RunList::RunListItem
- Chef::RunList::VersionedRecipeList
- Chef::RunStatus
- Chef::Runner
- Chef::Sandbox
- Chef::ScanAccessControl
- Chef::Search
- Chef::Search::Query
- Chef::ShellOut
- Chef::SolrQuery
- Chef::SolrQuery::QueryTransform
- Chef::SolrQuery::SolrHTTPRequest
- Chef::StreamingCookbookUploader
- Chef::StreamingCookbookUploader::MultipartStream
- Chef::StreamingCookbookUploader::StreamPart
- Chef::StreamingCookbookUploader::StringPart
- Chef::Util
- Chef::Util::FileEdit
- Chef::Util::Windows
- Chef::Util::Windows::NetGroup
- Chef::Util::Windows::NetUse
- Chef::Util::Windows::NetUser
- Chef::Util::Windows::Volume
- Chef::Version
- Chef::VersionConstraint
- Chef::WebUIUser
- Lucene
- Lucene::AndOperator
- Lucene::BinaryOp
- Lucene::Body
- Lucene::BoostOp
- Lucene::ExclFieldRange
- Lucene::Field
- Lucene::FieldName
- Lucene::FieldRange
- Lucene::FuzzyOp
- Lucene::FuzzyParam
- Lucene::Group
- Lucene::InclFieldRange
- Lucene::NotOperator
- Lucene::OrOperator
- Lucene::Phrase
- Lucene::ProhibitedOperator
- Lucene::RangeValue
- Lucene::RequiredOperator
- Lucene::Term
- Lucene::UnaryOp
- Shef
- Shef::ClientSession
- Shef::DoppelGangerClient
- Shef::DoppelGangerSession
- Shef::Extensions
- Shef::Extensions::FalseClass
- Shef::Extensions::ObjectCoreExtensions
- Shef::Extensions::String
- Shef::Extensions::Symbol
- Shef::Extensions::TrueClass
- Shef::ModelWrapper
- Shef::NamedDataBagWrapper
- Shef::Options
- Shef::ShefREST
- Shef::ShefSession
- Shef::SoloSession
- Shef::StandAloneSession
- Net
- Net::HTTPError
- Net::HTTPFatalError
- Net::HTTPRetriableError
- Net::HTTPServerException
- Moneta
- Moneta::BasicFile
- Moneta::Defaults
- FFI
- FFI::Pointer
- FileUtils
- FileUtils::Entry_
- ChefNetHTTPExceptionExtensions
- Dir
- FalseClass
- Mash
- Numeric
- Object
- Regexp
- String
- Symbol
- TrueClass

No matching classes.

# Chef::Mixin::DeepMerge

Implements a deep merging algorithm for nested data structures.

#### Notice:

    This code was originally imported from deep_merge by Steve Midgley.
    deep_merge is available under the MIT license from
    http://trac.misuse.org/science/wiki/DeepMerge

### Public Instance Methods

clear_or_nil(obj) click to toggle source

    # File lib/chef/mixin/deep_merge.rb, line 233
    def clear_or_nil(obj)
      if obj.respond_to?(:clear)
        obj.clear
      else
        obj = nil
      end
      obj
    end

deep_merge(source, dest, options = {}) click to toggle source

    # File lib/chef/mixin/deep_merge.rb, line 229
    def deep_merge(source, dest, options = {})
      deep_merge!(source.dup, dest.dup, options)
    end

deep_merge!(source, dest, options = {}) click to toggle source

Deep Merge core documentation. deep_merge! method permits merging of arbitrary child elements. The two top level elements must be hashes. These hashes can contain unlimited (to stack limit) levels of child elements. These child elements to not have to be of the same types. Where child elements are of the same type, deep_merge will attempt to merge them together. Where child elements are not of the same type, deep_merge will skip or optionally overwrite the destination element with the contents of the source element at that level. So if you have two hashes like this:

    source = {:x => [1,2,3], :y => 2}
    dest =   {:x => [4,5,'6'], :y => [7,8,9]}
    dest.deep_merge!(source)
    Results: {:x => [1,2,3,4,5,'6'], :y => 2}

By default, "deep_merge!" will overwrite any unmergeables and merge everything else. To avoid this, use "deep_merge" (no bang/exclamation mark)

Options:

    Options are specified in the last parameter passed, which should be in hash format:
    hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '!merge'})
    :preserve_unmergeables  DEFAULT: false
       Set to true to skip any unmergeable elements from source
    :knockout_prefix        DEFAULT: nil
       Set to string value to signify prefix which deletes elements from existing element
       A colon is appended when indicating a specific value, eg:
       :knockout_prefix => "dontmerge", is referenced as "dontmerge:foobar" in an array
    :sort_merged_arrays     DEFAULT: false
       Set to true to sort all arrays that are merged together
    :unpack_arrays          DEFAULT: nil
       Set to string value to run "Array::join" then "String::split" against all arrays
    :merge_debug            DEFAULT: false
       Set to true to get console output of merge process for debugging

Selected Options Details: :knockout_prefix => The purpose of this is to provide a way to remove elements

    from existing Hash by specifying them in a special way in incoming hash
     source = {:x => ['!merge:1', '2']}
     dest   = {:x => ['1', '3']}
     dest.ko_deep_merge!(source)
     Results: {:x => ['2','3']}
    Additionally, if the knockout_prefix is passed alone as a string, it will cause
    the entire element to be removed:
     source = {:x => '!merge'}
     dest   = {:x => [1,2,3]}
     dest.ko_deep_merge!(source)
     Results: {:x => ""}

:unpack_arrays => The purpose of this is to permit compound elements to be passed

    in as strings and to be converted into discrete array elements
    irsource = {:x => ['1,2,3', '4']}
    dest   = {:x => ['5','6','7,8']}
    dest.deep_merge!(source, {:unpack_arrays => ','})
    Results: {:x => ['1','2','3','4','5','6','7','8'}
    Why: If receiving data from an HTML form, this makes it easy for a checkbox
     to pass multiple values from within a single HTML element

There are many tests for this library - and you can learn more about the features and usages of deep_merge! by just browsing the test examples

    # File lib/chef/mixin/deep_merge.rb, line 104
    def deep_merge!(source, dest, options = {})
      # turn on this line for stdout debugging text
      merge_debug = options[:merge_debug] || false
      overwrite_unmergeable = !options[:preserve_unmergeables]
      knockout_prefix = options[:knockout_prefix] || nil
      raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!" if knockout_prefix == ""
      raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!" if knockout_prefix && !overwrite_unmergeable
      # if present: we will split and join arrays on this char before merging
      array_split_char = options[:unpack_arrays] || false
      # request that we sort together any arrays when they are merged
      sort_merged_arrays = options[:sort_merged_arrays] || false
      di = options[:debug_indent] || ''
      # do nothing if source is nil
      return dest if source.nil?
      # if dest doesn't exist, then simply copy source to it
      if dest.nil? && overwrite_unmergeable
        dest = source; return dest
      end

      puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug
      if source.kind_of?(Hash)
        puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug
        source.each do |src_key, src_value|
          if dest.kind_of?(Hash)
            puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug
            if dest[src_key]
              puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug
              dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + '  '))
            else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
              puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
              # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
              begin
                src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
              rescue TypeError
                src_dup = src_value
              end
              dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + '  '))
            end
          else # dest isn't a hash, so we overwrite it completely (if permitted)
            if overwrite_unmergeable
              puts "#{di}  overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over->  #{dest.inspect}" if merge_debug
              dest = overwrite_unmergeables(source, dest, options)
            end
          end
        end
      elsif source.kind_of?(Array)
        puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
        # if we are instructed, join/split any source arrays before processing
        if array_split_char
          puts "#{di} split/join on source: #{source.inspect}" if merge_debug
          source = source.join(array_split_char).split(array_split_char)
          if dest.kind_of?(Array)
            dest = dest.join(array_split_char).split(array_split_char)
          end
        end
        # if there's a naked knockout_prefix in source, that means we are to truncate dest
        ko_variants = [ knockout_prefix, "#{knockout_prefix}:" ]
        ko_variants.each do |ko|
          if source.index(ko)
            dest = clear_or_nil(dest); source.delete(ko)
          end
        end
        if dest.kind_of?(Array)
          if knockout_prefix
            print "#{di} knocking out: " if merge_debug
            # remove knockout prefix items from both source and dest
            source.delete_if do |ko_item|
              retval = false
              item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%{^#{knockout_prefix}:}, "") : ko_item
              if item != ko_item
                print "#{ko_item} - " if merge_debug
                dest.delete(item)
                dest.delete(ko_item)
                retval = true
              end
              retval
            end
            puts if merge_debug
          end
          puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
          dest = dest | source
          dest.sort! if sort_merged_arrays
        elsif overwrite_unmergeable
          puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
          dest = overwrite_unmergeables(source, dest, options)
        end
      else # src_hash is not an array or hash, so we'll have to overwrite dest
        puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
        dest = overwrite_unmergeables(source, dest, options)
      end
      puts "#{di}Returning #{dest.inspect}" if merge_debug
      dest
    end

merge(first, second) click to toggle source

    # File lib/chef/mixin/deep_merge.rb, line 31
    def merge(first, second)
      first  = Mash.new(first)  unless first.kind_of?(Mash)
      second = Mash.new(second) unless second.kind_of?(Mash)

      DeepMerge.deep_merge(second, first, {:preserve_unmergeables => false})
    end

overwrite_unmergeables(source, dest, options) click to toggle source

allows deep_merge! to uniformly handle overwriting of unmergeable entities

    # File lib/chef/mixin/deep_merge.rb, line 199
    def overwrite_unmergeables(source, dest, options)
      merge_debug = options[:merge_debug] || false
      overwrite_unmergeable = !options[:preserve_unmergeables]
      knockout_prefix = options[:knockout_prefix] || false
      di = options[:debug_indent] || ''
      if knockout_prefix && overwrite_unmergeable
        if source.kind_of?(String) # remove knockout string from source before overwriting dest
          if source == knockout_prefix
            src_tmp = ""
          else
            src_tmp = source.gsub(%{^#{knockout_prefix}:},"")
          end
        elsif source.kind_of?(Array) # remove all knockout elements before overwriting dest
          src_tmp = source.delete_if {|ko_item| ko_item.kind_of?(String) && ko_item.match(%{^#{knockout_prefix}:}) }
        else
          src_tmp = source
        end
        if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest
          puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug
          dest = src_tmp
        else # if we do find a knockout_prefix, then we just delete dest
          puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug
          dest = ""
        end
      elsif overwrite_unmergeable
        dest = source
      end
      dest
    end

role_merge(first, second) click to toggle source

Inherited roles use the knockout_prefix array subtraction functionality This is likely to go away in Chef >= 0.11

    # File lib/chef/mixin/deep_merge.rb, line 40
    def role_merge(first, second)
      first  = Mash.new(first)  unless first.kind_of?(Mash)
      second = Mash.new(second) unless second.kind_of?(Mash)

      DeepMerge.deep_merge(second, first, {:knockout_prefix => "!merge", :preserve_unmergeables => false})
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.