prevent reassignment of function names

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

prevent reassignment of function names

Tim Bergsma
Hi.

I'm trying to find a systematic way to prevent assignment to names of
existing functions.  I've tried reassigning to the assignment operator,
with mixed results.  The function definition for "<-" below works as
hoped for the demonstrated assignments to a and c.  However, for the
assignment based on the test function, it appears that the formal
argument is not visible.  Any suggestions?

Thanks,

Tim.

-------------------------------------------------------------
rm(list=ls())
"<-" <- function(x,value){
        try(assign("y",x), silent=TRUE)
        if (exists("y", mode="function"))
                stop("assignment to an existing function")
        else  eval(substitute(.Primitive("<-")(x, value)),sys.frame(sys.parent(2)))
}

MYLEN <- function(infile){
        LEN <- nchar(infile)
        return(LEN)
}
a <- 3
c <- 3
#Error in c <- 3 : assignment to an existing function
d <- MYLEN("word")
#Error in nchar(infile) : object "infile" not found

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: prevent reassignment of function names

Thomas Lumley
On Thu, 6 Apr 2006, Tim Bergsma wrote:

> Hi.
>
> I'm trying to find a systematic way to prevent assignment to names of
> existing functions.  I've tried reassigning to the assignment operator,
> with mixed results.  The function definition for "<-" below works as
> hoped for the demonstrated assignments to a and c.  However, for the
> assignment based on the test function, it appears that the formal
> argument is not visible.  Any suggestions?
>

Well, my first suggestion would be not to do it. I don't see any real
benefit, and messing around with something as basic as assignment is
likely to break something.  If nothing else, there is certainly code out
there where people have, say, "df" or "c" as a variable name, and it isn't
doing any harm.

As a programming exercise it seems that the following works

"<-" <- function(x,value){
         if(tryCatch(is.function(x),error=function(e) FALSE))
                 stop("assignment to an existing function")
         else  eval.parent(substitute(.Primitive("<-")(x,value)))
}


  -thomas

Thomas Lumley Assoc. Professor, Biostatistics
[hidden email] University of Washington, Seattle

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: prevent reassignment of function names

Seth Falcon-2
In reply to this post by Tim Bergsma
Tim Bergsma <[hidden email]> writes:

> Hi.
>
> I'm trying to find a systematic way to prevent assignment to names of
> existing functions.

An alternative would be to put your functions into an R package with a
namespace.  Then you won't be able to overwrite them (easily).

+ seth

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: prevent reassignment of function names

Henrik Bengtsson-2
On 4/6/06, Seth Falcon <[hidden email]> wrote:
> Tim Bergsma <[hidden email]> writes:
>
> > Hi.
> >
> > I'm trying to find a systematic way to prevent assignment to names of
> > existing functions.
>
> An alternative would be to put your functions into an R package with a
> namespace.  Then you won't be able to overwrite them (easily).

Can even be a package without a namespace - to overwrite anything in a
package you have to explicitly do assign() to the environment of the
package.

Another way is to add an environment to the search path (?search) and
add you functions to that.  Example:

# Add an empty environment to the search path
env <- attach(list(), name="myFunctions")

# Define functions
assign("foo", function(x) { cat("foo: x=", x, "\n", sep="") }, envir=env)
assign("bar", function(x) { cat("bar: x=", x, "\n", sep="") }, envir=env)

# Assign 'foo' in the global environment
foo <- 3

# Function foo() is still available in 'myFunctions'
foo(4)

If you have a myFunction.R file with function definitions, e.g.

foo <- function(x) {
  cat("foo: x=", x, "\n", sep="")
}

bar <- function(x) {
  cat("bar: x=", x, "\n", sep="")
}

then it's a bit tricky to make source() assign objects to the
environment.  Instead you can use sourceTo() in the R.utils package,
e.g.

sourceTo("myFunctions.R", envir=env)

/Henrik

> + seth
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: prevent reassignment of function names

Brian Ripley
On Fri, 7 Apr 2006, Henrik Bengtsson wrote:

> On 4/6/06, Seth Falcon <[hidden email]> wrote:
>> Tim Bergsma <[hidden email]> writes:
>>
>>> Hi.
>>>
>>> I'm trying to find a systematic way to prevent assignment to names of
>>> existing functions.
>>
>> An alternative would be to put your functions into an R package with a
>> namespace.  Then you won't be able to overwrite them (easily).
>
> Can even be a package without a namespace - to overwrite anything in a
> package you have to explicitly do assign() to the environment of the
> package.

I don't think the concern was actually to 'overwrite' but rather to
redefine, which you can do by masking.  To quote the original post

   'I'm trying to find a systematic way to prevent assignment to names of
    existing functions.'

Note, `to names'.  Namespaces obviate masking of names of functions in
your package or in base, and from other namespaces you import.

>
> Another way is to add an environment to the search path (?search) and
> add you functions to that.  Example:
>
> # Add an empty environment to the search path
> env <- attach(list(), name="myFunctions")
>
> # Define functions
> assign("foo", function(x) { cat("foo: x=", x, "\n", sep="") }, envir=env)
> assign("bar", function(x) { cat("bar: x=", x, "\n", sep="") }, envir=env)
>
> # Assign 'foo' in the global environment
> foo <- 3
>
> # Function foo() is still available in 'myFunctions'
> foo(4)
>
> If you have a myFunction.R file with function definitions, e.g.
>
> foo <- function(x) {
>  cat("foo: x=", x, "\n", sep="")
> }
>
> bar <- function(x) {
>  cat("bar: x=", x, "\n", sep="")
> }
>
> then it's a bit tricky to make source() assign objects to the
> environment.  Instead you can use sourceTo() in the R.utils package,
> e.g.
>
> sourceTo("myFunctions.R", envir=env)
>
> /Henrik
>
>> + seth
>>
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

--
Brian D. Ripley,                  [hidden email]
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel