README.rdoc in sander6-daijobu-0.2.1 vs README.rdoc in sander6-daijobu-0.3.0

- old
+ new

@@ -11,38 +11,66 @@ rufus = Rufus::Tokyo::Cabinet.new('casket.tch') daijobu = Daijobu::Client.new(rufus, :schemes => :json) You can now use the regular hash getter and setter methods ([] and []=) without worrying about serialization. -The supported schemes are :marshal (using Marshal), :json (using JSON from the json gem), :yaml (using YAML), :eval (using Kernel::eval), and :raw (using nothing). +The out-of-the-box schemes are :marshal (using Marshal), :json (using JSON from the json gem), :yaml (using YAML), :eval (using Kernel::eval), and :raw (using nothing). +You can specify your own schemes by making new Daijobu::Parser objects. Just instantiate a new Parser and tell it how you want to parse and unparse. + + parser = Daijobu::Parser.new({ + :parse => Proc.new { |str| str.deserialize }, + :unparse => Proc.new { |obj| obj.serialize } + }) + +If you don't like passing procs as keyword arguments, you can give a block and define the #parse and #unparse methods yourself. + + parser = Daijobu::Parser.new do + def parse(str) + str.deserialize_using_some_fancy_method + end + def unparse(obj) + obj.serialize_using_some_fancy_method + end + end + +Alternately, you can make a new Parser with a delegate object, and specify which methods of the delegate should be used for parsing and unparsing. For example, the :marshal parser is this: + + parser = Daijobu::Parser(Marshal, :parse => :load, :unparse => :dump) + +Then just pass this parser object as your scheme. + + daijobu = Daijobu::Client.new(rufus, :schemes => parser) + Because some schemes are very strict, and sometimes what gets dumped can't be parsed back (for example, unparsing an integer using JSON), you can specify a set of schemes. If one doesn't work, it'll try the next in the list until it succeeds in parsing. Daijobu::Client.new(rufus, :schemes => [:json, :yaml, :eval]) -Daijobu doesn't do any real format-checking; if, say, Marshal.load throws an error, for whatever reason, it'll just rescue and move on to the next scheme. The success of this gem all hinges on the fact that the supported serialization formats don't have much to do with one another (except for JSON and YAML, of course), and you shouldn't ever end up parsing Ruby code as JSON accidentally, or at least not in unintended ways. +Daijobu doesn't do any real format-checking; if, say, Marshal.load throws an error, for whatever reason, it'll just rescue and move on to the next scheme. Therefore, if you define your own parser and want to use fallbacks, the #parse and #unparse methods should raise some kind of error (besides a Daijobu::Error) if they fail. You can set different read and write schemes, too. This would be useful, say, if you wanted to change the serialization format. Daijobu::Client.new(rufus, :read => :json, :write => :raw) -One last cool thing that I threw in just because: the key names in a key-value store are often namespaced. You can call these namespaces as methods on a Client object to automatically prepend that namespace to any keys asked for. +One last cool thing that I threw in just because: the key names in a key-value store are often namespaced, so you can call these namespaces as methods on a Client object to automatically prepend that namespace to any keys asked for. - daijobu = Daijobu::Client.new(rufus, :read => :json, :write => :raw) daijobu.namespace['123'] # => looks for 'namespace:123' daijobu.name.space['123'] # => looks for 'name:space:123' -You can set the separator (defaults to ':' because that's what I was using) on the Daijobu::NamespaceProxy class. +You can set the separator (defaults to ':' because that's what I was using) on the Daijobu::Client class. - Daijobu::NamespaceProxy.default_separator = '/' - daijobu.name.space['123'] # => looks for 'name/space/123' + Daijobu::Client.default_separator = '/' + daijobu.name.space['123'] # => 'name/space/123' -And a last bit of syntatical sugar: you can leave off the brackets when asking for namespaced keys. +Or you can set it per-invocation: - daijobu.namespace '123' # => looks for 'namespace:123' - daijobu.name.space '123' # => looks for 'name:space:123' + daijobu.name('/').space(':')['123'] # => 'name/space:123' + +If this is the case, it'll keep using the last separator mentioned for subsequent namespacing. + daijobu.some('/').long(':').name.space['123'] # => 'some/long:name:space:123' + === "Anything else I should know?" Pretty much only the getting and setting APIs are implemented for the supported adapters, so fancier stuff like iterating over keys isn't there yet. Multi-get is also kind of janky right now for MemCache, due to a flaw in the memcache-client gem that assumes Marshal.load'ing on get_multi. Keys are therefore fetched one at a time. @@ -50,11 +78,9 @@ === "What does the future hold for Daijobu?" I plan to eventually switch out my home-rolled adapters for a more complete and more-intelligently-written backend, like Moneta, but last time I checked it was broken and I needed this gem to do work right now. Until then, I'm thinking of putting in support for user-defined adapters as a stopgap, basically any object that responds to #get(key) and #set(key, value). - -Less of a priority is support for user-defined serialization schemes that respond to #parse(string) and #unparse(object). I also plan to take a look at ActiveRecord::Base#serialize to see if I can do something with that, because reading and writing YAML is like dying every day. === "What's with the name?"