The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    Data::CapabilityBased - Ask your data not what it is, but what it can do
    for your program

SYNOPSIS
      use Data::Store;
      use Data::Collection;
      use Data::Stream;
      use Data::Query;

DESCRIPTION
    The Data::CapabilityBased module itself is, and will always be, an empty
    placeholder providing an overview of the concepts of the project and
    links to the known distributions making use of this code. Sub namespaces
    of this module will likely contain helper modules to ease bla blah
    finish this bit when we find out if we need them.

    This distribution is uploaded in the absence of code in order to
    function as a central point to document the design of the capabilities
    as we flesh them out and start building the compliance suites; please
    see the Data::Store, Data::Collection, Data::Stream, Data::Query for the
    progress made so far towards this.

MANIFESTO
    The principle behind this system is: when you're being passed something
    that's being treated as simply data, you shouldn't be thinking about
    -what- you've been passed but merely whether you can use it in the
    manner you need to. So, to pick an example I deal with every day, you
    have code that needs to process a set of objects. Think -

      method do_something ($to) {
        foreach my $target (@$to) {
          $to->frotz;
        }
      }

    Now, of course, this is great if $to is an arrayref. But otherwise
    you're in trouble. So, you think "hey, I'll add a type check:"

      method do_something ($to) {
        confess "Dammit, Jim, I'm a deckchair not an osculator"
          unless ref($to) eq 'ARRAY';
        ...

    But now what happens if it's an object that arrayifies? BOOM. (a good
    example of this from my world would be a DBIx::Class::ResultSet).

    Well. We could test it's something that arrayifies:

      method do_something ($to) {
        confess "Out of Cleese error. Call stack has Goon away."
          unless (ref($to) eq 'ARRAY' || (blessed($to) && $to->can('(@{}')));
        ...

    but for a start that's really ugly, and more importantly it only handles
    the case that we want to do @$to. Which is probably fine, except now
    we're going to slurp whatever contents of that resultset were into
    memory at once. If it contains a million records, we just made your
    computer cry (and probably your sysadmin developercidal).

    So, what's a better approach? Well, what if we could say to our data
    "hey, I know you're capable of returning me a series of objects, but I
    really just want to run something on all of them" - so, something like

      method do_something ($to) {
        $to->each(sub { $_->frotz });
      }

    but then how do we know if this is something that can provide a suitable
    each method ... and what do we do about plain arrayrefs, which don't
    have methods at all? Well, given autoboxing can provide an ->each method
    on an arrayref, we can do something like:

      use Data::Collection::Capabilities qw(Eachable);
      use Data::Collection::Autobox;

      method do_something (Eachable $to) {

    and then an arrayref will be automatically autoboxed with an ->each
    method that supports this interface, and report that it provides the
    capability, and a collection object that declares its capabilities will
    pass the type test as well.

AUTHOR
      Matt S. Trout (mst) <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/

LICENSE
    This library is free software under the same license as perl itself.