1 README for Bioperl examples/root
3 This directory contains some sample scripts and modules that
4 illustrate the use of the Bio::Root::* modules. Currently, these
5 example scripts focus on how exception handling.
7 Here are some short descriptions of the examples/root scripts:
10 -------------- ----------------------------------------
11 exceptions1.pl How to throw and catch Error.pm objects
12 exceptions2.pl How to throw Error.pm objects via Bio::Root::Root
13 exceptions3.pl Illustrates inheritance between Error.pm types
14 exceptions4.pl Shows what happens when Error.pm isn't installed
16 These demo scripts should be executed within the
17 examples/root directory of the Bioperl distribution.
20 Using Error.pm for Exception Handling
21 --------------------------------------
23 The Bio::Root::Root module interfaces with Graham Barr's Error.pm.
24 Error.pm provides a handy way to create, throw, and catch exceptions
25 as objects. Error.pm is quite convenient and easy to use and adds a
26 level of control for managing errors within your Perl code using
27 familiar object-oriented, try-catch-finally semantics. You can define
28 subclasses of Error.pm representing particular types of exceptions,
29 and you can define catch blocks to handle these types of exceptions.
31 This has distinct advantages over simply catching any and all errors
32 with an eval{} block, as is currently done in Bioperl. Strongly typed
33 exception objects make it easy to write appropriate handlers. It also
34 makes you code easier to understand because it's clear what type of
35 things can/did go wrong.
37 Throwing exceptions that are Error.pm-compliant is a little more work
38 than throwing them the usual Bioperl way. Here's an example:
40 Using Error.pm-compliant syntax:
42 if( !$feat->isa("Bio::SeqFeatureI") ) {
43 $self->throw(-class => 'Bio::Root::BadParameter',
44 -text =>"$feat is not a SeqFeatureI and that's what we expect.",
48 Not using Error.pm-compliant syntax:
50 if( !$feat->isa("Bio::SeqFeatureI") ) {
51 $self->throw("$feat is not a SeqFeatureI and that's what we expect.");
54 The advantage of using the Error.pm-compliant syntax is that, even if
55 Error.pm isn't installed, the exception message that gets thrown will
56 contain the name of the class of the exception. This provides a more
57 informative description of what went wrong.
59 In the Error.pm-compliant case above, the exception string starts with:
61 ------------- EXCEPTION: Bio::Root::BadParameter -------------
63 Compare this to the non-Error.pm-compliant exception string:
65 -------------------- EXCEPTION --------------------
67 There are a variety of exception classes that are declared in
68 Bio::Root::Exception for common types of error conditions:
71 Bio::Root::NotImplemented
72 Bio::Root::IOException
73 Bio::Root::FileOpenException
74 Bio::Root::SystemException
75 Bio::Root::BadParameter
77 Bio::Root::NoSuchThing
79 Feel free to use these, or subclass from them to derive more specific
80 classes of exceptions. For more information about these types of
81 exceptions, see perldoc Bio::Root::Exception.
83 Error.pm is available through CPAN and I encourage Bioperl users and
84 developers to install it and experiment with it.
87 Bio::Root::Exception.pm
88 -----------------------
90 The Bio::Root::Exception.pm module contains a number of Error.pm
91 subclasses representing common types of errors. If you want to throw
92 an exception within your Bioperl module that doesn't correspond to any
93 of the ones defined in Bio::Root::Exception, feel free to define a new
94 one, but be sure it inherits from Bio::Root::Exception or one of its
95 subclasses. This will allow anyone to write a handler for any type of
98 Defining a new type of exception can be done quite simply. All you
99 need to do is to specify the @ISA array for your new type, as in:
101 @Bio::Root::Exception::MyBad::ISA = qw( Bio::Root::Exception );
103 If you want to override any of the available methods or add new ones,
104 you'll have to provide a package statement and the appropriate
107 Programming tip: Be careful not to use exceptions as your primary
108 means of flow control within your code. Throwing and handling
109 exceptions come with some execution overhead. Also, such excessive use
110 of exceptions can make your logic hard to follow.
113 Bio::Root::RootI.pm and Bio::Root::Root.pm
114 -------------------------------------------
116 The modules in the lib directory also demonstrate the use of the Bioperl
117 modules Bio::Root::RootI and Bio::Root::Root. RootI.pm should be used
118 as the base class for any Bioperl module that specifies an
119 interface. It simplifies the process of writing virtual
120 methods. Root.pm implements RootI.pm should be used as a base class
121 for any Bioperl module that specifies a concrete object.
123 The module TestInterface.pm demonstrates how to use
124 Bio::Root::RootI.pm. The module TestObject.pm demonstrates how to use
127 Bio::Root::RootI defines a method called "throw_not_implemented()"
128 that will throw a Bio::Root::NotImplemented exception. This is useful
129 for ensuring that an implementing class has implemented all
130 methods. Any method within a Bio::Root::RootI subclass can call
131 throw_not_implemented() to indicate that a method has not been
132 implemented. Implementations of the interface must implement the
133 method or an exception will result when someone tries to use it.
135 Note that Bio::Root::Root can make use of Error.pm if available, but
136 Error.pm is not required.
139 Bio::Root::Root::throw() with Error.pm
140 ---------------------------------------
142 Bio::Root::Root can determine if Error.pm is available and if so, can
143 make use of it when Bio::Root::Root::throw() is called. For a demo,
150 For additional examples of how to make use of the Error.pm-related capabilities
151 of Bio::Root::Root.pm, I created new versions of Bio::SeqI.pm,
152 Bio::Seq.pm, Bio::PrimarySeqI.pm, and Bio::PrimarySeq.pm within the
153 lib/Bio subdirectory. This conversion is pretty straightforward and could
154 be done on the other Bioperl modules without too much effort.
156 TODO: Update the lib/Bio modules based on the latest versions in bioperl-live.
159 Using Error.pm's try{} and catch{} within Bioperl Modules
160 ----------------------------------------------------------
162 For developers, using Error.pm's try{} and catch{} blocks within
163 Bioperl modules themselves could come in handy. But doing so would add
164 an external dependency for Error.pm, which is not part of the standard
165 Perl distribution. So at this stage, it's best to stick with just
166 using Error.pm's throw() method (via Bio::Root::Root) and leave the
167 try{} and catch{} blocks for use only within your scripts.
169 If you really want to use try{} and catch{} within your module and
170 still want to be capable of running when Error.pm isn't available, you
171 can check $Bio::Root::Root::ERRORLOADED variable.
173 If we really want to incorporate it within Bioperl, a reasonable
174 solution would be to distribute Error.pm with Bioperl.
176 So why use Error.pm instead of some other utility? Well, Perl 6 will
177 most likely include some form of structured exception handling akin to
178 that provided by Error.pm (see these RFC's:
179 http://dev.perl.org/rfc/63.pod and http://dev.perl.org/rfc/88.pod).
180 So it will probably be easy to convert Error.pm-based exception handling
181 to whatever is adopted for Perl 6.
183 (Side note for any CORBA folks out there: Error.pm is used in some
184 other CPAN modules, notably CORBA::MICO. Thus, using Error.pm within
185 Bioperl allows consistent exception handling methodology when working
186 with such modules and Bioperl together.)
189 Steve Chervitz <sac@bioperl.org>