Randy Stauner > Sub-Chain-Group-0.013 > Sub::Chain::Group

Download:
Sub-Chain-Group-0.013.tar.gz

Dependencies

Annotate this POD

Website

View/Report Bugs
Module Version: 0.013   Source  

NAME ^

Sub::Chain::Group - Group chains of subs by field name

VERSION ^

version 0.013

SYNOPSIS ^

  my $chain = Sub::Chain::Group->new();
  $chain->append(\&trim, fields => [qw(name address)]);

  # append other subs to this or other fields as desired...
  my $trimmed = $chain->call(address => ' 123 Street Rd. ');


  # or, using a Sub::Chain subclass:

  my $named = Sub::Chain::Group->new(
    chain_class => 'Sub::Chain::Named',
    chain_args  => { subs => {
      uc => sub { uc $_[0] },
      reverse => sub { reverse $_[0] },
    }}
  );
  $named->group(fruits => [qw(apple orange banana)]);
  $named->append('uc', groups => 'fruits');
  $named->append('reverse', fields => 'orange');

  my $fruit = $named->call({apple => 'green', orange => 'dirty'});
  # returns a hashref: {apple => 'GREEN', orange => 'YTRID'}

DESCRIPTION ^

This module provides an interface for managing multiple Sub::Chain instances for a group of fields. It is mostly useful for applying a chain of subs to a set of data (like a hash or array (like a database record)). In addition to calling different sub chains on specified fields It uses Set::DynamicGroups to allow you to build sub chains for dynamic groups of fields.

METHODS ^

new

  my $chain = Sub::Chain::Group->new(%opts);

  my $chain = Sub::Chain::Group->new(
    chain_class => 'Sub::Chain::Named',
    chain_args  => {subs => {happy => sub { ":-P" } } },
  );

Constructor; Takes a hash or hashref of options.

Possible options:

append

  $chain->append($sub, %options); # or \%options
  $chain->append(\&trim,  fields => [qw(fld1 fld2)]);
  $chain->append(\&trim,  field  => 'col3', opts => {on_undef => 'blank'});
  # or, if using Sub::Chain::Named
  $chain->append('match', groups => 'group1', args => ['pattern']);

Append a sub onto the chain for the specified fields and/or groups.

Possible options:

call

  my $values = $chain->call({key => 'value', ...});
  my $values = $chain->call([qw(fields)], [qw(values)]);
  my $value  = $chain->call('address', '123 Street Road');

Call the sub chain appropriate for each field of the supplied data.

The input (and output) can be one of the following:

chain

  $chain->chain($field);

Return the sub chain for the given field name.

dequeue

Process the queue of group and field specifications.

Queuing allows you to specify subs for a group before you specify what fields belong in that group.

This method is called when another method needs something from the chain and there are still specifications in the queue (like "chain" and "call", for instance).

fields

  $chain->fields(@fields);

Add fields to the list of all known fields. This tells the object which fields are available or expected which can be useful for specifying groups based on exclusions.

For example:

  $chain->group(some => {not => [qw(primary secondary)]});
  $chain->fields(qw(primary secondary this that));
  # the 'some' group will now contain ['this', 'that']

  $chain->fields('another');
  # the 'some' group will now contain ['this', 'that', 'another']

This is a convenience method. Arguments are passed to "add_items" in Set::DynamicGroups.

group

  $chain->group(groupname => [qw(fields)]);

Add fields to the specified group name.

This is a convenience method. Arguments are passed to "add" in Set::DynamicGroups.

groups

  my $set_dg = $chain->groups();

Return the object's instance of Set::DynamicGroups.

This can be useful if you need more advanced manipulation of the groups than is available through the "group" and "fields" methods.

new_sub_chain

This method is used internally to instantiate a new Sub::Chain using the chain_class and chain_args options.

reprocess_queue

Force the queue of chain specifications to be completely reprocessed.

This gets called automatically when groups are changed after the queue was initially processed.

HOOKS ^

In addition to building sub chains for specific fields (or groups) there are also hooks available to process the input as a whole (the hash ref or array refs passed to "call").

Specify hook => 'before' (or hook => 'after') when calling "append" (instead of specifying fields or groups) and the provided sub will be appended to a chain that will be able to modify the input record as a whole before (or after) the sub chains are called for each field.

These can modify the input by updating (or even adding new) fields:

  sub debug_hash {
    my $h = shift;
    $h->{debug} = join ':', keys %$h;
    return $h;
  }

  $chain->append(\&debug_hash, hook => 'before');

The sub should return the (modified) data structure for consistency with other chained subs.

When passing a hash ref to "call" the hash ref will be passed to the hook (as shown above).

If two array refs are passed to "call" the array ref of values will be passed to the hook as the first argument and the array ref of keys will be passed as the second argument. This is consistent with all other chained subs that receive their value as the first argument.

  $chain->call([qw(a b c), [1, 2, 3]);
  # sub will receive: ([1, 2, 3], [qw(a b c)])
  # and should return an array ref of (possibly modified) values

You can also set hook_as_hash => 1 in the constructor which will use the two input arrays to build a hash ref, pass the hash ref to any hook subs (which should return a hash ref), and in the end return an array ref of the fields of that hash ref preserving the order of the original array ref. This can be simpler to work with in the sub (and enable using the same sub regardless of the input type).

  $chain->call([qw(a b c)], [1, 2, 3]);
  # sub will receive: ({a => 1, b => 2, c => 3})
  # and should return a (possibly modified) hash ref.

If a simple string key is passed to "call" the hooks will be called with the value as the first argument and the field name as the second (similar to the way array refs are handled). The hook_as_hash option will also work here; A hashref will be passed to the hooks and ultimately return the single value.

Note: A shallow clone is performed on the ref(s) (but not a deep clone) so it's up to you to determine if modifying the structures in the hooks is acceptable or if you need to do a deep clone.

TODO ^

See "TODO" in Sub::Chain.

SEE ALSO ^

SUPPORT ^

Perldoc

You can find documentation for this module with the perldoc command.

  perldoc Sub::Chain::Group

Websites

The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources.

Bugs / Feature Requests

Please report any bugs or feature requests by email to bug-sub-chain-group at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Sub-Chain-Group. You will be automatically notified of any progress on the request by the system.

Source Code

https://github.com/rwstauner/Sub-Chain-Group

  git clone https://github.com/rwstauner/Sub-Chain-Group.git

AUTHOR ^

Randy Stauner <rwstauner@cpan.org>

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2010 by Randy Stauner.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

syntax highlighting: