In this example, we expose a Normal distribution as a COM object.
This class provides methods for
Unlike the S functions to which one must supply the parameters of the
distribution, objects from this class maintain state and the methods
have access to these. To do this, we generate a closure containing
simple functions that merely call the regular S functions to for
dealing with the Normal distribution. These are
*rnorm*, *pnorm*,
*qnorm*, *dnorm*.
Because the Normal distribution object has state given by the mean and
standard deviation, we need a closure in R to "capture" this state.
We do this by providing a generator function that defines the methods
with these settings.

Now we register this class definition with R and
for clients to access.

- generating samples
- computing percentiles
- computing quantiles
- computing densitys
- shifting and scaling the distribution for subsequent computations

g <- function(mu = 0, sigma = 1) { generic <- function(n, abc=10, k="My string") { n + 10 } sample <- function(n) { rnorm(as.integer(n), mu, sigma) } percentile <- function(q, lower = TRUE) { pnorm(as.numeric(q), mu, sigma, lower.tail = as.logical(lower)) } quantile <- function(p) { qnorm(as.numeric(p), mu, sigma) } density <- function(x) { dnorm(as.numeric(x), mu, sigma) } deviate <- function() { rnorm(1, mu, sigma) } list(sample = sample, percentile = percentile, quantile = quantile, density = density, deviate = deviate, generic = generic, .properties = c("mu", "sigma"), .help = c(sample = "generate a sample of values", percentile = "CDF values from this distribution", quantile = "quantile values from this distribution", density = "values of the density function for this distribution" )) } |
---|

def = SCOMIDispatch(g, "SNormal") def@classId = getuuid("c484d2f9-21f5-49ac-8c8d-2007e12245d3") registerCOMClass(def) |
---|

We can use this class in any of the COM supported classes. For
example, consider *Visual Basic* (VB). We first create an instance of
this class. We declare some variables and then create the object.

Now we can invoke the objects methods. So we create a sample of 3
elements.

Now **v** is a *VARIANT*.
Unlike high-level languages such as Python or Perl,
*Visual Basic* doesn't convert the array returned from R directly
into a VB array. Instead, we can access it via the
variant and ask for its upper and lower indices and query
its contents.

We can iterate over its entries
as follows

Dim N as Object Dim v as Variant Set N = CreateObject("SNormal") |
---|

v = N.sample(3) |
---|

Debug.Print TypeName(v) Debug.Print UBound(v) Debug.Print LBound(v) Debug.Print v(1) |
---|

For i = LBound(v) To UBound(v) Debug.Print v(i) Next i |
---|