Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 176 lines (101 sloc) 6.197 kb

Gibbler - v0.5 ALPHA

Git-like hashes and history for Ruby objects.

NOTE: Gibbler supports Ruby 1.8, 1.9 and JRuby.

Example 1 – Basic Usage

require 'gibbler'

"kimmy".gibbler              # => c8027100ecc54945ab15ddac529230e38b1ba6a1
:kimmy.gibbler               # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df

config = {}
config.gibbler               # => 4fdcadc66a38feb9c57faf3c5a18d5e76a6d29bf
config.gibbled?              # => false

config[:server] = {          
  :users => [:dave, :ali],   
  :ports => [22, 80, 443]    
}                            
config.gibbled?              # => true
config.gibbler               # => ef23d605f8c4fc80a8e580f9a0e8dab8426454a8 

config[:server][:users] << :yanni

config.gibbler               # => 4c558a56bc2abf5f8a845a69e47ceb5e0003683f

config.gibbler.short         # => 4c558a56

Example 2 – Object History

Gibbler can also keep track of the history of changes to an object. By default Gibbler supports history for Hash, Array, and String objects. The gibbler_commit method creates a clone of the current object and stores in an instance variable using the current hash digest as the key.

require 'gibbler'
require 'gibbler/history'

a = { :magic => :original }     
a.gibbler_commit             # => d7049916ddb25e6cc438b1028fb957e5139f9910

a[:magic] = :updated           
a.gibbler_commit             # => b668098e16d08898532bf3aa33ce2253a3a4150e

a[:magic] = :changed 
a.gibbler_commit             # => 0b11c377fccd44554a601e5d2b135c46dc1c4cb1

a.gibbler_history            # => d7049916, b668098e, 0b11c377

a.gibbler_revert! 'd7049916' # Return to a specific commit
a.gibbler                    # => d7049916ddb25e6cc438b1028fb957e5139f9910
a                            # => { :magic => :original } 

a.delete :magic

a.gibbler_revert!            # Return to the previous commit  
a.gibbler                    # => 0b11c377fccd44554a601e5d2b135c46dc1c4cb1
a                            # => { :magic => :changed }

a.gibbler_object 'b668098e'  # => { :magic => :updated }
a.gibbler_stamp              # => 2009-07-01 18:56:52 -0400

Example 3 – Method Aliases

If you have control over the namespaces of your objects, you can use the method aliases to tighten up your code a bit. The “gibbler” and “gibbled?” methods can be accessed via “digest” and “changed?”, respectively. (The reason they're not enabled by default is to avoid conflicts.)

require 'gibbler'
require 'gibbler/aliases'

"kimmy".digest               # => c8027100ecc54945ab15ddac529230e38b1ba6a1
:kimmy.digest                # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df

a = [:a, :b, :c]
a.digest                     # => e554061823b8f06367555d1ee4c25b4ffee61944
a << :d
a.changed?                   # => true

The history methods also have aliases which remove the “gibbler_”.

require 'gibbler'
require 'gibbler/history'
require 'gibbler/aliases'

a = { :magic => :original }     
a.commit                     
a.history                    
a.revert!                    
# etc...

Supported Classes

Gibbler methods are available only to the classes which explicitly include them (see RDocs for details on which classes are supported by default). You can also extend custom objects:

class FullHouse
  include Gibbler::Complex
  attr_accessor :roles
end

a = FullHouse.new
a.gibbler                    # => 4192d4cb59975813f117a51dcd4454ac16df6703

a.roles = [:jesse, :joey, :danny, :kimmy, :michelle, :dj, :stephanie]
a.gibbler                    # => 6ea546919dc4caa2bab69799b71d48810a1b48fa

Gibbler::Complex creates a digest based on the name of the class and the names and values of the instance variables. See the RDocs for other Gibbler::* types.

If you want to support all Ruby objects, add the following to your application:

class Object
  include Gibbler::String
end

Gibbler::String creates a digest based on the name of the class and the output of the to_s method. This is a reasonable default for most objects however any object that includes the object address in to_s (e.g. “Object:0x0x4ac9f0…”) will produce unreliable digests (because the address can change).

ALPHA Notice

This code is hella fresh (est 2009-06-25). It's barely tested and the interface may change, but it's fun to play with. I'll happily accept patches.

NOTE: Gibbler history is not suitable for very large objects since it keeps complete copies of the object in memory. This is a very early implementation of this feature so don't rely on it for production code.

News

2009-07-07: Added aliases

The “gibbler” methods can be cumbersome so I added some aliases which can be included by request. See the example above.

2009-07-06: Renamed gibbler_revert to gibbler_revert!

The gibbler_revert! method modifies the object in place so this was an important change to follow the Ruby convention of appending the exclamation mark. Thanks to ivey for pointing this out.

Known Issues

  • gibbler or gibbled? must be called at least once before gibbled? will be able to return a useful value (otherwise there is no previous digest value to compare to)

Installation

Via Rubygems, one of:

$ gem install gibbler
$ gem install delano-gibbler

or via download:

More Info

Credits

  • Delano (@solutious.com)

License

See: LICENSE.txt

Something went wrong with that request. Please try again.