[R] Lexical Scoping: eval(expr,envir=)

Gabor Grothendieck
Thu, 18 Nov 2004 14:52:23 -0000

Eric Lecoutre <lecoutre <at> stat.ucl.ac.be> writes:

:
: Hi R-listers,
:
: I am trying to better undertand what we would call "functional
paradigm"
: use of S/R to better map my programming activities in other languages.
:
: This little function is aimed to create an object (at the end end, it would
: have it's own class):
:
: --
:    myObject =function(){
:      list(
:        a=1,
:        foo=function(b)
:        {
:        cat("b:",b)
:        cat("\na:", a)
:        }
:      )
:    }
: --
: To my minds, "a" would be a property of the object and
"foo" one of it's
: method.
:
: Let instantiate one version of this object:
:
: --
:  > tmp = myObject()
:  > tmp
: $a
: [1] 1
:
: $foo
: function(b)
:        {
:        cat("b:",b)
:        cat("\na:", a)
:        }
: <environment: 012DDFC8>
: --
:
: Now I try to "invoke it's foo method" (definitively not a S
terminology!)
: For sure, tmp$foo() wont work, as it can't know anything about
"a".
:
: Reading eval() help page, It is said:
:
: envir: the 'environment' in which 'expr' is to be evaluated.
May
:            also be a list, a data frame, or an integer as in
'sys.call' was
:
: so that I was thinking that
:
:  > eval(tmp$foo(),envir=tmp)
: Error in cat("b:", b) : Argument "b" is missing, with no
default
:
: would solve my problem, which is not the case.
: tmp is a list, in which "a" is defined hand has a value.
:
: Where is my fault?
:
: Eric
:
: R version 2.0.1, Windows

An example of lexical scoping lose to yours
is found by issuing the R command:

   demo(scoping)

However, you probably want to use the builtin
facilities, namely the S3 or S4 object oriented
system or possibly the more conventional oo system
defined in the R.oo package of the R.classes bundle
found at:
   http://www.maths.lth.se/help/R/R.classes/

In S3 your problem is done like this:

   # use S3 to define 2 objects of class "myObject" and a method

   tmp <- list(a=1); class(tmp) <- "myObject"
   tmp2 <- list(a=2); class(tmp2) <- "myObject"

   foo <- function(obj, b) UseMethod("foo")
   foo.myObject <- function(obj, b) cat("b", b, "\a",
obj$a, "\n")

   # try out the method
   foo(tmp, 3)
   foo(tmp2, 5)