AcePerl

 view release on metacpan or  search on metacpan

Ace/Object.pm  view on Meta::CPAN

  return $class eq 'date' ? $self->_to_ace_date($name) : $name;
}

# It's an object unless it is one of these things
sub _isObject {
    return unless defined $_[0];
    $_[0] !~ /^(float|int|date|tag|txt|peptide|dna|scalar|[Tt]ext|comment)$/;
}

# utility routine used to split a tag path into individual components
# allows components to contain dots.
sub _split_tags {
  my $self = shift;
  my $tag = shift;
  $tag =~ s/\\\./$;/g; # protect backslashed dots
  return map { (my $x=$_)=~s/$;/./g; $x } split(/\./,$tag);
}


1;

__END__

=head1 NAME

Ace::Object - Manipulate  Ace Data Objects

=head1 SYNOPSIS

    # open database connection and get an object
    use Ace;
    $db = Ace->connect(-host => 'beta.crbm.cnrs-mop.fr',
                       -port => 20000100);
    $sequence  = $db->fetch(Sequence => 'D12345');
    
    # Inspect the object
    $r    = $sequence->at('Visible.Overlap_Right');
    @row  = $sequence->row;
    @col  = $sequence->col;
    @tags = $sequence->tags;
    
    # Explore object substructure
    @more_tags = $sequence->at('Visible')->tags;
    @col       = $sequence->at("Visible.$more_tags[1]")->col;

    # Follow a pointer into database
    $r     = $sequence->at('Visible.Overlap_Right')->fetch;
    $next  = $r->at('Visible.Overlap_left')->fetch;

    # Classy way to do the same thing
    $r     = $sequence->Overlap_right;
    $next  = $sequence->Overlap_left;

    # Pretty-print object
    print $sequence->asString;
    print $sequence->asTabs;
    print $sequence->asHTML;

    # Update object
    $sequence->replace('Visible.Overlap_Right',$r,'M55555');
    $sequence->add('Visible.Homology','GR91198');
    $sequence->delete('Source.Clone','MBR122');
    $sequence->commit();

    # Rollback changes
    $sequence->rollback()

    # Get errors
    print $sequence->error;

=head1 DESCRIPTION

I<Ace::Object> is the base class for objects returned from ACEDB
databases. Currently there is only one type of I<Ace::Object>, but
this may change in the future to support more interesting
object-specific behaviors.

Using the I<Ace::Object> interface, you can explore the internal
structure of an I<Ace::Object>, retrieve its content, and convert it
into various types of text representation.  You can also fetch a
representation of any object as a GIF image.

If you have write access to the databases, add new data to an object,
replace existing data, or kill it entirely.  You can also create a new
object de novo and write it into the database.

For information on connecting to ACEDB databases and querying them,
see L<Ace>.

=head1 ACEDB::OBJECT METHODS

The structure of an Ace::Object is very similar to that of an Acedb
object.  It is a tree structure like this one (an Author object):

 Thierry-Mieg J->Full_name ->Jean Thierry-Mieg
                  |
                 Laboratory->FF
                  |
                 Address->Mail->CRBM duCNRS
                  |        |     |
                  |        |    BP 5051
                  |        |     |
                  |        |    34033 Montpellier
                  |        |     |
                  |        |    FRANCE
                  |        |
                  |       E_mail->mieg@kaa.cnrs-mop.fr
                  |        |
                  |       Phone ->33-67-613324
                  |        |
                  |       Fax   ->33-67-521559
                  |
                 Paper->The C. elegans sequencing project
                         |
                        Genome Project Database
                         |
                        Genome Sequencing
                         |
                         How to get ACEDB for your Sun
                         |
                        ACEDB is Hungry

Each object in the tree has two pointers, a "right" pointer to the
node on its right, and a "down" pointer to the node beneath it.  Right
pointers are used to store hierarchical relationships, such as
Address->Mail->E_mail, while down pointers are used to store lists,
such as the multiple papers written by the Author.

Each node in the tree has a type and a name.  Types include integers,
strings, text, floating point numbers, as well as specialized
biological types, such as "dna" and "peptide."  Another fundamental
type is "tag," which is a text identifier used to label portions of
the tree.  Examples of tags include "Paper" and "Laboratory" in the
example above.

In addition to these built-in types, there are constructed types known
as classes.  These types are specified by the data model.  In the
above example, "Thierry-Mieg J" is an object of the "Author" class,
and "Genome Project Database" is an object of the "Paper" class.  An
interesting feature of objects is that you can follow them into the
database, retrieving further information.  For example, after
retrieving the "Genome Project Database" Paper from the Author object,
you could fetch more information about it, either by following B<its>
right pointer, or by using one of the specialized navigation routines
described below.

=head2 new() method

    $object = new Ace::Object($class,$name,$database);
    $object = new Ace::Object(-class=>$class,
                              -name=>$name,
                              -db=>database);

You can create a new Ace::Object from scratch by calling the new()
routine with the object's class, its identifier and a handle to the
database to create it in.  The object won't actually be created in the
database until you add() one or more tags to it and commit() it (see
below).  If you do not provide a database handle, the object will be
created in memory only.

Arguments can be passed positionally, or as named parameters, as shown
above.

This routine is usually used internally.  See also add_row(),
add_tree(), delete() and replace() for ways to manipulate this object.

=head2 name() method

    $name = $object->name();

