ensembl-hive  2.7.0
Scalar.pm
Go to the documentation of this file.
1 =head1 LICENSE
2 
3 See the NOTICE file distributed with this work for additional information
4 regarding copyright ownership.
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 =cut
19 
20 package Bio::EnsEMBL::Utils::Scalar;
21 
22 =pod
23 
24 
25 =head1 CONTACT
26 
27  Please email comments or questions to the public Ensembl
28  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
29 
30  Questions may also be sent to the Ensembl help desk at
31  <http://www.ensembl.org/Help/Contact>.
32 
33 =cut
34 
35 =pod
36 
37 =head1 NAME
38 
40 
41 =head1 SYNOPSIS
42 
43  use Bio::EnsEMBL::Utils::Scalar qw(check_ref assert_ref wrap_array check_ref_can assert_ref_can assert_numeric assert_integer scope_guard);
44 
45  check_ref([], 'ARRAY'); # Will return true
46  check_ref({}, 'ARRAY'); # Will return false
47  check_ref($dba, 'Bio::EnsEMBL::DBSQL::DBAdaptor'); #Returns true if $dba is a DBAdaptor
48 
49  # Returns true if all array contents are of the given type
50  check_array_contents([$dba], 'Bio::EnsEMBL::DBSQL::DBAdaptor');
51 
52  assert_ref([], 'ARRAY'); #Returns true
53  assert_ref({}, 'ARRAY'); #throws an exception
54  assert_ref($dba, 'Bio::EnsEMBL::Gene'); #throws an exception if $dba is not a Gene
55 
56  # Throws an exception if all array contents are not of the given type
57  assert_array_contents([$dba], 'Bio::EnsEMBL::Gene'); #throws an exception if $dba is not a Gene
58 
59  wrap_array([]); #Returns the same reference
60  wrap_array($a); #Returns [$a] if $a was not an array
61  wrap_array(undef); #Returns [] since incoming was undefined
62  wrap_array(); #Returns [] since incoming was empty (therefore undefined)
63 
64  check_ref_can([], 'dbID'); #returns false as ArrayRef is not blessed
65  check_ref_can($gene, 'dbID'); #returns true as Gene should implement dbID()
66  check_ref_can(undef); #Throws an exception as we gave no method to test
67 
68  assert_ref_can([], 'dbID'); #throws an exception since ArrayRef is not blessed
69  assert_ref_can($gene, 'dbID'); #returns true if gene implements dbID()
70  assert_ref_can(undef); #Throws an exception as we gave no method to test
71 
72  asssert_integer(1, 'dbID'); #Passes
73  asssert_integer(1.1, 'dbID'); #Fails
74  asssert_numeric(1E-11, 'dbID'); #Passes
75  asssert_numeric({}, 'dbID'); #Fails
76 
77  #Scope guards
78  my $v = 'wibble';
79  {
80  #Build a guard to reset $v to wibble
81  my $guard = scope_guard(sub { $v = 'wibble'});
82  $v = 'wobble';
83  warn $v; # prints wobble
84  }
85  # $guard is out of scope; sub is triggered and $v is reset
86  warn $v; # prints wibble
87 
88  #Tags are also available for exporting
89  use Bio::EnsEMBL::Utils::Scalar qw(:assert); # brings in all assert methods
90  use Bio::EnsEMBL::Utils::Scalar qw(:check); #brings in all check methods
91  use Bio::EnsEMBL::Utils::Scalar qw(:array); #brings in wrap_array
92  use Bio::EnsEMBL::Utils::Scalar qw(:all); #import all methods
93 
94 =head1 DESCRIPTION
95 
96 A collection of subroutines aimed to helping Scalar based operations
97 
98 =head1 METHODS
99 
100 See subroutines.
101 
102 =head1 MAINTAINER
103 
104 $Author$
105 
106 =head1 VERSION
107 
108 $Revision$
109 
110 =cut
111 
112 use strict;
113 use warnings;
114 
115 #
116 # Interface with some of the module function XS reimplementation
117 #
118 # If Bio::EnsEMBL::XS is installed, assign the function glob to
119 # the XS counterpart, otherwise assign to the original function
120 #
121 BEGIN {
122 
123  if (eval { require Bio::EnsEMBL::XS; 1 }) {
124  *check_ref = \&Bio::EnsEMBL::XS::Utils::Scalar::check_ref;
125  *assert_ref = \&Bio::EnsEMBL::XS::Utils::Scalar::assert_ref;
126  # *assert_numeric = \&Bio::EnsEMBL::XS::Utils::Scalar::assert_numeric;
127  # *assert_integer = \&Bio::EnsEMBL::XS::Utils::Scalar::assert_integer;
128  } else {
129  *check_ref = \&check_ref_pp;
130  *assert_ref = \&assert_ref_pp;
131  # *assert_numeric = \&assert_numeric_pp;
132  # *assert_integer = \&assert_integer_pp;
133 
134  }
135 
136  *assert_numeric = \&assert_numeric_pp;
137  *assert_integer = \&assert_integer_pp;
138 }
139 
140 
141 use base qw(Exporter);
142 
143 our %EXPORT_TAGS;
144 our @EXPORT_OK;
145 
146 @EXPORT_OK = qw(
147  check_ref check_ref_can check_array_contents check_hash_contents
148  assert_ref assert_ref_can assert_numeric assert_integer assert_boolean assert_strand assert_file_handle assert_array_contents assert_hash_contents
149  wrap_array
150  scope_guard
151  split_array
152 );
153 %EXPORT_TAGS = (
154  assert => [qw(assert_ref assert_ref_can assert_integer assert_numeric assert_boolean assert_strand assert_file_handle assert_array_contents assert_hash_contents)],
155  check => [qw(check_ref check_ref_can check_array_contents check_hash_contents)],
156  array => [qw/wrap_array split_array/],
157  all => [@EXPORT_OK]
158 );
159 
160 use Bio::EnsEMBL::Utils::Exception qw(throw);
161 use Scalar::Util qw(blessed looks_like_number openhandle);
162 
163 our $ASSERTIONS = 1;
164 
165 =head2 check_ref_pp()
166 
167  Arg [1] : The reference to check
168  Arg [2] : The type we expect
169  Description : A subroutine which checks to see if the given object/ref is
170  what you expect. If you give it a blessed reference then it
171  will perform an isa() call on the object after the defined
172  tests. If it is a plain reference then it will use ref().
173 
174  An undefined value will return a false.
175  Returntype : Boolean indicating if the reference was the type we
176  expect
177  Example : my $ok = check_ref([], 'ARRAY');
178  Exceptions : If the expected type was not set
179  Status : Stable
180 
181 =cut
182 
183 sub check_ref_pp {
184  my ($ref, $expected) = @_;
185  throw('No expected type given') if ! defined $expected;
186  if(defined $ref) {
187  if(blessed($ref)) {
188  return 1 if $ref->isa($expected);
189  }
190  else {
191  my $ref_ref_type = ref($ref);
192  return 1 if defined $ref_ref_type && $ref_ref_type eq $expected;
193  }
194  }
195  return 0;
196 }
197 
198 =head2 assert_ref_pp()
199 
200  Arg [1] : The reference to check
201  Arg [2] : The type we expect
202  Arg [3] : The attribute name you are asserting; not required but allows
203  for more useful error messages to be generated. Defaults to
204  C<-Unknown->.
205  Description : A subroutine which checks to see if the given object/ref is
206  what you expect. This behaves in an identical manner as
207  C<check_ref()> does except this will raise exceptions when
208  the values do not match rather than returning a boolean
209  indicating the situation.
210 
211  Undefs cause exception circumstances.
212 
213  You can turn assertions off by using the global variable
214  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
215  Returntype : Boolean; true if we managed to get to the return
216  Example : assert_ref([], 'ARRAY');
217  Exceptions : If the expected type was not set and if the given reference
218  was not assignable to the expected value
219  Status : Stable
220 
221 =cut
222 
223 sub assert_ref_pp {
224  my ($ref, $expected, $attribute_name) = @_;
225  return 1 unless $ASSERTIONS;
226  $attribute_name ||= '-Unknown-';
227  throw('No expected type given') if ! defined $expected;
228  my $class = ref($ref);
229  throw("The given reference for attribute $attribute_name was undef. Expected '$expected'") unless defined $ref;
230  throw("Asking for the type of the attribute $attribute_name produced no type; check it is a reference. Expected '$expected'") unless $class;
231  if(blessed($ref)) {
232  throw("${attribute_name}'s type '${class}' is not an ISA of '${expected}'") if ! $ref->isa($expected);
233  }
234  else {
235  throw("$attribute_name was expected to be '${expected}' but was '${class}'") if $expected ne $class;
236  }
237  return 1;
238 }
239 
240 =head2 assert_array_contents
241 
242  Arg [1] : ArrayRef references to check
243  Arg [2] : The type we expect
244  Arg [3] : The attribute name you are asserting; not required but allows
245  for more useful error messages to be generated. Defaults to
246  C<-Unknown->.
247  Description : A subroutine which checks to see if the given objects/refs are
248  what you expect. This behaves in an identical manner as
249  C<assert_ref> does works on an array ref of references
250 
251  You can turn assertions off by using the global variable
252  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
253  Returntype : Boolean; true if we managed to get to the return
254  Example : assert_array_contents([[],[],[]], 'ARRAY');
255  Exceptions : Throws is references argument is not an ArrayRef, also
256  if the expected type was not set and if the given reference
257  was not assignable to the expected value.
258  Status : Stable
259 
260 =cut
261 
262 sub assert_array_contents {
263  my ($array, $expected, $attribute_name) = @_;
264  return 1 unless $ASSERTIONS;
265  throw('No expected type given') if ! defined $expected;
266  $attribute_name ||= '-Unknown-';
267  assert_ref($array, 'ARRAY', $attribute_name);
268  my $count = scalar(@{$array});
269  for(my $i = 0; $i<$count; $i++) {
270  my $ref = $array->[$i];
271  my $class = ref($ref);
272  throw("The given reference for attribute $attribute_name was undef (at position ${i}). Expected '$expected'") unless defined $ref;
273  throw("Asking for the type of the attribute $attribute_name produced no type; check it is a reference (at position ${i}). Expected '$expected'") unless $class;
274  if(blessed($ref)) {
275  throw("${attribute_name}'s type '${class}' is not an ISA of '${expected}' (at position ${i})") if ! $ref->isa($expected);
276  }
277  else {
278  throw("$attribute_name was expected to be '${expected}' but was '${class}' (at position ${i})") if $expected ne $class;
279  }
280  }
281  return 1;
282 }
283 
284 =head2 check_array_contents
285 
286  Arg [1] : ArrayRef references to check
287  Arg [2] : The type we expect
288  Arg [3] : The attribute name you are asserting; not required but allows
289  for more useful error messages to be generated. Defaults to
290  C<-Unknown->.
291  Description : A subroutine which checks to see if the given objects/refs are
292  what you expect.
293  Returntype : Boolean; true if all contents were as expected
294  Example : check_array_contents([[],[],[]], 'ARRAY');
295  Exceptions : Thrown if no type was given
296  Status : Stable
297 
298 =cut
299 
300 sub check_array_contents {
301  my ($array, $expected, $attribute_name) = @_;
302  return 0 if ! check_ref($array, 'ARRAY');
303  throw('No expected type given') if ! defined $expected;
304  my $contents_ok = 1;
305  my $count = scalar(@{$array});
306  for(my $i = 0; $i<$count; $i++) {
307  my $ref = $array->[$i];
308  if(!$ref) {
309  $contents_ok = 0;
310  last;
311  }
312  my $class = ref($ref);
313  if(!$class) {
314  $contents_ok = 0;
315  last;
316  }
317  if(blessed($ref)) {
318  if(! $ref->isa($expected)) {
319  $contents_ok = 0;
320  last;
321  }
322  }
323  elsif($expected ne $class) {
324  $contents_ok = 0;
325  last;
326  }
327  }
328  return $contents_ok;
329 }
330 
331 =head2 assert_hash_contents
332 
333  Arg [1] : HashRef references to check
334  Arg [2] : The type we expect
335  Arg [3] : The attribute name you are asserting; not required but allows
336  for more useful error messages to be generated. Defaults to
337  C<-Unknown->.
338  Description : A subroutine which checks to see if the given objects/refs are
339  what you expect. This behaves in an identical manner as
340  C<assert_ref> does works on a HashRef of references. Hash keys
341  are always Strings so do not need asserting.
342 
343  You can turn assertions off by using the global variable
344  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
345  Returntype : Boolean; true if we managed to get to the return
346  Example : assert_hash_contents({a => [], b => []}, 'ARRAY');
347  Exceptions : Throws is references argument is not an ArrayRef, also
348  if the expected type was not set and if the given reference
349  was not assignable to the expected value.
350  Status : Stable
351 
352 =cut
353 
354 sub assert_hash_contents {
355  my ($hash, $expected, $attribute_name) = @_;
356  return 1 unless $ASSERTIONS;
357  throw('No expected type given') if ! defined $expected;
358  $attribute_name ||= '-Unknown-';
359  assert_ref($hash, 'HASH', $attribute_name);
360  my @keys = keys %{$hash};
361  while(my $key = shift @keys) {
362  my $ref = $hash->{$key};
363  my $class = ref($ref);
364  throw("The given reference for attribute $attribute_name was undef (with key ${key}). Expected '$expected'") unless defined $ref;
365  throw("Asking for the type of the attribute $attribute_name produced no type; check it is a reference (with key ${key}). Expected '$expected'") unless $class;
366  if(blessed($ref)) {
367  throw("${attribute_name}'s type '${class}' is not an ISA of '${expected}' (with key ${key})") if ! $ref->isa($expected);
368  }
369  else {
370  throw("$attribute_name was expected to be '${expected}' but was '${class}' (with key ${key})") if $expected ne $class;
371  }
372  }
373  return 1;
374 }
375 
376 =head2 check_hash_contents
377 
378  Arg [1] : HashRef references to check
379  Arg [2] : The type we expect
380  Arg [3] : The attribute name you are asserting; not required but allows
381  for more useful error messages to be generated. Defaults to
382  C<-Unknown->.
383  Description : A subroutine which checks to see if the given objects/refs are
384  what you expect.
385  Returntype : Boolean; true if all contents were as expected
386  Example : check_hash_contents({a => [], b => []}, 'ARRAY');
387  Exceptions : Thrown if no type was given
388  Status : Stable
389 
390 =cut
391 
392 sub check_hash_contents {
393  my ($hash, $expected, $attribute_name) = @_;
394  throw('No expected type given') if ! defined $expected;
395  return 0 if ! check_ref($hash, 'HASH');
396  my $contents_ok = 1;
397  my @keys = keys %{$hash};
398  while(my $key = shift @keys) {
399  my $ref = $hash->{$key};
400  if(!$ref) {
401  $contents_ok = 0;
402  last;
403  }
404  my $class = ref($ref);
405  if(!$class) {
406  $contents_ok = 0;
407  last;
408  }
409  if(blessed($ref)) {
410  if(! $ref->isa($expected)) {
411  $contents_ok = 0;
412  last;
413  }
414  }
415  elsif($expected ne $class) {
416  $contents_ok = 0;
417  last;
418  }
419  }
420  return $contents_ok;
421 }
422 
423 =head2 wrap_array()
424 
425  Arg : The reference we want to wrap in an array
426  Description : Takes in a reference and returns either the reference if it
427  was already an array, the reference wrapped in an array or
428  an empty array (if the given value was undefined).
429  Returntype : Array Reference
430  Example : my $a = wrap_array($input);
431  Exceptions : None
432  Status : Stable
433 
434 =cut
435 
436 sub wrap_array {
437  my ($incoming_reference) = @_;
438  if(defined $incoming_reference) {
439  if(check_ref($incoming_reference, 'ARRAY')) {
440  return $incoming_reference;
441  }
442  else {
443  return [$incoming_reference];
444  }
445  }
446  return [];
447 }
448 
449 =head2 check_ref_can
450 
451  Arg [1] : The reference to check
452  Arg [2] : The method we expect to run
453  Description : A subroutine which checks to see if the given object/ref is
454  implements the given method. This is very similar to the
455  functionality given by C<UNIVERSAL::can()> but works
456  by executing C<can()> on the object meaning we consult the
457  object's potentially overriden version rather than Perl's
458  default mechanism.
459  Returntype : CodeRef
460  Example : check_ref_can($gene, 'dbID');
461  Exceptions : If the expected type was not set.
462  Status : Stable
463 
464 =cut
465 
466 sub check_ref_can {
467  my ($ref, $method) = @_;
468  throw('No method given') if ! defined $method;
469  return unless defined $ref && blessed($ref);
470  return $ref->can($method);
471 }
472 
473 =head2 assert_ref_can
474 
475  Arg [1] : The reference to check
476  Arg [2] : The method we expect to run
477  Arg [3] : The attribute name you are asserting; not required but allows
478  for more useful error messages to be generated. Defaults to
479  C<-Unknown->.
480  Description : A subroutine which checks to see if the given object/ref is
481  implements the given method. Will throw exceptions.
482 
483  You can turn assertions off by using the global variable
484  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
485  Returntype : Boolean; true if we managed to get to the return
486  Example : assert_ref_can($gene, 'dbID');
487  Exceptions : If the reference is not defined, if the object does not
488  implement the given method and if no method was given to check
489  Status : Stable
490 
491 =cut
492 
493 sub assert_ref_can {
494  my ($ref, $method, $attribute_name) = @_;
495  return 1 unless $ASSERTIONS;
496  $attribute_name ||= '-Unknown-';
497  throw('No method given') if ! defined $method;
498  throw "The given reference $attribute_name is not defined. Expected method '$method'" unless defined $ref;
499  throw "The given reference $attribute_name is not blessed. Expected method '$method'" unless blessed($ref);
500  if(! $ref->can($method)) {
501  my $str_ref = ref($ref);
502  throw sprintf(q{The given blessed reference '%s' for attribute '%s' does not implement the method '%s'}, $str_ref, $attribute_name, $method);
503  }
504  return 1;
505 }
506 
507 =head2 assert_numeric_pp
508 
509  Arg [1] : The Scalar to check
510  Arg [2] : The attribute name you are asserting; not required but allows
511  for more useful error messages to be generated. Defaults to
512  C<-Unknown->.
513  Description : A subroutine which checks to see if the given scalar is
514  number or not. If not then we raise exceptions detailing why
515 
516  You can turn assertions off by using the global variable
517  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
518  Returntype : Boolean; true if we had a numeric otherwise we signal failure
519  via exceptions
520  Example : assert_numeric(1, 'dbID');
521  Exceptions : If the Scalar is not defined, if the Scalar was blessed and
522  if the value was not a number
523  Status : Stable
524 
525 =cut
526 
527 sub assert_numeric_pp {
528  my ($integer, $attribute_name) = @_;
529  return 1 unless $ASSERTIONS;
530  $attribute_name ||= '-Unknown-';
531  throw "$attribute_name attribute is undefined. Expected a number" if ! defined $integer;
532  throw "The given attribute $attribute_name is blessed; cannot work with blessed values. Expected a number" if blessed($integer);
533  if(! looks_like_number($integer)) {
534  throw "Attribute $attribute_name was not a number";
535  }
536  return 1;
537 }
538 
539 =head2 assert_integer_pp
540 
541  Arg [1] : The Scalar to check
542  Arg [2] : The attribute name you are asserting; not required but allows
543  for more useful error messages to be generated. Defaults to
544  C<-Unknown->.
545  Description : A subroutine which checks to see if the given scalar is
546  a whole integer; we delegate to L<assert_numeric> for number
547  checking.
548 
549  You can turn assertions off by using the global variable
550  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
551  Returntype : Boolean; true if we had a numeric otherwise we signal failure
552  via exceptions
553  Example : assert_integer(1, 'dbID');
554  Exceptions : See L<assert_numeric> and we raise exceptions if the value
555  was not a whole integer
556  Status : Stable
557 
558 =cut
559 
560 sub assert_integer_pp {
561  my ($integer, $attribute_name) = @_;
562  return 1 unless $ASSERTIONS;
563  $attribute_name ||= '-Unknown-';
564  throw "$attribute_name attribute is undefined. Expected an Integer" if ! defined $integer;
565  throw "The given attribute $attribute_name is blessed; cannot work with blessed values. Expected an Integer" if blessed($integer);
566  if(! looks_like_number($integer)) {
567  throw "Attribute $attribute_name was not a number. Expected an Integer";
568  }
569  if($integer != int($integer)) {
570  throw "Attribute $attribute_name was a number but not an Integer";
571  }
572  return 1;
573 }
574 
575 =head2 assert_boolean
576 
577  Arg [1] : The Scalar to check
578  Arg [2] : The attribute name you are asserting; not required but allows
579  for more useful error messages to be generated. Defaults to
580  C<-Unknown->.
581  Description : A subroutine which checks to see if the given scalar is
582  a boolean i.e. value is set to C<1> or C<0>
583 
584  You can turn assertions off by using the global variable
585  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
586  Returntype : Boolean; true if we were given a boolean otherwise we signal
587  failure via exceptions
588  Example : assert_boolean(1, 'is_circular');
589  Exceptions : See L<assert_integer> and we raise exceptions if the value
590  was not equal to the 2 valid states
591  Status : Stable
592 
593 =cut
594 
595 sub assert_boolean {
596  my ($boolean, $attribute_name) = @_;
597  return 1 unless $ASSERTIONS;
598  $attribute_name ||= '-Unknown-';
599  throw "$attribute_name attribute is undefined. Expected a boolean" if ! defined $boolean;
600  throw "The given attribute $attribute_name is blessed; cannot work with blessed values. Expected an Integer" if blessed($boolean);
601  if(! looks_like_number($boolean)) {
602  throw "Attribute $attribute_name was not a number. Expected a boolean";
603  }
604  if($boolean != 0 && $boolean != 1) {
605  throw "Attribute $attribute_name was an invalid boolean. Expected: 1 or 0. Got: $boolean";
606  }
607  return 1;
608 }
609 
610 =head2 assert_strand
611 
612  Arg [1] : The Scalar to check
613  Arg [2] : The attribute name you are asserting; not required but allows
614  for more useful error messages to be generated. Defaults to
615  C<-Unknown->.
616  Description : A subroutine which checks to see if the given scalar is
617  a whole integer and if the value is set to C<1>, C<0> or C<-1>
618 
619  You can turn assertions off by using the global variable
620  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
621  Returntype : Boolean; true if we had a strand integer otherwise we signal
622  failure via exceptions
623  Example : assert_strand(1, 'strand');
624  Exceptions : See L<assert_integer> and we raise exceptions if the value
625  was not equal to the 3 valid states
626  Status : Stable
627 
628 =cut
629 
630 sub assert_strand {
631  my ($strand, $attribute_name) = @_;
632  return 1 unless $ASSERTIONS;
633  $attribute_name ||= '-Unknown-';
634  throw "$attribute_name attribute is undefined. Expected: 1, 0 or -1" if ! defined $strand;
635  throw "The given attribute $attribute_name is blessed; cannot work with blessed values. Expected: 1, 0 or -1" if blessed($strand);
636  if(! looks_like_number($strand)) {
637  throw "Attribute $attribute_name was not a number. Expected: 1, 0 or -1";
638  }
639  if($strand != -1 && $strand != 0 && $strand ne 1) {
640  throw "Attribute $attribute_name was an invalid strand. Expected: 1, 0 or -1. Got: $strand";
641  }
642  return 1;
643 }
644 
645 
646 =head2 assert_file_handle
647 
648  Arg [1] : The Scalar to check
649  Arg [2] : The attribute name you are asserting; not required but allows
650  for more useful error messages to be generated. Defaults to
651  C<-Unknown->.
652  Description : A subroutine which checks to see if the given scalar is
653  actually a file handle. This will handle those which are Glob
654  references and those which inherit from C<IO::Handle>. It will
655  also cope with a blessed Glob reference.
656 
657  You can turn assertions off by using the global variable
658  $Bio::EnsEMBL::Utils::Scalar::ASSERTIONS = 0
659  Returntype : Boolean;
660  Example : assert_file_handle($fh, '-FILE_HANDLE');
661  Exceptions : Raised if not defined, not a reference and was not a
662  GLOB or did not inherit from IO::Handle
663  Status : Stable
664 
665 =cut
666 
667 sub assert_file_handle {
668  my ($file_handle, $attribute_name) = @_;
669  return 1 unless $ASSERTIONS;
670  $attribute_name ||= '-Unknown-';
671  throw "Attribute $attribute_name was undefined. Expected a FileHandle" if ! defined $file_handle;
672  my $ref = ref($file_handle);
673  throw "Attribute $attribute_name was not a reference. Got: $file_handle. Expected a FileHandle" if ! $ref;
674  if(!openhandle($file_handle)) {
675  if(blessed($file_handle)) {
676  if(! $file_handle->isa('IO::Handle')) {
677  throw "Attribute $attribute_name was blessed but did not inherit from IO::Handle. Ref was: $ref";
678  }
679  }
680  else {
681  throw "Attribute $attribute_name was not a file handle. Ref was: $ref";
682  }
683  }
684  return 1;
685 }
686 
687 =head2 split_array
688 
689  Arg [1] : Integer Maximum size of an array produced
690  Arg [2] : ArrayRef The array to split
691  Description : Takes an array of values and splits the array into multiple
692  arrays where the maximum size of each array is as specified
693  Example : my $split_arrays = split_array($large_array, 10);
694  Returntype : ArrayRef of ArrayRefs where each element is a split list
695 =cut
696 
697 sub split_array {
698  my ($amount, $array) = @_;
699  assert_ref($array, 'ARRAY', 'array');
700  my @split;
701  my $counter = 0;
702  my $index = 0;
703  foreach my $e (@$array) {
704  if($counter == $amount) {
705  $index++;
706  $counter = 0;
707  }
708  push(@{$split[$index]}, $e);
709  $counter++;
710  }
711  return \@split;
712 }
713 
714 =head2 scope_guard
715 
716  Arg [1] : CodeRef The block of code to exit once it escapes out of scope
717  Description : Simple subroutine which blesses your given code reference into
718  a L<Bio::EnsEMBL::Utils::Scalar::ScopeGuard> object. This has
719  a DESTROY implemented which will cause the code reference
720  to execute once the object goes out of scope and its reference
721  count hits 0.
722  Returntype : Bio::EnsEMBL::Utils::Scalar::ScopeGuard
723  Example : my $v = 'wibble';
724  {
725  #Build a guard to reset $v to wibble
726  my $guard = scope_guard(sub { $v = 'wibble'});
727  $v = 'wobble';
728  warn $v;
729  }
730  # $guard is out of scope; sub is triggered and $v is reset
731  warn $v;
732  Exceptions : Raised if argument was not a CodeRef
733  Status : Stable
734 
735 =cut
736 
737 sub scope_guard {
738  my ($callback) = @_;
739  assert_ref($callback, 'CODE', 'callback');
740  return bless($callback, 'Bio::EnsEMBL::Utils::Scalar::ScopeGuard');
741 }
742 
743 1;
744 
745 #### SUPER SECRET PACKAGE. IGNORE ME
746 package Bio::EnsEMBL::Utils::Scalar::ScopeGuard;
747 sub DESTROY {
748  my ($self) = @_;
749  $self->();
750  return;
751 }
752 
753 1;
EnsEMBL
Definition: Filter.pm:1
Bio::EnsEMBL::Utils::Scalar
Definition: Scalar.pm:66
BEGIN
public BEGIN()
run
public run()
Bio::EnsEMBL::Utils::Exception
Definition: Exception.pm:68