[R-pkg-devel] Force namespace prefix for a loaded package function
Tim Keitt
tkeitt at utexas.edu
Tue Jun 28 18:07:05 CEST 2016
http://www.keittlab.org/
On Mon, Jun 27, 2016 at 7:04 PM, Tim Keitt <tkeitt at utexas.edu> wrote:
>
>
> http://www.keittlab.org/
>
> On Mon, Jun 27, 2016 at 5:18 PM, Duncan Murdoch <murdoch.duncan at gmail.com>
> wrote:
>
>> On 27/06/2016 5:46 PM, Tim Keitt wrote:
>>
>>>
>>>
>>> http://www.keittlab.org/
>>>
>>> On Mon, Jun 27, 2016 at 10:19 AM, Duncan Murdoch
>>> <murdoch.duncan at gmail.com <mailto:murdoch.duncan at gmail.com>> wrote:
>>>
>>> On 27/06/2016 11:08 AM, Tim Keitt wrote:
>>>
>>> http://www.keittlab.org/
>>>
>>> On Mon, Jun 27, 2016 at 3:22 AM, Joris Meys <jorismeys at gmail.com
>>> <mailto:jorismeys at gmail.com>> wrote:
>>>
>>> > If you want to call a non exported function, you need three
>>> colons
>>> >
>>> > X:::f ()
>>> >
>>> > And frankly, that is a bad idea.
>>> >
>>> I think you missed the point (and stated the obvious).
>>>
>>> A well-designed namespace feature would give control of imports
>>> to the code
>>> user, not the code writer.
>>>
>>> Right now, I have to avoid all the function names in base
>>> because I will
>>> cause a collision. If I want to have an "options" function in my
>>> package, I
>>> have to make it "pkgname_options" rather than pkgname::options,
>>> which is
>>> greatly preferable and would allow the user to decide whether
>>> they want to
>>> import it and then simply use "options" and "base::options".
>>>
>>> I've always considered this all-or-nothing approach to imports a
>>> bug in the
>>> implementation of namespaces in R. I was trying to suggest that
>>> it be
>>> fixed. (Probably should have sent this to r-devel actually.)
>>>
>>>
>>> The base package is special, but for all other packages there's no
>>> "all-or-nothing" approach to imports, so your statement about a
>>> function named "options" doesn't really make sense. If you want to
>>> do that, just do it, and other packages that prefer your
>>> implementation to the base one can import just that one function, or
>>> do the import at run time by calling it as pkgname::options().
>>>
>>>
>>> I know that. I mean for someone writing a script, not a package.
>>>
>>> Its all good for package writers. Its quite simple to control imports
>>> there. But not so much for someone using the package in R to write a
>>> script. You either go with package_name::object for everything or you
>>> call "library" and you get everything the packager exported.
>>>
>>> It would be nice to 1) be able to hold back some functions from being
>>> fully exported in a package and (maybe or) 2) extend the functionality
>>> of the NAMESPACE file to the user session via a set of functions.
>>>
>>> Does that make any more sense?
>>>
>>
>> It makes a little more sense, but it's still not correct. If you want to
>> do the equivalent of importing foo::options, just add the line
>>
>> options <- foo::options
>>
>> at the start of your script. This "imports" that one function, and
>> nothing else from the foo namespace.
>>
>> It has the side effect of leaving the options object in the current
>> workspace afterwards. If that concerns you, use local():
>>
>> local( {
>> options <- foo::options
>> # Lots of calculations, computing result
>> result
>> })
>>
>
> Good one. Yes, that is more of what I had in mind.
>
> I suppose I really want C++-like namespaces because I tend to think that
> way.
>
Here's a prototype package implementing some ideas:
https://github.com/thk686/using
THK
>
> THK
>
>
>>
>> Duncan Murdoch
>>
>>
>>
>>> THK
>>>
>>>
>>>
>>> Duncan Murdoch
>>>
>>>
>>> THK
>>>
>>>
>>>
>>> > Cheers
>>> > Joris
>>> > On 26 Jun 2016 19:37, "Tim Keitt" <tkeitt at utexas.edu
>>> <mailto:tkeitt at utexas.edu>> wrote:
>>> >
>>> >> It would be rather nice if we could define functions in our
>>> packages that
>>> >> must be called with the namespace prefix.
>>> >>
>>> >> I'd like to do
>>> >>
>>> >> #' @protected (or some such)
>>> >> f = function(...) list(...)
>>> >>
>>> >> in package scope and then
>>> >>
>>> >> library(x)
>>> >> f(1) # fails
>>> >> x::f(1) # succeeds
>>> >>
>>> >> Currently unless I am missing something, a function is either
>>> exported to
>>> >> global scope or not available. This could be done if package
>>> loading made
>>> >> two environments, one in the path and another not in the
>>> path, and then
>>> >> have the namespace prefix search both in succession.
>>> >>
>>> >> Yes, you could do
>>> >>
>>> >> #' @export
>>> >> x_f = function(...) list(...)
>>> >>
>>> >> library(x)
>>> >> x_f(1)
>>> >>
>>> >> but I would prefer reusing the namespace prefix syntax.
>>> >>
>>> >> This would also avoid name collisions between package, which
>>> ideally is
>>> >> the
>>> >> purpose of a namespace.
>>> >>
>>> >> I suppose also you could make two packages and list one in
>>> Imports: but I
>>> >> find that less satisfying because it requires a different
>>> namespace
>>> >> prefix.
>>> >>
>>> >> Or am I missing something obvious here.
>>> >>
>>> >> THK
>>> >>
>>> >> http://www.keittlab.org/
>>> >>
>>> >> [[alternative HTML version deleted]]
>>> >>
>>> >> ______________________________________________
>>> >> R-package-devel at r-project.org
>>> <mailto:R-package-devel at r-project.org> mailing list
>>> >> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>> >>
>>> >
>>>
>>> [[alternative HTML version deleted]]
>>>
>>> ______________________________________________
>>> R-package-devel at r-project.org
>>> <mailto:R-package-devel at r-project.org> mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>
>>>
>>>
>>>
>>>
>>
>
[[alternative HTML version deleted]]
More information about the R-package-devel
mailing list