Return the name of the Ace::Object.  This happens automatically
whenever you use the object in a context that requires a string or a
number.  For example:

    $object = $db->fetch(Author,"Thierry-Mieg J");
    print "$object did not write 'Pride and Prejudice.'\n";

=head2 class() method

    $class = $object->class();

Return the class of the object.  The return value may be one of
"float," "int," "date," "tag," "txt," "dna," "peptide," and "scalar."
(The last is used internally by Perl to represent objects created
programatically prior to committing them to the database.)  The class
may also be a user-constructed type such as Sequence, Clone or
Author.  These user-constructed types usually have an initial capital
letter.

=head2 db() method

Ace/Object.pm  view on Meta::CPAN

=head2 right() and down() methods

     $subtree = $object->right;
     $subtree = $object->right($position);	
     $subtree = $object->down;
     $subtree = $object->down($position);	

B<right()> and B<down()> provide a low-level way of traversing the
tree structure by following the tree's right and down pointers.
Called without any arguments, these two methods will move one step.
Called with a numeric argument >= 0 they will move the indicated
number of steps (zero indicates no movement).

     $full_name = $object->right->right;
     $full_name = $object->right(2);

     $city = $object->right->down->down->right->right->down->down;
     $city = $object->right->down(2)->right(2)->down(2);

If $object contains the "Thierry-Mieg J" Author object, then the first
series of accesses shown above retrieves the string "Jean
Thierry-Mieg" and the second retrieves "34033 Montpellier."  If the
right or bottom pointers are NULL, these methods will return undef.

In addition to being somewhat awkard, you will probably never need to
use these methods.  A simpler way to retrieve the same information
would be to use the at() method described in the next section.  

The right() and down() methods always walk through the tree of the
current object.  They do not follow object pointers into the database.
Use B<fetch()> (or the deprecated B<pick()> or B<follow()> methods)
instead.

=head2 at() method

    $subtree    = $object->at($tag_path);
    @values     = $object->at($tag_path);

at() is a simple way to fetch the portion of the tree that you are
interested in.  It takes a single argument, a simple tag or a path.  A
simple tag, such as "Full_name", must correspond to a tag in the
column immediately to the right of the root of the tree.  A path such
as "Address.Mail" is a dot-delimited path to the subtree.  Some
examples are given below.

    ($full_name)   = $object->at('Full_name');
    @address_lines = $object->at('Address.Mail');

The second line above is equivalent to:

    @address = $object->at('Address')->at('Mail');

Called without a tag name, at() just dereferences the object,
returning whatever is to the right of it, the same as
$object->right

If a path component already has a dot in it, you may escape the dot
with a backslash, as in:

    $s=$db->fetch('Sequence','M4');
    @homologies = $s->at('Homol.DNA_homol.yk192f7\.3';

This also demonstrates that path components don't necessarily have to
be tags, although in practice they usually are.

at() returns slightly different results depending on the context in
which it is called.  In a list context, it returns the column of
values to the B<right> of the tag.  However, in a scalar context, it
returns the subtree rooted at the tag.  To appreciate the difference,
consider these two cases:

    $name1   = $object->at('Full_name');
    ($name2) = $object->at('Full_name');

After these two statements run, $name1 will be the tag object named
"Full_name", and $name2 will be the text object "Jean Thierry-Mieg",
The relationship between the two is that $name1->right leads to
$name2.  This is a powerful and useful construct, but it can be a trap
for the unwary.  If this behavior drives you crazy, use this
construct:
  
    $name1   = $object->at('Full_name')->at();

For finer control over navigation, path components can include
optional indexes to indicate navigation to the right of the current
path component.  Here is the syntax:

    $object->at('tag1[index1].tag2[index2].tag3[index3]...');

Indexes are zero-based.  An index of [0] indicates no movement
relative to the current component, and is the same as not using an
index at all.  An index of [1] navigates one step to the right, [2]
moves two steps to the right, and so on.  Using the Thierry-Mieg
object as an example again, here are the results of various indexes:

    $object = $db->fetch(Author,"Thierry-Mieg J");
    $a = $object->at('Address[0]')   --> "Address"
    $a = $object->at('Address[1]')   --> "Mail"
    $a = $object->at('Address[2]')   --> "CRBM duCNRS"

In an array context, the last index in the path does something very
interesting.  It returns the entire column of data K steps to the
right of the path, where K is the index.  This is used to implement
so-called "tag[2]" syntax, and is very useful in some circumstances.
For example, here is a fragment of code to return the Thierry-Mieg
object's full address without having to refer to each of the
intervening "Mail", "E_Mail" and "Phone" tags explicitly.

   @address = $object->at('Address[2]');
   --> ('CRBM duCNRS','BP 5051','34033 Montpellier','FRANCE',
        'mieg@kaa.cnrs-mop.fr,'33-67-613324','33-67-521559')

Similarly, "tag[3]" will return the column of data three hops to the
right of the tag.  "tag[1]" is identical to "tag" (with no index), and
will return the column of data to the immediate right.  There is no
special behavior associated with using "tag[0]" in an array context;
it will always return the subtree rooted at the indicated tag.

Internal indices such as "Homol[2].BLASTN", do not have special
behavior in an array context.  They are always treated as if they were
called in a scalar context.



( run in 0.686 second using v1.01-cache-2.11-cpan-437f7b0c052 )