File Coverage

blib/lib/Math/Matlab/Local.pm
Criterion Covered Total %
statement 19 97 19.5
branch 4 42 9.5
condition 0 9 0.0
subroutine 7 20 35.0
pod 8 8 100.0
total 38 176 21.5


line stmt bran cond sub pod time code
1             package Math::Matlab::Local;
2              
3 2     2   30786 use strict;
  2         5  
  2         100  
4 2     2   11 use vars qw($VERSION $ROOT_MWD $CMD);
  2         4  
  2         214  
5              
6             BEGIN {
7 2     2   64 $VERSION = sprintf "%d.%03d", q$Revision: 1.8 $ =~ /: (\d+)\.(\d+)/;
8             }
9              
10 2     2   600 use Math::Matlab;
  2         5  
  2         75  
11 2     2   11 use base qw( Math::Matlab );
  2         5  
  2         223  
12              
13 2     2   14 use Cwd qw( getcwd abs_path );
  2         5  
  2         3297  
14              
15             ##----- assign defaults, unless already set externally -----
16             $CMD = 'matlab -nodisplay -nojvm' unless defined $CMD;
17             $ROOT_MWD = getcwd unless defined $ROOT_MWD;
18              
19             ##----- Public Class Methods -----
20             sub new {
21 4     4 1 1402 my ($class, $href) = @_;
22 4 100       45 my $self = {
    100          
23             cmd => defined($href->{cmd}) ? $href->{cmd} : $CMD,
24             root_mwd => defined($href->{root_mwd}) ? $href->{root_mwd} : $ROOT_MWD,
25             err_msg => '',
26             result => '',
27             wrapper_fn => '',
28             script_fn => '',
29             output_fn => '',
30             generated_script => undef,
31             };
32              
33 4         21 bless $self, $class;
34             }
35              
36             ##----- Public Object Methods -----
37             sub execute {
38 0     0 1   my ($self, $code, $rel_mwd, $script_fn) = @_;
39 0           my $success = 0;
40 0           my ($cwd, $cmd);
41            
42             ## clear err_msg
43 0           $self->clear_err_msg;
44            
45             ## save current directory and change to Matlab working directory
46 0 0 0       $cwd = getcwd if $self->root_mwd or $rel_mwd;
47 0 0         if ($self->root_mwd) {
48 0 0         chdir $self->root_mwd or die("Couldn't chdir to '@{[ $self->root_mwd ]}'");
  0            
49             }
50 0 0         if ($rel_mwd) {
51 0           my $mwd = abs_path( $rel_mwd );
52 0 0         chdir $mwd or die("Couldn't chdir to '$mwd'");
53             }
54            
55             ## create input files
56 0           $self->_create_input_files($code, $script_fn);
57              
58             ## set up command to fire off Matlab with the input file
59 0           $cmd = sprintf('%s -r %s -logfile %s',
60             $self->cmd, substr($self->wrapper_fn, 0, -2), $self->output_fn);
61              
62             ## run it
63 0           my $err = `$cmd 2>&1`;
64 0 0         if (open(Matlab::IO, $self->output_fn)) {
65 0           $self->{'result'} = join('', );
66 0           close(Matlab::IO);
67 0 0         if ($self->{'result'} =~ /-----MATLAB-BEGIN-----\n-----SUCCESS/) {
    0          
68 0           $success = 1;
69 0           $self->remove_files;
70             } elsif ($self->{'result'} =~ /-----MATLAB-BEGIN-----\n-----ERROR/) {
71             ## runtime error
72 0           $self->err_msg(
73             sprintf("MATLAB RUNTIME ERROR\n[%s] in [%s] returned:\n%s",
74             $cmd, getcwd, $self->{'result'} )
75             );
76             } else {
77             ## couldn't execute Matlab code (compile err, license err)
78 0           $self->err_msg(
79             sprintf("MATLAB INITIALIZATION ERROR\n[%s] in [%s] returned:\n%s",
80             $cmd, getcwd, $self->{'result'} )
81             );
82             }
83             } else {
84             ## couldn't launch Matlab (no output file created)
85 0           $self->err_msg(
86             sprintf("MATLAB LAUNCH FAILURE\n[%s] in [%s] returned:\n%s",
87             $cmd, getcwd, $err )
88             );
89             }
90              
91             ## restore current working directory
92 0 0         if ($cwd) {
93 0 0         chdir $cwd or die("Couldn't chdir to '$cwd'");
94             }
95              
96 0           return $success;
97             }
98              
99 0     0 1   sub cmd { my $self = shift; return $self->_getset('cmd', @_); }
  0            
