Skip to content

Commit

Permalink
rename capture -> dt_capture, method_capture -> dt_method_capture
Browse files Browse the repository at this point in the history
  • Loading branch information
jrfiedler committed Mar 27, 2014
1 parent 0d4a31b commit 476f887
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 51 deletions.
52 changes: 26 additions & 26 deletions capture.mata → dt_capture.mata
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
mata
class Capture {
class dt_Capture {
pointer(function) scalar func_ptr
pointer matrix arg_ptrs
pointer scalar rv_ptr
}
capture = Capture()
dt_capture = dt_Capture()
real scalar capture(pointer(function) scalar func_ptr,
pointer matrix arg_ptrs,
| pointer scalar rv_ptr)
real scalar dt_capture(pointer(function) scalar func_ptr,
pointer matrix arg_ptrs,
| pointer scalar rv_ptr)
{
real scalar rc, i, nargs
string scalar run_str, arg_template
external class Capture scalar capture
external class dt_Capture scalar dt_capture
// It seems that any errors in pointer arguments get captured
// by the Stata capture below. So, test them here.
Expand Down Expand Up @@ -43,17 +43,17 @@ mata
exit(_error(3257, "2nd arg should be a vector of pointers"))
}
capture.func_ptr = func_ptr
capture.arg_ptrs = arg_ptrs
dt_capture.func_ptr = func_ptr
dt_capture.arg_ptrs = arg_ptrs
if (args() == 3) {
capture.rv_ptr = rv_ptr
run_str = "*(capture.rv_ptr) = (*capture.func_ptr)("
dt_capture.rv_ptr = rv_ptr
run_str = "*(dt_capture.rv_ptr) = (*dt_capture.func_ptr)("
}
else {
run_str = "(*capture.func_ptr)("
run_str = "(*dt_capture.func_ptr)("
}
arg_template = "*(capture.arg_ptrs[%f])%s"
arg_template = "*(dt_capture.arg_ptrs[%f])%s"
nargs = length(arg_ptrs)
for (i = 1; i <= nargs; i++) {
Expand All @@ -66,21 +66,21 @@ mata
rc = strtoreal(st_local("rc"))
// remove references to func_ptr, etc.
capture.func_ptr = NULL
capture.arg_ptrs = J(0,0,NULL)
capture.rv_ptr = NULL
dt_capture.func_ptr = NULL
dt_capture.arg_ptrs = J(0,0,NULL)
dt_capture.rv_ptr = NULL
return(rc)
}
real scalar method_capture(string scalar class_name,
string scalar func_name,
pointer matrix arg_ptrs,
| pointer scalar rv_ptr)
real scalar dt_method_capture(string scalar class_name,
string scalar func_name,
pointer matrix arg_ptrs,
| pointer scalar rv_ptr)
{
real scalar rc, i, nargs
string scalar run_str, arg_template
external class Capture scalar capture
external class dt_Capture scalar dt_capture
// It seems that any errors in pointer arguments get captured
// by the Stata capture below. So, test them here.
Expand All @@ -105,17 +105,17 @@ mata
}
capture.arg_ptrs = arg_ptrs
dt_capture.arg_ptrs = arg_ptrs
if (args() == 4) {
capture.rv_ptr = rv_ptr
run_str = "*(capture.rv_ptr) = " + ///
dt_capture.rv_ptr = rv_ptr
run_str = "*(dt_capture.rv_ptr) = " + ///
class_name + "." + func_name + "("
}
else {
run_str = class_name + "." + func_name + "("
}
arg_template = "*(capture.arg_ptrs[%f])%s"
arg_template = "*(dt_capture.arg_ptrs[%f])%s"
nargs = length(arg_ptrs)
for (i = 1; i <= nargs; i++) {
Expand All @@ -128,8 +128,8 @@ mata
rc = strtoreal(st_local("rc"))
// remove references
capture.arg_ptrs = J(0,0,NULL)
capture.rv_ptr = NULL
dt_capture.arg_ptrs = J(0,0,NULL)
dt_capture.rv_ptr = NULL
return(rc)
}
Expand Down
49 changes: 24 additions & 25 deletions mf_capture.sthlp → mf_dt_capture.sthlp
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{smcl}
{* 26mar2014}{...}
{cmd:help mata capture()}
{cmd:help mata dt_capture()}
{hline}

{title:Title}

{p 4 4 2}
{bf:capture() {hline 2}} Capture function errors in Mata
{bf:dt_capture() {hline 2}} Capture function errors in Mata


{title:Syntax}

{p 8 20 2}
{it:real scalar}
{cmd:capture(}{it:func_ptr}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}
{cmd:dt_capture(}{it:func_ptr}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}

{p 8 20 2}
{it:real scalar}
{cmd:method_capture(}{it:class_name}{cmd:,} {it:func_name}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}
{cmd:dt_method_capture(}{it:class_name}{cmd:,} {it:func_name}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}

{p 4 8 2}
where
Expand All @@ -41,20 +41,20 @@ where
{title:Description}

{pstd}
{cmd:capture()} runs the specified function with the specified arguments. If the
function aborts with error, {cmd:capture()} returns the error code. If the
function does not abort with error, {cmd:capture()} returns zero, and puts the
{cmd:dt_capture()} runs the specified function with the specified arguments. If the
function aborts with error, {cmd:dt_capture()} returns the error code. If the
function does not abort with error, {cmd:dt_capture()} returns zero, and puts the
return value of the function in {it:rv_ptr}, if specified.

{pstd}
{cmd:method_capture()} does the same for a class method.
{cmd:dt_method_capture()} does the same for a class method.


{title:Examples}

{pstd}
{cmd:capture()} is useful in the same situations as the Stata command
{cmd:capture}. That is, when you want to verify that an error get raised,
{cmd:dt_capture()} is useful in the same situations as the Stata command
{cmd:capture}. That is, when you want to verify that an error is raised,
or when you want to handle an error yourself (or ignore it) rather than
let the error halt your program.

Expand All @@ -74,13 +74,12 @@ sum.
Suppose your larger goal is to return the sum when possible or return the "."
missing value otherwise. You could write a function like this


function any_add(a, b)
{
real scalar rc
real matrix rv
transmorphic rv

rc = capture(&add(), (&a, &b), &rv)
rc = dt_capture(&add(), (&a, &b), &rv)
if (rc) {
return(.)
}
Expand Down Expand Up @@ -123,25 +122,25 @@ to be checked with custom code.
{p 8 8 8}
Since an error is being raised manually, you should probably write some tests
to check that the function raises the error you expect exactly when you expect
it to. This can be done with {cmd:capture()} and the built-in {cmd:assert()}.
it to. This can be done with {cmd:dt_capture()} and the built-in {cmd:assert()}.
Some tests you might write:

assert( capture(&thin(), &J(10, 1, 1)) == 0 )
assert( capture(&thin(), &J(0, 0, 1)) == 0 )
assert( capture(&thin(), &J(0, 10, 1)) == 0 )
assert( capture(&thin(), &J(10, 2, 1)) == 3200 )
assert( capture(&thin(), &J(10, 10, 1)) == 3200 )
assert( dt_capture(&thin(), &J(10, 1, 1)) == 0 )
assert( dt_capture(&thin(), &J(0, 0, 1)) == 0 )
assert( dt_capture(&thin(), &J(0, 10, 1)) == 0 )
assert( dt_capture(&thin(), &J(10, 2, 1)) == 3200 )
assert( dt_capture(&thin(), &J(10, 10, 1)) == 3200 )


{title:Conformability}

{cmd:capture(}{it:func_ptr}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}:
{cmd:dt_capture(}{it:func_ptr}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}:
{it:func_ptr}: 1 {it:x} 1
{it:arg_ptrs}: 1 {it:x c} or {it:r x} 1 or zero-dimensional
{it:rv_ptr}: 1 {it:x} 1
{it:result}: 1 {it:x} 1.

{cmd:method_capture(}{it:class_name}{cmd:,} {it:func_name}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}:
{cmd:dt_method_capture(}{it:class_name}{cmd:,} {it:func_name}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)}:
{it:class_name}: 1 {it:x} 1
{it:func_name}: 1 {it:x} 1
{it:arg_ptrs}: 1 {it:x c} or {it:r x} 1 or zero-dimensional
Expand All @@ -152,25 +151,25 @@ Some tests you might write:
{title:Diagnostics}

{p 4 8 8}
{cmd:capture(}{it:func_ptr}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)} aborts
{cmd:dt_capture(}{it:func_ptr}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)} aborts
with error if {break}
{it:func_ptr} is not a pointer to a function,{break}
{it:arg_ptrs} is not a vector of pointers, or{break}
{it:rv_ptr} (if used) is not a pointer scalar.

{p 4 8 8}
{cmd:method_capture(}{it:class_name}{cmd:,} {it:func_name}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)} aborts with error if{break}
{cmd:dt_method_capture(}{it:class_name}{cmd:,} {it:func_name}{cmd:,} {it:arg_ptrs} [{cmd:,} {it:rv_ptr}]{cmd:)} aborts with error if{break}
{it:class_name} is not a string scalar,{break}
{it:func_name} is not a string scalar,{break}
{it:arg_ptrs} is not a vector of pointers, or{break}
{it:rv_ptr} (if used) is not a pointer scalar.

{p 4 4 8}
{cmd:method_capture()} will return 3000 if there is no class with name
{cmd:dt_method_capture()} will return 3000 if there is no class with name
{it:class_name} or the class has no function with name {it:func_name}.

{pstd}
{cmd:method_capture()} will not work with classes defined within a function.
{cmd:dt_method_capture()} will not work with classes defined within a function.


{title:Author}
Expand Down

0 comments on commit 476f887

Please sign in to comment.