Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The difference between what <code>with(list(x = 42), f())</code> is doing and what you expect is the difference between <em>lexical scoping</em> (which is what R uses) and <em>dynamic scoping</em> (which seems to be what you are expecting). </p> <p>Lexical scoping means that <em>free variables</em> (like the variable <code>x</code> in <code>f</code>) are looked up in the environment where <code>f</code> is <em>defined</em> -- not the environment <code>f</code> is <em>called from</em>.</p> <p><code>f</code> is defined in the global environment so that is where <code>x</code> is looked up.</p> <p>It doesn't matter that <code>with</code> has been invoked to create a new environment from which <code>f</code> is called since the environment from which its called is not involved in looking up free variables.</p> <p>To get this to work the way you want create a copy of <code>f</code> and reset its environment since that is what R uses to search for free variables:</p> <pre><code>with(list(x = 42), { environment(f) &lt;- environment(); f() }) </code></pre> <p>Admittedly this is a bit onerous but you could simplify it somewhat by using the proto package since <code>proto</code> resets the environment of each function that is explicitly inserted into a proto object:</p> <pre><code>library(proto) with(proto(x = 42, f = f), f()) </code></pre> <p>ADDED:</p> <p>Note that if your aim is to do object oriented programming (as per your comment to another response) then you might want to look into proto further at the <a href="http://r-proto.google.code" rel="nofollow">proto home page</a>. For example, we could define the proto object <code>p</code> and redefine <code>f</code> so that its a method of <code>p</code> (in which case it must accept the object in argument 1) like this:</p> <pre><code>library(proto) p &lt;- proto(x = 42, f = function(.) print(.$x)) p$f() </code></pre> <p>ADDED 2:</p> <p>With the attached case, running <code>f()</code> first looks in the global environment since that is where <code>f</code> is defined. Since <code>x</code> is not found in the global environment it looks into the parent of the global environment and in this case it finds it there. We can discover the parent of the global environment using <code>parent.env</code> and here we see that the attached environment has become the parent of the global environment.</p> <pre><code>&gt; attach(list(x = 42)) &gt; parent.env(.GlobalEnv) &lt;environment: 0x048dcdb4&gt; attr(,"name") [1] "list(x = 42)" </code></pre> <p>We can view the global environment and all its ancestors in order like this:</p> <pre><code>&gt; search() [1] ".GlobalEnv" "list(x = 42)" "package:stats" [4] "package:graphics" "package:grDevices" "package:utils" [7] "package:datasets" "package:methods" "Autoloads" [10] "package:base" </code></pre> <p>Thus <code>"list(x = 42)"</code> is the parent of the global environment, stats is the parent of <code>"list(x = 42)"</code> and so on.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload