Beautiful Code [173]
We then create a feature collection object using BioPerl; ordinarily this will be connected to a database of some sort and initiate a query (lines 5–6), returning an iterator across the results. We then call $iterator->next_seq repeatedly to return all features that satisify the query (lines 8–16). For each returned feature, we interrogate its type using a method from Bio::SeqFeatureI called method. If the feature is of type gene, we add it to track1 and bump up a counter for genes. If the feature is of type variation, we add it to track2 and bump up a different counter.
After all features are added, we interrogate the number of genes and variations added. If the total number of either feature exceeds 100, we call the corresponding track's configure() method in order to set the bump option to false (17–18). What this achieves is to turn on collision control for tracks that contain a manageable number of features, so that overlapping features are moved up and down to avoid covering each other. Tracks with a large number of features, where collision control might create unreasonably tall tracks, have bumping set to false, so that overlapping features can be superimposed.
READING THE CODE IN THIS CHAPTER
Bio::Graphics and BioPerl are written in Perl, a language which is deceptively similar to C or Java, but has many cryptic idiosyncrasies. If you don't know Perl, don't sweat it. Just read through the code examples to get a general sense of the logic of the design. To help you understand what's going on, here's a quick summary of the quirkier parts of Perl syntax:
$variable_name
A variable name that starts with a dollar sign ($) is a scalar variable. It holds a single-valued string or number.
@variable_name
A variable name that starts with an at-sign (@) is an ordered array. It holds multiple strings or numbers, indexed by their numeric position in the array. When addressing a member of the array, one places the index in square brackets:
$foo[3] = 'element three';
There's a $ in front of the variable name because the individual element is scalar.
Within subroutine and method definitions, a special array named @_ holds the list of arguments passed to the subroutine.
%variable_name
A variable name that starts with a percent sign (%) is an unordered hash. It holds multiple strings or numbers (the hash values) indexed by strings (the hash keys). When assigning a list of key/value pairs to a hash, one uses this notation:
%clade = (monkey=>'mammal',
frog=>'amphibian',
gazelle=>'mammal');
When addressing a member of the hash, one places the key in curly braces:
print "The clade of a monkey is ", $clade{monkey};
$object->method('arg1','arg2','arg3')
The -> arrow indicates an object-oriented method call. The object is stored in the scalar variable $object. The method call takes zero or more arguments.
If there are no arguments, the parentheses can be omitted, which looks weird to C and Java folk:
$object->method;
Within the definition of a method, the object is usually stored in a scalar named $self, although this is a matter of coding style.
12.2.2. Setting Options
Up to this point I hadn't figured out how options would be set. I decided that for consistency with the BioPerl coding style, options should be passed as tag/value pairs in the format -option_name=>option_value. For example, the following method call would create a track with feature drawings 10 pixels high, a background color of blue, and collision control (bump) turned on:
$track1 = $panel_object>add_track(\@features,
-height => 10,
-bgcolor => 'blue',
-bump => 1);
Later on, one would be able to change any of these options by calling configure(). This example turns off collision control:
$track1>configure(-bump => 0);
Eventually, I extended the power of track configuration options by making it possible to use code references (a type of callback) as option values, but