Chemistry-Mok
view release on metacpan or search on metacpan
lib/Chemistry/Mok.pm view on Meta::CPAN
sub compile_blocks {
my ($self, @blocks) = @_;
my $pack = $self->{package};
my $format = $self->{pattern_format};
my @compiled_blocks;
for my $block (@blocks) {
#use Data::Dumper; print Dumper $block;
my $code = <<END;
package Chemistry::Mok::UserCode::$pack;
no strict;
no warnings;
sub {
my (\$mol, \$file, \$match, \$patt) = \@_;
my (\$MOL, \$FILE, \$MATCH, \$PATT, \$FH) = \@_;
my (\@A) = \$MATCH ? \$MATCH->atom_map : \$MOL->atoms;
my (\@B) = \$MATCH ? \$MATCH->bond_map : \$MOL->bonds;
#line $block->{line} "mok code"
$block->{block};
}
END
print "MOK: COMPILING BLOCK: <<<<$code>>>>\n\n" if $DEBUG;
my $sub = eval $code;
die "Mol: Error compiling block: $@" if $@;
my ($patt, $patt_str);
if ($block->{patt}) {
$block->{patt} =~ m#^/(.*)/$#;
$patt_str = $1;
$patt = Chemistry::Pattern->parse($patt_str,
format => $block->{pattlang} || $format);
$patt->attr(global => 1) if $block->{opts} =~ /g/;
$patt->options(overlap => 0) if $block->{opts} =~ /O/;
$patt->options(permute => 1) if $block->{opts} =~ /p/;
}
push @compiled_blocks, {'sub' => $sub,
patt => $patt, patt_str => $patt_str};
}
\@compiled_blocks;
}
=item Chemistry::Mok->new($code, %options)
Compile the code and return a Chemistry::Mok object. Available options:
=over
=item C<package>
If the C<package> option is given, the code runs in the
Chemistry::Mok::UserCode::$options{package} package instead of the
Chemistry::Mok::UserCode::Default package. Specifying a package name is
recommended if you have more than one mok object and you are using global
varaibles, in order to avoid namespace clashes.
=item C<pattern_format>
The name of the format which will be used for parsing slash-delimited patterns
that don't define an explicit format. Mok versions until 0.16 only used the
'smiles' format, but newer versions can use other formats such as 'smarts',
'midas', 'formula_pattern', and 'sln', if available. The default is 'smarts'.
=back
=cut
sub new {
my ($class, $code, @a) = @_;
my %opts;
# for backwards compatibility with Chemistry::Mok->new($code, $package)
unshift @a, "package" if (@a == 1);
%opts = @a;
my $self = bless {
'package' => $opts{package} || "Default",
pattern_format => $opts{pattern_format} || "smarts",
}, $class;
$self->setup_package;
my @toks = $self->tokenize($code);
my ($subs, $blocks) = $self->parse(@toks);
$self->compile_subs(@$subs);
$self->{blocks} = $self->compile_blocks(@$blocks);
return $self;
}
sub setup_package {
my ($self) = @_;
my $usr_pack = $self->{package};
# import convenience functions into the user's namespace
eval <<EVAL;
package Chemistry::Mok::UserCode::$usr_pack;
use Chemistry::Atom ':all';
use Chemistry::Ring ':all';
use Chemistry::Ring::Find ':all';
use Chemistry::Bond::Find ':all';
use Chemistry::Canonicalize ':all';
use Chemistry::InternalCoords::Builder ':all';
use Chemistry::Isotope ':all';
use Math::VectorReal ':all';
use Chemistry::3DBuilder ':all';
sub println { print "\@_", "\n" }
EVAL
die "Mok: error setting up 'Chemistry::Mok::UserCode::$usr_pack' $@" if $@;
}
=item $mok->run($options, @args)
Run the code on the filenames contained in @args. $options is a hash reference
with runtime options. Available options:
=over
=item build_3d
Generate 3D coordinates using Chemistry::3DBuilder.
=item aromatize
( run in 0.852 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )