<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/an-example-of-monkey-patching-a-package-2/"></div></div><div><a data-url="https://www.r-bloggers.com/an-example-of-monkey-patching-a-package-2/" data-counturl="https://www.r-bloggers.com/an-example-of-monkey-patching-a-package-2/" data-count="horizontal" data-text="An example of monkey patching a package" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://r2d2.quartzbio.com/posts/monkey-patching-package.html"> R2D2</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>


<ul>
<li>An example of monkey patching a package</li>
<li><br></li>
<li>2013-07-11</li>
<li><a target="_blank" href="http://r2d2.quartzbio.com/posts/monkey-patching-package.Rmd">Source</a>
</li>
</ul>
<div>
<h2>Scope</h2>
<p>This article is about R package development.</p>
<h2>Motivation</h2>
<p>In the same spirit that my previous post <a target="_blank" href="http://r2d2.quartzbio.com/posts/package-depends-dirty-hack-solution.html">A dirty hack for importing packages that use Depends</a><br>
, I wanted to use an earlier version of the excellent <strong>gdata</strong> package in one of my packages, but as an <strong>Import</strong> instead of a <strong>Depend</strong>.</p>
<p>At that time <strong>gdata</strong> had a bug that prevented certain functions from being used through Import.<br>
I would like to show you the hack I used to make it work.<br>
(Gregory Warnes has now fixed <strong>gdata</strong> by releasing a new version, and I am very grateful for his responsiveness and<br>
efficiency, and for allowing me to use <strong>gdata</strong> as an illustration.)</p>
<h2>Analysis of the problem</h2>
<p><strong>gdata</strong> used <code>path.package(&quot;gdata&quot;)</code> to locate its files at runtime. But <code>path.package</code> can only locate a package that<br>
is attached (to the search path), and that is exactly what we want to avoid.</p>
<h2>The idea of the hack</h2>
<p>The function to use to locate a package directory when the package is not attached is <code>find.package</code>.<br>
What we would like is to somehow modify —at runtime— the <strong>gdata</strong> package and replace the calls to <code>path.package</code> by<br>
calls to <code>find.package</code>. </p>
<p>When executing a call to a <strong>gdata</strong> function, R locates the <code>path.package</code> symbol by first looking in the <strong>gdata</strong>'s namespace,<br>
then in the <strong>gdata</strong>'s imports environment, then in the base/core namespace, then in the search path.</p>
<p>Because all these namespaces are sealed, and because the prime directive is not to modify the search path, we can not<br>
alter or add a new definition in those environments. Butwe can insert a new environment somewhere in the<br>
chain between <strong>gdata</strong>'s namespace and the base environment which provides an alternate definition of <code>path.package</code>.</p>
<h2>Illustration</h2>
<p>We are going to insert a new environment between <strong>gdata</strong>'s imports environment and its parent.<br>
This environment will contain a symbol named <code>path.package</code>, but which have the same definition as <code>find.package</code><br>
(i.e. <code>path.package</code> will point to <code>find.package</code>).</p>
<p><img alt="plot of chunk before" src="https://i0.wp.com/r2d2.quartzbio.com/posts/assets/fig/before-1.png?w=456" data-recalc-dims="1"> </p>
<p><img alt="plot of chunk after" src="https://i2.wp.com/r2d2.quartzbio.com/posts/assets/fig/after-1.png?w=456" data-recalc-dims="1"> </p>
<h2>Implementation</h2>
<p>To achieve this, we will provide a custom <code>.onLoad</code> function in <code>MyPkg</code>, which is executed when the package is loaded.<br>
We also define a special symbol to avoid repeated insertion of a new environment in the case that our package is unloaded then reloaded.</p>
<pre><code>.onLoad &lt;- function(libname, pkgname) {

    # Monkey patch so that gdata uses find.package instead of path.package
    gdata_imports &lt;- parent.env(getNamespace('gdata'))
    current &lt;- parent.env(gdata_imports)

    HACK &lt;- '__hack__'
    # set the new env between gdata imports and base env, only if not already done
    if (! exists(HACK, envir=parent.env(gdata_imports) ) ) {
        # make a new env, with path.package poiting to find.package
        env &lt;- new.env(parent=current)
        assign(HACK, TRUE, envir=env)
        assign('path.package', find.package, envir=env)   ### define path.package=find.package
        parent.env(gdata_imports) &lt;- env                  ### insert our custom env
    }
}
</code></pre>
<h2>Conclusion</h2>
<p>This is an example of the kind of trick we can achieve in our objective of trustworthy computation.<br>
Once again, this trick is no longer needed for the current version of <strong>gdata</strong>.</p>
<p><em>Karl Forner @ Quartz Bio</em><br>
(with help from Gregory Warnes)</p>
</div>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/an-example-of-monkey-patching-a-package-2/"></div></div><div><a data-url="https://www.r-bloggers.com/an-example-of-monkey-patching-a-package-2/" data-counturl="https://www.r-bloggers.com/an-example-of-monkey-patching-a-package-2/" data-count="vertical" data-text="An example of monkey patching a package" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://r2d2.quartzbio.com/posts/monkey-patching-package.html"> R2D2</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/le6-o7YbH_A"></a></div>