Acabamos de implementar un objeto de la clase PDB usando registros y subrutinas, ahora lo
haremos usando la sintaxis propia de la programación orientada a objetos. Para ello debemos
crear un paquete
.pm
que contendrá el código de la clase. Como ejemplo os muestro la
clase PDB, contenida en el archivo PDB.pm , donde veréis que usamos la función
bless
que permite distinguir al intérprete entre referencias y objetos:
package PDB; # se incluye en otro programa con 'use PDB.pm;'
use strict;
sub PDB::constructor # en ingles este metodo suele llamarse 'new'
{
# autoreferencia a la clase y atributos como parametros
my($clase,$nombre,$n_de_cadenas,$archivoPDB) = @_;
# implementacion de atributos como una tabla asociativa
my $objeto = {
'nombre' => $nombre,
'ncadenas' => $n_de_cadenas,
'archivo' => $archivoPDB,
'coordenadas' => [],
};
# podria haber sido como un arreglo, mas eficiente, pero menos obvio el contenido
#$objeto->[0] = $nombre;
#$objeto->[1] = $n_de_cadenas;
#$objeto->[2] = $archivoPDB;
#$objeto->[3] = [];
bless($objeto,$clase); # la funcion bless da caracter de objeto a la referencia $objeto
return $objeto;
}
sub PDB::pon_nombre_archivo
{
my($objeto,$archivoPDB) = @_;
$objeto->{'archivo'} = $archivoPDB;
}
sub PDB::leer_archivoPDB
{
# autoreferencia al objeto y parametros
my($objeto, $comprimido) = @_;
# variables locales
my @coordenadas = ();
if(!$objeto->{'archivo'})
{
print "'archivo' no esta definido\n";
return 0;
}
if($comprimido == 1)
{
open(PDB,"zcat $objeto->{'archivo'} |") || warn "no puedo leer zcat $objeto->{'archivo'}\n";
}
else
{
open(PDB,"$objeto->{'archivo'}") || warn "no puedo leer $objeto->{'archivo'}\n";
}
while(<PDB>)
{
if(/^ATOM/||/^TER/)
{
push(@coordenadas,$_);
}
}
close(PDB);
$objeto->{'coordenadas'} = [ @coordenadas ];
return scalar(@coordenadas);
}
sub PDB::imprime_coordenadas
{
my($objeto) = @_;
print @{ $objeto->{'coordenadas'} };
}
1;
A continuación os muestro la clase derivada PDBdna, contenida en un archivo llamado
PDBdna.pm , que hereda de la clase PDB y sólo modifica el método
leer_archivoPDB:
package PDBdna; # se incluye en otro programa con 'use PDBdna.pm;'
use strict;
# clase derivada de PDB, especializada en representar ADN
use PDB;
use vars '@ISA';
@ISA = 'PDB';
# redefino el metodo leer_archivoPDB, para tener en cuanta solo los
# atomos de ADN
sub PDBdna::leer_archivoPDB
{
# autoreferencia al objeto y parametros
my($objeto, $comprimido) = @_;
# variables locales
my @coordenadas = ();
if(!$objeto->{'archivo'})
{
print "'archivo' no esta definida\n";
return 0;
}
if($comprimido == 1)
{
open(PDB,"zcat $objeto->{'archivo'} |") || warn "no puedo leer zcat $objeto->{'archivo'}\n";
}
else
{
open(PDB,"$objeto->{'archivo'}") || warn "no puedo leer $objeto->{'archivo'}\n";
}
while(<PDB>)
{
# lee solo atomos de ADN
if((/^ATOM/ && substr($_,18,1) eq " " && substr($_,19,1) =~ /A|G|C|T/) || /^TER/)
{
push(@coordenadas,$_);
}
}
close(PDB);
$objeto->{'coordenadas'} = [ @coordenadas ];
return scalar(@coordenadas);
}
1;
Finalmente, os muestro un ejemplo que deberéis probar donde se utilizan estas clases:
#!/usr/bin/perl -w
# Ejemplo escrito por Bruno Contreras
use strict;
use PDB; # incluye PDB.pm
use PDBdna; # incluye PDBdna.pm, en el mismo directorio
my $pdb1 = PDB->constructor('1lfu',3,'bioinfoPerl/problemas/1lfu.pdb');
$pdb1->leer_archivoPDB(0);
$pdb1->imprime_coordenadas();
Bruno Contreras-Moreira