akshay kulkarni
2023-Jan-20 17:18 UTC
[R] function doesn't exists but still runs..... (akshay kulkarni)
Dear Jorgen,
thanks for the reply.....so according to you one can pegion
hole the problem as concerning R's lexical scoping rules,am I right? Or some
arcane concept regarding environments....?
THanking you,
Yours sincerely,
AKSHAY M KULKARNI
________________________________
From: Jorgen Harmse <JHarmse at roku.com>
Sent: Friday, January 20, 2023 9:34 PM
To: r-help at r-project.org <r-help at r-project.org>; akshay_e4 at
hotmail.com <akshay_e4 at hotmail.com>; williamwdunlap at gmail.com
<williamwdunlap at gmail.com>
Subject: Re: function doesn't exists but still runs..... (akshay kulkarni)
It may help to expand a bit on Bill Dunlap's answer. I think that library
does something like this:
Create a new environment for all the package objects. This environment will not
be directly visible from .GlobalEnv, and ancestor environments may not be
directly visible either. It may contain functions & other objects that are
not exported, and it may use objects in ancestor environments that .GlobalEnv
doesn't see directly. On the other hand, functions in the package will still
see external functions in the way the package author intended instead of seeing
functions with the same name that are visible to .GlobalEnv.
Run the source code in the private environment (using source(local=private
environment, ....)?). Most package source code just defines functions, but the
source code could build other objects that the package needs for some reason, or
it could use delayedAssign to build the objects lazily. By default, the
environment of any function defined by the source code is the private
environment, so the function has access to private objects and to anything in
ancestor environments.
Create a second new environment whose parent is parent.env(.GlobalEnv). For
every export, assign the corresponding object from the private environment into
the corresponding name in the public environment. Note that the environment of
any function is still the private environment in which it was created. (I think
that a function is mostly determined by its environment, its formals, and its
body. A function call creates a new environment whose parent is the environment
of the function. Thus whoever wrote the function can control the search for
anything that isn?t passed in or created by the function itself.)
Reset parent.env(.GlobalEnv) to be the public environment. This makes all the
exported objects (usually functions) available at the command line and allows
the user to see everything that was available before (usually by name only, but
by scope-resolved name if necessary). As noted by Bill Dunlap and in more detail
above, package functions can use functions & other objects that are not
directly visible to the user. As he also showed, you can (usually) pierce the
privacy as long at least one function is exported. environment(package_function)
is the private environment, so you can use it to see all the private objects and
everything in the ancestor environments. You can repeat the trick to see private
environments of packages you didn't directly pull in. I think you can even
unlock bindings and do ghastly things to the package's private environment.
Regards,
Jorgen Harmse.
------------------------------
Message: 17
Date: Thu, 19 Jan 2023 16:02:31 -0800
From: Bill Dunlap <williamwdunlap at gmail.com>
To: akshay kulkarni <akshay_e4 at hotmail.com>
Cc: R help Mailing list <r-help at r-project.org>
Subject: Re: [R] function doesn't exists but still runs.....
Message-ID:
<CAHqSRuTCBqh84FHg7=Xmd9qHxUiAN3Y4zBJbkAR3dRWhggu89Q at
mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Look into R's scoping rules. E.g.,
https://bookdown.org/rdpeng/rprogdatascience/scoping-rules-of-r.html.
* When a function looks up a name, it looks it up in the environment in
which the function was defined.
* Functions in a package are generally defined in the package's environment
(although sometimes they are in a descendent of the parent's environment).
* When one searches an environment for a name, if it is not found in the
environment the search continues in the parent environment of that
environment, recursively until the parent environment is the empty
environment.
> with(environment(wdman::selenium), java_check)
function ()
{
javapath <- Sys.which("java")
if (identical(unname(javapath), "")) {
stop("PATH to JAVA not found. Please check JAVA is
installed.")
}
javapath
}
<bytecode: 0x000001fd0ab826a8>
<environment: namespace:wdman>
-Bill
On Thu, Jan 19, 2023 at 2:28 PM akshay kulkarni <akshay_e4 at hotmail.com>
wrote:
> dear members,
> I am using the RSelenium package which uses
> the function selenium() from the wdman package. The selenium function
> contains the function java_check at line 12. If I try to run it, it throws
> an error:
>
> > javapath <- java_check()
> Error in java_check() : could not find function "java_check"
>
> Also:
>
> > exists("java_check")
> [1] FALSE
>
> But when I run selenium(), it works fine....
>
> How do you explain this conundrum? You can refer to this link:
> https://github.com/ropensci/wdman/issues/15
>
> Specifically what concept of R explains this weird behaviour?
>
> Thanking you,
> Yours sincerely,
> AKSHAY M KULKARNI
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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]]
------------------------------
Subject: Digest Footer
_______________________________________________
R-help at 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.
------------------------------
End of R-help Digest, Vol 239, Issue 20
***************************************
[[alternative HTML version deleted]]
Jeff Newmiller
2023-Jan-20 17:59 UTC
[R] function doesn't exists but still runs..... (akshay kulkarni)
This is not a "problem" ... it is a "feature". Packages often use functions from other packages, but that does NOT mean that you as a user can automatically use those functions also. If Package A uses Package B to implement something, but Package B becomes unavailable, the maintainer of Package A would like to fill in the gap. If Package A "Depends" on Package B then users of package A automatically get access to Package B and they get used to treating Package A like it contains all of the functions in Package B directly. Therefore it is common to have Package A "Import" Package B so that the Package A maintainer won't have to re-implement all of Package B to avoid breaking code for users of Package A. They can fix things under the hood for their own Package A functions using other code. If a user wants to depend on Package B, it is up to them to use the library function to do so explicitly... and when Package B goes away, they are responsible for dealing with that mess themselves. You asked "how", and got answers... but you didn't bother to follow up on those answers by reading things like "Writing R Extensions" or Hadley Wickham's "R Packages" or "Advanced R". Don't turn that laziness into a value judgement about "problems" with R. On January 20, 2023 9:18:54 AM PST, akshay kulkarni <akshay_e4 at hotmail.com> wrote:>Dear Jorgen, > thanks for the reply.....so according to you one can pegion hole the problem as concerning R's lexical scoping rules,am I right? Or some arcane concept regarding environments....? > >THanking you, >Yours sincerely, >AKSHAY M KULKARNI >________________________________ >From: Jorgen Harmse <JHarmse at roku.com> >Sent: Friday, January 20, 2023 9:34 PM >To: r-help at r-project.org <r-help at r-project.org>; akshay_e4 at hotmail.com <akshay_e4 at hotmail.com>; williamwdunlap at gmail.com <williamwdunlap at gmail.com> >Subject: Re: function doesn't exists but still runs..... (akshay kulkarni) > > >It may help to expand a bit on Bill Dunlap's answer. I think that library does something like this: > > > >Create a new environment for all the package objects. This environment will not be directly visible from .GlobalEnv, and ancestor environments may not be directly visible either. It may contain functions & other objects that are not exported, and it may use objects in ancestor environments that .GlobalEnv doesn't see directly. On the other hand, functions in the package will still see external functions in the way the package author intended instead of seeing functions with the same name that are visible to .GlobalEnv. > > > >Run the source code in the private environment (using source(local=private environment, ....)?). Most package source code just defines functions, but the source code could build other objects that the package needs for some reason, or it could use delayedAssign to build the objects lazily. By default, the environment of any function defined by the source code is the private environment, so the function has access to private objects and to anything in ancestor environments. > > > >Create a second new environment whose parent is parent.env(.GlobalEnv). For every export, assign the corresponding object from the private environment into the corresponding name in the public environment. Note that the environment of any function is still the private environment in which it was created. (I think that a function is mostly determined by its environment, its formals, and its body. A function call creates a new environment whose parent is the environment of the function. Thus whoever wrote the function can control the search for anything that isn?t passed in or created by the function itself.) > > > >Reset parent.env(.GlobalEnv) to be the public environment. This makes all the exported objects (usually functions) available at the command line and allows the user to see everything that was available before (usually by name only, but by scope-resolved name if necessary). As noted by Bill Dunlap and in more detail above, package functions can use functions & other objects that are not directly visible to the user. As he also showed, you can (usually) pierce the privacy as long at least one function is exported. environment(package_function) is the private environment, so you can use it to see all the private objects and everything in the ancestor environments. You can repeat the trick to see private environments of packages you didn't directly pull in. I think you can even unlock bindings and do ghastly things to the package's private environment. > > > >Regards, > >Jorgen Harmse. > >------------------------------ > >Message: 17 >Date: Thu, 19 Jan 2023 16:02:31 -0800 >From: Bill Dunlap <williamwdunlap at gmail.com> >To: akshay kulkarni <akshay_e4 at hotmail.com> >Cc: R help Mailing list <r-help at r-project.org> >Subject: Re: [R] function doesn't exists but still runs..... >Message-ID: > <CAHqSRuTCBqh84FHg7=Xmd9qHxUiAN3Y4zBJbkAR3dRWhggu89Q at mail.gmail.com> >Content-Type: text/plain; charset="utf-8" > >Look into R's scoping rules. E.g., >https://bookdown.org/rdpeng/rprogdatascience/scoping-rules-of-r.html. > >* When a function looks up a name, it looks it up in the environment in >which the function was defined. >* Functions in a package are generally defined in the package's environment >(although sometimes they are in a descendent of the parent's environment). >* When one searches an environment for a name, if it is not found in the >environment the search continues in the parent environment of that >environment, recursively until the parent environment is the empty >environment. > >> with(environment(wdman::selenium), java_check) >function () >{ > javapath <- Sys.which("java") > if (identical(unname(javapath), "")) { > stop("PATH to JAVA not found. Please check JAVA is installed.") > } > javapath >} ><bytecode: 0x000001fd0ab826a8> ><environment: namespace:wdman> > >-Bill > >On Thu, Jan 19, 2023 at 2:28 PM akshay kulkarni <akshay_e4 at hotmail.com> >wrote: > >> dear members, >> I am using the RSelenium package which uses >> the function selenium() from the wdman package. The selenium function >> contains the function java_check at line 12. If I try to run it, it throws >> an error: >> >> > javapath <- java_check() >> Error in java_check() : could not find function "java_check" >> >> Also: >> >> > exists("java_check") >> [1] FALSE >> >> But when I run selenium(), it works fine.... >> >> How do you explain this conundrum? You can refer to this link: >> https://github.com/ropensci/wdman/issues/15 >> >> Specifically what concept of R explains this weird behaviour? >> >> Thanking you, >> Yours sincerely, >> AKSHAY M KULKARNI >> >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> 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]] > > > > >------------------------------ > >Subject: Digest Footer > >_______________________________________________ >R-help at 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. > > >------------------------------ > >End of R-help Digest, Vol 239, Issue 20 >*************************************** > > [[alternative HTML version deleted]] >-- Sent from my phone. Please excuse my brevity.
Jorgen Harmse
2023-Jan-20 18:05 UTC
[R] [EXTERNAL] Re: function doesn't exists but still runs..... (akshay kulkarni)
Hi Akshay,
Lexical scoping and environments are closely tied. (I think Bill even cited the
documentation.) I guess it's arcane in the sense that scoping usually does
what you expect, but the way that works is related to what we discussed.
What led you to discover the issue? Were you debugging the public package
function because it didn't do what you expected, or were you just curious
how it worked?
Regards,
Jorgen.
From: akshay kulkarni <akshay_e4 at hotmail.com>
Date: Friday, January 20, 2023 at 11:19
To: Jorgen Harmse <JHarmse at roku.com>, r-help at r-project.org
<r-help at r-project.org>, williamwdunlap at gmail.com <williamwdunlap
at gmail.com>
Subject: [EXTERNAL] Re: function doesn't exists but still runs..... (akshay
kulkarni)
Dear Jorgen,
thanks for the reply.....so according to you one can pegion
hole the problem as concerning R's lexical scoping rules,am I right? Or some
arcane concept regarding environments....?
THanking you,
Yours sincerely,
AKSHAY M KULKARNI
________________________________
From: Jorgen Harmse <JHarmse at roku.com>
Sent: Friday, January 20, 2023 9:34 PM
To: r-help at r-project.org <r-help at r-project.org>; akshay_e4 at
hotmail.com <akshay_e4 at hotmail.com>; williamwdunlap at gmail.com
<williamwdunlap at gmail.com>
Subject: Re: function doesn't exists but still runs..... (akshay kulkarni)
It may help to expand a bit on Bill Dunlap's answer. I think that library
does something like this:
Create a new environment for all the package objects. This environment will not
be directly visible from .GlobalEnv, and ancestor environments may not be
directly visible either. It may contain functions & other objects that are
not exported, and it may use objects in ancestor environments that .GlobalEnv
doesn't see directly. On the other hand, functions in the package will still
see external functions in the way the package author intended instead of seeing
functions with the same name that are visible to .GlobalEnv.
Run the source code in the private environment (using source(local=private
environment, ....)?). Most package source code just defines functions, but the
source code could build other objects that the package needs for some reason, or
it could use delayedAssign to build the objects lazily. By default, the
environment of any function defined by the source code is the private
environment, so the function has access to private objects and to anything in
ancestor environments.
Create a second new environment whose parent is parent.env(.GlobalEnv). For
every export, assign the corresponding object from the private environment into
the corresponding name in the public environment. Note that the environment of
any function is still the private environment in which it was created. (I think
that a function is mostly determined by its environment, its formals, and its
body. A function call creates a new environment whose parent is the environment
of the function. Thus whoever wrote the function can control the search for
anything that isn?t passed in or created by the function itself.)
Reset parent.env(.GlobalEnv) to be the public environment. This makes all the
exported objects (usually functions) available at the command line and allows
the user to see everything that was available before (usually by name only, but
by scope-resolved name if necessary). As noted by Bill Dunlap and in more detail
above, package functions can use functions & other objects that are not
directly visible to the user. As he also showed, you can (usually) pierce the
privacy as long at least one function is exported. environment(package_function)
is the private environment, so you can use it to see all the private objects and
everything in the ancestor environments. You can repeat the trick to see private
environments of packages you didn't directly pull in. I think you can even
unlock bindings and do ghastly things to the package's private environment.
Regards,
Jorgen Harmse.
------------------------------
Message: 17
Date: Thu, 19 Jan 2023 16:02:31 -0800
From: Bill Dunlap <williamwdunlap at gmail.com>
To: akshay kulkarni <akshay_e4 at hotmail.com>
Cc: R help Mailing list <r-help at r-project.org>
Subject: Re: [R] function doesn't exists but still runs.....
Message-ID:
<CAHqSRuTCBqh84FHg7=Xmd9qHxUiAN3Y4zBJbkAR3dRWhggu89Q at
mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Look into R's scoping rules. E.g.,
https://bookdown.org/rdpeng/rprogdatascience/scoping-rules-of-r.html.
* When a function looks up a name, it looks it up in the environment in
which the function was defined.
* Functions in a package are generally defined in the package's environment
(although sometimes they are in a descendent of the parent's environment).
* When one searches an environment for a name, if it is not found in the
environment the search continues in the parent environment of that
environment, recursively until the parent environment is the empty
environment.
> with(environment(wdman::selenium), java_check)
function ()
{
javapath <- Sys.which("java")
if (identical(unname(javapath), "")) {
stop("PATH to JAVA not found. Please check JAVA is
installed.")
}
javapath
}
<bytecode: 0x000001fd0ab826a8>
<environment: namespace:wdman>
-Bill
On Thu, Jan 19, 2023 at 2:28 PM akshay kulkarni <akshay_e4 at hotmail.com>
wrote:
> dear members,
> I am using the RSelenium package which uses
> the function selenium() from the wdman package. The selenium function
> contains the function java_check at line 12. If I try to run it, it throws
> an error:
>
> > javapath <- java_check()
> Error in java_check() : could not find function "java_check"
>
> Also:
>
> > exists("java_check")
> [1] FALSE
>
> But when I run selenium(), it works fine....
>
> How do you explain this conundrum? You can refer to this link:
> https://github.com/ropensci/wdman/issues/15
>
> Specifically what concept of R explains this weird behaviour?
>
> Thanking you,
> Yours sincerely,
> AKSHAY M KULKARNI
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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]]
------------------------------
Subject: Digest Footer
_______________________________________________
R-help at 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.
------------------------------
End of R-help Digest, Vol 239, Issue 20
***************************************
[[alternative HTML version deleted]]