Files | Admin

Notes:

Release Name: 0.7.1

Notes:
= Gibbler - v0.7 ALPHA

Git-like hashes and history for Ruby objects for Ruby 1.8, 1.9 and JRuby. 

Check out the screencast[http://www.rubypulse.com/episode-0.3-gibbler.html] created by Alex Peuchert.

=== Important Information Regarding Your Digests

<i>Digest calculation changed in the 0.7 release for Proc objects. See "News" below for more info.</i>


== 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 <tt>gibbler_commit</tt> 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
    
http://delano.github.com/gibbler/img/whoababy.gif


== 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/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/aliases'
    require 'gibbler/history'
    
    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[http://delano.github.com/gibbler] 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[http://delano.github.com/gibbler] 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).

As of 0.7 all Proc objects have the same digest: <tt>12075835e94be34438376cd7a54c8db7e746f15d</tt>. 


== ALPHA Notice

This code is fresh so the interface may change. Some things to keep in mind:

* 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. 
* Digest calculation may change between minor releases (e.g. 0.6 to 0.7, etc)
* Don't forget to enjoy what you do!


== News

=== 2009-10-07: Digest calculation for Proc objects has changed.

Proc digests are now based on the name of the class and the value of Proc#name (if available). Procs or objects containing Procs will have different digests than those created in previous releases.

After much deliberation, I realized that Gibbler cares about the data and not the code. Procs are code, but a reference to a Proc in an instance variable is data. With this change all Proc objects have the same digest. This decision has the side benefit of increasing compatibility between Ruby 1.8, 1.9 & JRuby. 

This is the only change between 0.6.4 and 0.7.0 so if you prefer the previous calculation for Procs you can find it in that version. 

Happy Digesting!

=== 2009-10-07: Support for freezing and Regexp

In 0.6.4, all Gibbler objects will create a new digest when <tt>obj.freeze</tt> is called. All subsequent calls to <tt>obj.gibbler</tt> will return the most recent digest without having to run the calculation again. 

I've also added support for Regexp out of the box. 

=== 2009-07-20: Digest change for instances of Class, Module, and Proc

Digest calculation has changed for Class, Module, and Proc objects. Digests created with Gibbler 0.5.x and earlier will not match the ones created by 0.6. 

* Class and Module objects were calculating digests based on the output of <tt>self.to_s</tt>. This was a problem because that string contains a memory address which can change arbitrarily. The new calculation is based on the object class, the length of name, and the name itself. e.g. <tt>"Class:6:Object" # => '5620e4a8b10ec6830fece61d33f5d3e9a349b4c2'</tt>
* Proc objects were including the return value of <tt>self.binding</tt> in the digest calculation. This is not reliable because the binding includes an arbitrary address. The new calculation is based on the class name, the arity, and whether it was created with a lambda. 

Also note that this change affects the digests for Hashes and Arrays that contain instances of Class, Module, or Proc. 


== 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)
* Digests for Bignum objects are different between Ruby and JRuby. Does anyone know why?
* Digests for Proc objects are different between Ruby 1.8 and 1.9 because Proc.arity returns different values and 1.8 has no lambda? method.


== Installation

Via Rubygems, one of:

    $ gem install gibbler
    $ gem install delano-gibbler


or via download:
* gibbler-latest.tar.gz[http://github.com/delano/gibbler/tarball/latest]
* gibbler-latest.zip[http://github.com/delano/gibbler/zipball/latest]


== What People Are Saying

* "nice approach - everything is an object, every object is 'gittish'" -- @olgen_morten[http://twitter.com/olgen_morten/statuses/2629909133]
* "gibbler is just awesome" -- @TomK32[http://twitter.com/TomK32/statuses/2618542872]
* "wie cool ist Gibbler eigentlich?" -- @we5[http://twitter.com/we5/statuses/2615274279]
* "it's nice idea and implementation!" -- HristoHristov[http://www.rubyinside.com/gibbler-git-like-hashes-and-history-for-ruby-objects-1980.html#comment-39092]

== More Info

* Codes[http://github.com/delano/gibbler]
* RDocs[http://delano.github.com/gibbler]
* Sponsor[http://solutious.com/]
* Inspiration[http://www.youtube.com/watch?v=fipD4DdV48g]


== Thanks

* Kalin Harvey (krrh[http://github.com/krrh]) for the early feedback and artistic direction. 
* Alex Peuchert (aaalex[http://github.com/aaalex]) for creating the screencast.


== Credits

* Delano (@solutious.com)


== License

See: LICENSE.txt


Changes: GIBBLER, CHANGES #### 0.7.1 (2009-10-09) ################################# * FIXED: Gibbler::Complex now sorts instance variables before processing. This resolves the issue of digest compatibility between 1.8, 1.9, and JRuby. #### 0.7.0 (2009-10-07) ################################# NOTE: Digest calculation for Proc objects has changed. Procs or objects containing Procs will have different digests than those created in previous releases. * CHANGE: Proc digests are now based on the values of obj.class and obj.name (if available). #### 0.6.4 (2009-10-07) ################################# * FIXED: Now using correct superclass for DateTime (Date) * CHANGE: aliases.rb will now require gibbler so you don't need to specify both. i.e. require 'gibbler' require 'gibbler/aliases' * CHANGE: Gibbler::Object#gibbler returns the value of gibbler_cache when the object is frozen, without calculation. * ADDED: Gibbler::Object#freeze to create digest before freezing. * ADDED: Out of the box support for Regexp (Gibbler::String) * ADDED: Gibbler::Object#digest_cache alias for gibbler_cache #### 0.6.3 (2009-09-30) ################################# * FIXED: Won't save digest to cache if the object is frozen * CHANGE: Renamed __gibbler_cache to gibbler_cache (with backwards compatability) * CHANGE: Gibbler::Digest#== now returns true only for exact matches * ADDED: Gibbler::Digest#shorter, Gibbler::Digest#tiny, Gibbler::Digest#=== #### 0.6.2 (2009-09-15) ################################# * FIXED: Enforce specific string format for Time objects. Fixes an issue with Ruby 1.8.7 which formats the to_s value differently than 1.8.6 and 1.9.1. * ADDED: Support for NilClass, File, and URI #### 0.6.1 (2009-08-25) ################################# * ADDED: Support for Date, Time, and DateTime. Time and DateTime refers to times in UTC. * ADDED: Support for Range. #### 0.6.0 (2009-07-20) ################################# NOTE: Digest calculation for Proc and Class objects have changed. Digests created for these types will not match previous releases. * FIXED: Proc digests no longer refer to Proc#binding * CHANGE: The Gibbler module now raises an exception if it's included * CHANGE: Module and Class now use the default Gibbler::Object digest * ADDED: Gibbler::Object now contains a default digest method #### 0.5.4 (2009-07-17) ################################# * FIXED: Improved support for Symbol and Fixnum objects with Attic 0.4 #### 0.5.3 (2009-07-12) ################################# * FIXED: Updated gemspec to fix missing files (aliases) * CHANGE: conversion to attic instead of weirdo instance variables (@__gibbler__ and @__gibbler_history) * NEW DEPENDENCY: attic #### 0.5.2 (2009-07-07) ################################# * CHANGE: Moved Gibbler instance methods to Gibbler::Object * ADDED: Proc.gibbler which is included by default * ADDED: gibbler aliases to allow shorter methods by request. #### 0.5.1 (2009-07-06) ################################# * CHANGE: Renamed gibbler_revert to gibbler_revert! (Thanks ivey) #### 0.5 (2009-07-01) ################################# NOTE: This is a significant change from 0.4. Many method names have been modified so this release is not backwards compatible. * CHANGE: Now refer to "gibble" as "digest" in all docs and methods. * CHANGE: Gibbler#gibble -> Gibbler#gibbler * CHANGE: Gibble is now Gibbler::Digest * ADDED: Gibbler::History, supporting gibbler_snapshots and gibbler_revert for the following objects: Array, Hash * ADDED: Support for short, 8-character digests * ADDED: Expanded test coverage #### 0.4 (2009-06-30) ################################# NOTE: Calculated digests have changed since 0.3. Most digests created with 0.3 and earlier will not match those created in 0.4 for the same object * FIXED: Hash and Array now use the class of the value for hashing rather than Hash or Array (respectively). * FIXED: __gibbler methods now return a digest based on their own class. Previously, all digests were created by String.__gibbler so the class name from the original object got lost. * CHANGE: Gibbler methods are no longer available to all Ruby classes by default. The default list is now: String, Hash, Array, Symbol, Class, Fixnum, Bignum. * CHANGE: Renamed Gibbler.gibbler_digest_type to Gibbler.digest_type * ADDED: Custom objects can now "include Gibbler::Complex" #### 0.3 (2009-06-29) ################################# * CHANGE: Renamed to_gibble -> gibble * CHANGE: Renamed __default_gibbler to __gibbler * CHANGE: Created Gibbler module, all other modules can include its junk into their namespace. * ADDED: Object#hash and performance tryouts #### 0.2 (2009-06-25) ################################# NOTE: Initial release