Winston,

 (back on list since I found some official info)

Looks like the behavior you are seeing is "documented-ish"

Only methods actually used will be included in the environment
corresponding to an individual object. To declare that a method requires a
particular other method, the first method should include a call to
$usingMethods() with the name of the other method as an argument. Declaring
the methods this way is essential if the other method is used indirectly
(e.g., via 
sapply<http://stat.ethz.ch/R-manual/R-devel/library/base/html/lapply.html>
() or 
do.call<http://stat.ethz.ch/R-manual/R-devel/library/base/html/do.call.html>
()). If it is called directly, code analysis will find it. Declaring the
method is harmless in any case, however, and may aid readability of the
source code.

Seems like .self$usingMethods() is supposed to allow you to do what you
want, but I wasn't able to get it to work after a few minutes of fiddling
and the actual usingMethods method doesn't seem to do anything on cursory
inspection in a toy example but I don't pretend to know the arcane depths
of the refclass machinery.

~G


On Wed, Oct 16, 2013 at 1:14 PM, Winston Chang <winstoncha...@gmail.com>wrote:

> Hi Gabriel -
>
> Thanks for your reply. The reason that I'm interested in doing it that
> way is because we're working on a project where we call a method and
> pass it the name of another method, and that method is accessed with $
> or [[.
>
> You might be right about [[ treating it as a standard environment.
> Reading the docs a little more closely, I found:
> "... The corresponding programming mechanism is to invoke a method on
> an object. In the R syntax we use "$" for this operation; one invokes
> a method, m1 say, on an object x by the expression x$m1(...)."
>
> This works as expected, but it is a bit clunky:
> `$`(.self, x)
>
> -Winston
>
>
> On Wed, Oct 16, 2013 at 3:08 PM, Gabriel Becker <gmbec...@ucdavis.edu>
> wrote:
> > Winston,
> >
> > Replying off list as I'm not an expert and don't have time to delve into
> > this enough to actually track it down.
> >
> > Is there a reason to expect [[ to work in this way? I've only ever
> > seen/written code that access fields/methods on reference classes via $
> > (which I assume has extra machinery for RefClasses to deal with active
> > binding functions for fields, etc).
> >
> > My guess would be that [[ is treating the reference class obj as a
> standard
> > environment which is bypassing some extra step necessary for refclass
> > objects and that is causing the problems.
> >
> >
> > I'd say its probably still a bug, but of the "why were you trying to do
> > that?" variety (no offense intended to you at all).
> >
> > All I can really suggest in the interim is to just use $ instead until
> John
> > (Chambers) pops up and responds to your mail.
> >
> > ~G
> >
> >
> > On Wed, Oct 16, 2013 at 12:47 PM, Winston Chang <winstoncha...@gmail.com
> >
> > wrote:
> >>
> >> When a reference class method is accessed with .self$x, it has
> >> different behavior from .self[['x']]. The former copies the function
> >> to the object's environment (with some attributes attached), and the
> >> latter just return NULL (unless it has already been accessed once with
> >> .self$x). Is this how it's supposed to work?
> >>
> >> Here's an example that illustrates: https://gist.github.com/wch/7013262
> >>
> >> TestClass <- setRefClass(
> >>   'TestClass',
> >>   fields = list(a = 'ANY'),
> >>   methods = list(
> >>     initialize = function() {
> >>       e <- environment()
> >>       pe <- parent.env(e)
> >>       ppe <- parent.env(pe)
> >>
> >>       # The environment of this object
> >>       print(ls(pe))
> >>       # The environment of the class
> >>       print(ls(ppe))
> >>
> >>       # No surprises with fields
> >>       cat("==================== .self[['a']] ====================\n")
> >>       print(.self[['a']])
> >>
> >>
> >>       # Getting b these ways isn't quite what we want
> >>       cat("==================== .self[['b']] ====================\n")
> >>       print(.self[['b']])
> >>       cat("==================== b ====================\n")
> >>       print(b)
> >>
> >>
> >>       # Accessing b with $ works, and it changes things from here on in
> >>       cat("==================== .self$b ====================\n")
> >>       print(.self$b)
> >>
> >>
> >>       # Now these return the b method with some attributes attached
> >>       cat("==================== .self[['b']] ====================\n")
> >>       print(.self[['b']])
> >>       cat("==================== b ====================\n")
> >>       print(b)
> >>
> >>
> >>       cat("===============================================\n")
> >>       print(ls(parent.env(e)))
> >>       print(ls(parent.env(parent.env(e))))
> >>
> >>     },
> >>
> >>     b = function() {
> >>       "Yes, this is b."
> >>     }
> >>   )
> >> )
> >>
> >> tc <- TestClass$new()
> >>
> >>
> >> Output:
> >> ============================================================
> >>
> >> [1] "a"          "initialize"
> >> [1] "b"         "e"         "tc"        "TestClass"
> >> ==================== .self[['a']] ====================
> >> An object of class "uninitializedField"
> >> Slot "field":
> >> [1] "a"
> >>
> >> Slot "className":
> >> [1] "ANY"
> >>
> >> ==================== .self[['b']] ====================
> >> NULL
> >> ==================== b ====================
> >> function() {
> >>       "Yes, this is b."
> >>     }
> >> ==================== .self$b ====================
> >> function() {
> >>       "Yes, this is b."
> >>     }
> >> <environment: 0x5a65418>
> >> attr(,"mayCall")
> >> character(0)
> >> attr(,"name")
> >> [1] "b"
> >> attr(,"refClassName")
> >> [1] "TestClass"
> >> attr(,"superClassMethod")
> >> [1] ""
> >> attr(,"class")
> >> [1] "refMethodDef"
> >> attr(,"class")attr(,"package")
> >> [1] "methods"
> >> ==================== .self[['b']] ====================
> >> function() {
> >>       "Yes, this is b."
> >>     }
> >> <environment: 0x5a65418>
> >> attr(,"mayCall")
> >> character(0)
> >> attr(,"name")
> >> [1] "b"
> >> attr(,"refClassName")
> >> [1] "TestClass"
> >> attr(,"superClassMethod")
> >> [1] ""
> >> attr(,"class")
> >> [1] "refMethodDef"
> >> attr(,"class")attr(,"package")
> >> [1] "methods"
> >> ==================== b ====================
> >> function() {
> >>       "Yes, this is b."
> >>     }
> >> <environment: 0x5a65418>
> >> attr(,"mayCall")
> >> character(0)
> >> attr(,"name")
> >> [1] "b"
> >> attr(,"refClassName")
> >> [1] "TestClass"
> >> attr(,"superClassMethod")
> >> [1] ""
> >> attr(,"class")
> >> [1] "refMethodDef"
> >> attr(,"class")attr(,"package")
> >> [1] "methods"
> >> ===============================================
> >> [1] "a"          "b"          "initialize"
> >> [1] "b"         "e"         "tc"        "TestClass"
> >>
> >>
> >>
> >> -Winston
> >>
> >> ______________________________________________
> >> R-devel@r-project.org mailing list
> >> https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> >
> >
> >
> > --
> > Gabriel Becker
> > Graduate Student
> > Statistics Department
> > University of California, Davis
>



-- 
Gabriel Becker
Graduate Student
Statistics Department
University of California, Davis

        [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to