Skip to content
DeepDive is a ruby gem that allows you to deep copy your object graphs in a controlled way. You can specify which instance variables to skip over in the duplication, which will just leave the original reference to them in the copy.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.idea
lib
spec
.document
.gitignore
.rspec
.ruby-version
.semver
.travis.yml
Gemfile
Gemfile.lock
Guardfile
LICENSE.txt
README.rdoc
Rakefile
deep_dive.gemspec

README.rdoc

DeepDive Deep Contolled Cloning

Join the chat at
https://gitter.im/flajann2/deep_dive

When you have a system of objects that have many references to each other, it becomes an issue to be able to clone properly that object graph. There may be control objects you may not want to clone, but maintain references to. And some references you may not wish to clone at all.

Enter DeepDive. Allows you a means by which you can do controlled deep cloning or copying of your complex interconnected objects.

Code Docs

www.rubydoc.info/github/flajann2/deep_dive/master

Gem Version

Gem Version

Installation

From commandline:

gem install deep_dive

From Gemfile:

gem 'deep_dive', '~> 0'

Usage

Simply include DeepDive in your base class. All classes derived will be set for deep cloning or deep duping.

Debugging

In some cases, you may need to get a dump of classes DeepDive is replicating, particulary if you need to hunt down objects whose instance variables might need to be added to the exclsion list. In that case, you may turn on the verbose mode, thusly:

DeepDive.verbose = true

in which case you will get a dump to stdout of all the classes of the objects it copies, which can be copious depending on your application.

Examples

class FooBase
  include DeepDive
  exclude :c
end

Even though the instance variable @c is not defined in the base class, any instance variables with that name in the subclasses will be excluded from the deep clone or duping. It will simply use the reference to that object instead (a.k.a shallow copying)

class Foo < FooBase
  attr_accessor :a, :b, :c, :changeme
end

class Bar < FooBase
  attr_accessor :a, :b, :c, :changeme
end

class FooBar < FooBase
  attr_accessor :a, :b, :c, :changeme, :dontcopy, :arr, :hsh, :nonddob
  exclude :dontcopy
end

class FooBlock < FooBar
  attr_accessor :freject, :fa, :fb, :fc, :frecur, :fexcludeme
  exclude { |sym, obj|
    sym == :@fexcludeme if obj.instance_variable_defined?(:@freject) and obj.send(:freject)
  }
end

@foo = Foo.new
@bar = Bar.new
@foobar = FooBar.new
@foobar.arr = [@foo, @bar, @foobar, "Just a string"]
@foobar.hsh = {foo: @foo, bar: @bar, foobar: @foobar, nonddob: "just a string"}

@foo.a = 'foo just around'
@bar.a = 'bar hanging around'
@foo.b = @bar
@bar.b = @foo
@foo.c = @bar.c = @foobar.c = @foobar
@foo.changeme = @bar.changeme = @foobar.changeme = "initial"

So now if you do:

nfoo = @foo.dclone

@foo.c will refer to the same object as nfoo.c, but @foo.b and nfoo.b will be different, as nfoo.b will be a deep clone of @foo.b.

Also, you may do:

mfoo = @foo.ddup

which will basically do a deep dup of @foo.

Please see spec/lib/deep_dive/deep_dive_spec.rb for a more comprehensve example of the above. Better documentation will be supplied shortly.

Patching

In some rare circumstances, you may need to patch an instance variable in your object graph during deep copying. Like for instance, when a child object is being cloned seprately from a different parent to be associated with a new parent.

We introduce patching. The instance variable

@foo.parent = @oldparent
pf = @foo.dclone parent: @newparent
pf.parent.should == @newparent

And all variables named “parent” in the object graph will pick up the new reference.

Note Well

DeepDive is expected to undergo “rapid” evolution until it hits 1.0.0. I will take every effort to keep the API backwards compatable until then. Thing is, DeepDive seems to be relatively stable anyway. As the RubyNEAT project is driving the features of deep_dive, we may see more exotic features in the near future.

Rails is driving much of the Ruby landscape these days. Alas, I have yet to test DeepDive in that context. In theory, it should just work fine, but I suspect there will need to be special treatment, especially with ActiveRecord type objects. Feel free to raise issues here so I can address them.

Release Notes

2016-10-23 0.3.4 – Minor update to spec because the older Rspec syntax failed to work in one case. Also updated the dependencies, and ran Rspec to ensure it still functions under Ruby 2.3.1

2015-07-07 0.3.0 – Added debugging and deep patching based on instance variable names.

2014-07-27 0.2.0 – Implemented the exclusion block, made gem restrictive to Ruby 2.x and higher.

Wish List and Known Issues

I wish to conver this document to org format someday.

I wish to fully support Rails and some of the special issues that may arise there.

Copyright

Copyright © 2013-2016 Fred Mitchell. See LICENSE.txt for further details.

You can’t perform that action at this time.