 

________________________________

	From: Allan Engelhardt [mailto:allane@cybaea.com] 
	Sent: Thursday, July 02, 2009 11:12 AM
	To: William Dunlap
	Cc: r-help@r-project.org
	Subject: Re: [R] How to use current value of variable in
function definition?
	
	
	Thanks for the pointer to substitute(), William.  This seems to
work and is a little shorter than yours:
	
	a <- 1; foo <- eval(substitute(function () print(a),
env=list(a=a)))
	a <- 2; foo()
	# [1] 1
	
	Not the clearest code I have ever seen, especially as 'foo'
still shows 'a':
	
	print(foo)
	# function () a
	
	Allan 
	 
	The need for eval and the misleading printout is why I sent the
longer version.
	functionBody(foo) does show the right thing.  One might consider
this a bug
	in substitute(): it does not clear out the source information
when it works on
	a call to function.  You can add
	    attr(foo,"source")<-NULL
	to fix up the printing.
	 
	substitute() doesn't seem to go into the default values of the
arguments,
	which is where one might prefer to put variables like this.
	 
	The eval() around substitute() is needed because function(z)z+1
is a call to
	a function called function, it is not a function until that call
gets evaluated
	and substitute does not evaluate its first argument).
	 
	Using local() avoids these problems.
	Bill Dunlap
	TIBCO Software Inc - Spotfire Division
	wdunlap tibco.com 

	 
	
	On 02/07/09 18:28, William Dunlap wrote: 

			From: r-help-bounces@r-project.org 
			[mailto:r-help-bounces@r-project.org] On Behalf
Of Allan Engelhardt
			Sent: Thursday, July 02, 2009 9:47 AM
			To: r-help@r-project.org
			Subject: [R] How to use current value of
variable in function 
			definition?
			
			Must be the heat or something but I can't get my
brain into gear and 
			figure out how to get something like
			
			if (1) { c <- 1; foo <- function () print(c); }
			c <- 2
			foo()
			
			to print 1, not 2.  (The real life example is a
little more 
			complex, but 
			you get the idea.  I don't want the variable c
in the function 
			definition, I want its value at that time.)
			
			The only thing I have been able to come up with
is something like
			
			if (1) foo <- (function () { c <- 1;
return(function () print(c)) })()
			c <- 2
			foo()
			# [1] 1
			    

		You might try local(), as in
		   > c<-1 ; foo.local<-local({orig.c <- c ;
function()orig.c})
		   > foo.local()
		   [1] 1
		   > c<-3
		   > foo.local()
		   [1] 1
		It is possible for someone to alter the orig.c after you
create
		foo.local, as in
		   > assign("orig.c", 17, env=environment(foo.local))
		   > foo.local()
		   [1] 17
		Looking at the function's code will not make it clear
where
		orig.c is coming from.  The clue is that its environment
is not
		one of the standard named ones, but it given by a hex
number.
		   > foo.local
		   function()orig.c
		   <environment: 0x02108c54>
		
		You could also use substitute() to change the code in
the function.
		It can be messy to do but the resulting code may be
clearer (although
		it won't give a hint as to where that constant came
from).  E.g.,
		   > foo.substitute<-function()orig.c
		   > c<-1 ;
functionBody(foo.substitute)<-do.call(substitute,
		list(functionBody(foo.substitute), list(orig.c=c)))
		   > foo.substitute()
		   [1] 1
		   > foo.substitute
		   function () 
		   1
		
		Bill Dunlap
		TIBCO Software Inc - Spotfire Division
		wdunlap tibco.com 
		
		  

			but that just hurts.  Please make the pain go
away.
			
			Can someone wake up my brain?
			
			Allan.
			
			______________________________________________
			R-help@r-project.org mailing list
			https://stat.ethz.ch/mailman/listinfo/r-help
			PLEASE do read the posting guide 
			http://www.R-project.org/posting-guide.html
			and provide commented, minimal, self-contained,
reproducible code.
			
			    


	[[alternative HTML version deleted]]


