
Gibbler: Git-like Hashes and History for Ruby Objects - luccastera
http://www.rubyinside.com/gibbler-git-like-hashes-and-history-for-ruby-objects-1980.html
======
jrockway
We use this pattern for immutable objects in our Perl applications, although I
think our implementation is cleaner:

[http://github.com/nothingmuch/kiokudb/blob/96f9a380c715b7aa1...](http://github.com/nothingmuch/kiokudb/blob/96f9a380c715b7aa1757db8788f0df366355ba0f/lib/KiokuDB/Role/ID/Content.pm)

~~~
delano
Interesting! I'm not familiar with KiokuDB or Moose so I hope you don't mind a
couple questions:

\- what is the return value of $self->data in the example you link to?

\- do you store the digest or calculate it each time?

\- where can I find an example of the digests being used? I looked around the
repo a bit but couldn't find one.

~~~
jrockway
$self->data returns the value of the data attribute. The class is responsible
for generating the identity of instances.

The digest is only calculated when the object is stored. When it is retrieved
and stored again (a no-op, since it's immutable), the ID is remembered and not
recalculated. (Creating an identical new object will result in the digest
being calculated again, of course.)

The basic pattern for using this, once you've written the class:

    
    
        my $foo = Class->new( ... );
        my $id = $db->store($foo); # 29837a387bffe...
        my $foo2 = $db->lookup('29837a387bffe...');
    

Then this is true (the linker keeps note of the in-memory object IDs):

    
    
        refaddr $foo == refaddr $foo2

~~~
delano
Thanks for the detailed answer. The reason I ask is b/c there are some non-
trivial problems which are similar regardless of the language or
implementation. For example, what would the $self->data return value look like
for a non-scalar? Does it recursively process a hash?

When you say the linker keeps note of the object IDs, does this mean the
digests are stored outside of the objects themselves?

~~~
jrockway
Yes, the class is not responsible for managing any aspect of its storage. It
can provide hints, however, and that's what the "ID" and "Immutable" roles do.

It is worth pointing out that no automatic hashing is occurring. You write a
function that is invoked on an instance of the class that determines the
unique ID. You decide the content-addressibility of your object by choosing
the address based on the content.

(If you just want a unique ID per object, KiokuDB assigns a UUID by default as
the ID.)