100 0     0 1   sub root_mwd { my $self = shift; return $self->_getset('root_mwd', @_); }
  0            
101 0     0 1   sub wrapper_fn { my $self = shift; return $self->_getset('wrapper_fn', @_); }
  0            
102 0     0 1   sub script_fn { my $self = shift; return $self->_getset('script_fn', @_); }
  0            
103 0     0 1   sub output_fn { my $self = shift; return $self->_getset('output_fn', @_); }
  0            
104              
105             sub remove_files {
106 0     0 1   my ($self) = @_;
107              
108 0 0 0       unlink $self->script_fn if $self->{generated_script} && -f $self->script_fn;
109 0 0         unlink $self->wrapper_fn if -f $self->wrapper_fn;
110 0 0         unlink $self->output_fn if -f $self->output_fn;
111 0           $self->{script_fn} = '';
112 0           $self->{wrapper_fn} = '';
113 0           $self->{output_fn} = '';
114             }
115              
116             sub _create_input_files {
117 0     0     my ($self, $code, $script_fn) = @_;
118              
119             ## set script file name
120 0 0         if (defined($script_fn)) { ## name given
121 0 0         if (-f $script_fn) {
122 0 0         if ($code) {
123 0           $self->{generated_script} = undef;
124 0           die("File '$script_fn' already exists");
125             } else {
126 0           $self->{generated_script} = 0;
127             }
128             }
129             } else { ## generate random name
130 0   0       while (!defined($script_fn) or -f $script_fn ) {
131 0           $script_fn = 'mm'.(int rand 10000000).'.m'; ## generate random file name
132             }
133 0           $self->{generated_script} = 1;
134             }
135              
136             ## create script
137 0           $self->script_fn( $script_fn );
138 0 0         if ($self->{generated_script}) {
139 0           $self->_create_script_file( $code );
140             }
141              
142             ## create command wrapper
143 0           $self->_set_wrapper_fn;
144 0           $self->_create_wrapper_file;
145              
146             ## set output file name
147 0           $self->_set_output_fn;
148              
149 0           return 1;
150             }
151              
152             ## Private class methods
153 0     0     sub _gen_script_name { return 'mm'.(int rand 10000000).'.m'; }
154              
155             ## Private object methods
156             sub _set_wrapper_fn {
157 0     0     my ($self) = @_;
158 0           return $self->wrapper_fn( substr($self->script_fn, 0, -2).'_wrap.m' );
159             }
160             sub _set_output_fn {
161 0     0     my ($self) = @_;
162 0           return $self->output_fn( substr($self->script_fn, 0, -2).'_out.txt' );
163             }
164              
165             sub _create_script_file {
166 0     0     my ($self, $code) = @_;
167            
168 0           my $fn = $self->script_fn;
169 0 0         open(Matlab::IO, ">$fn") || die "Couldn't open '$fn'";
170 0           print Matlab::IO $code;
171 0           close(Matlab::IO);
172              
173 0           return 1;
174             }
175              
176             sub _create_wrapper_file {
177 0     0     my ($self) = @_;
178            
179 0           my $fn = $self->wrapper_fn;
180 0 0         open(Matlab::IO, ">$fn") || die "Couldn't open '$fn'";
181 0           print Matlab::IO <
182             fprintf('-----MATLAB-BEGIN-----\\n');
183             try
184 0           rv = evalc('@{[ substr($self->script_fn, 0, -2) ]}');
185             fprintf('-----SUCCESS\\n\%s', rv);
186             catch
187             fprintf('-----ERROR\\n\%s\\n\%s', lasterr);
188             end
189             quit;
190             END_OF_CODE
191 0           close(Matlab::IO);
192              
193 0           return 1;
194             }
195              
196              
197              
198             1;
199             __END__