Re: [R] type converters not being saved to workspace

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [R] type converters not being saved to workspace

John Chambers-2
(diverted to r-devel)

The problem seems to be rather that loading of the saved image takes
place _after_ the packages are attached.  So nothing that the methods
package does in its initialization will see the relevant type converters
or other methods objects.

More generally, loading into .GlobalEnv will never cause the equivalent
of cacheMetaData(.GlobalEnv).

It would be possible to hack the C code in main/saveload.c to generate a
call to cacheMetaData under the right circumstances, but is that the
best solution?

Intuitively, it's the objects containing the method/class definitions
that should trigger actions when they are loaded (emulating what happens
when the corresponding setMethod or setClass function call takes
place).  I.e., a load method for these classes of objects.  Possible?

It might be better, now that we're past feature freeze, to leave this as
a "design infelicity" for the upcoming release.


Prof Brian Ripley wrote:

> It is recommended that you use a package for this sort of thing.
>
> When a package is loaded, the S4 methods it contains are merged into
> the metadata.  When the global environment is loaded, they are not.  
> Call 'cacheMetaData(1)' to do so.
>
> [This looks like a bug: cacheMetaData is called on .GlobalEnv in the
> startup code for package methods, but seems not to work when called
> from there.  I think this is because package methods is not at that
> point on the search path (the call is from .onLoad) and hence the
> coerce() generic is not visible to cacheMetaData.  If you have S4 code
> in a package, it will ensure that package methods is attached before
> your package is loaded.]
>
> On Sun, 9 Apr 2006, Joseph Wang wrote:
>
>> Any one can explain why this happens or any work arounds?
>>
>>> setClass('foo')
>>
>> [1] "foo"
>>
>>> setAs('foo', 'character', function(from) from)
>>> showMethods('coerce')
>>
>>
>> Function "coerce":
>> from = "ANY", to = "array"
>> from = "ANY", to = "call"
>> from = "ANY", to = "character"
>> from = "ANY", to = "complex"
>> from = "ANY", to = "environment"
>> from = "ANY", to = "expression"
>> from = "ANY", to = "function"
>> from = "ANY", to = "integer"
>> from = "ANY", to = "list"
>> from = "ANY", to = "logical"
>> from = "ANY", to = "matrix"
>> from = "ANY", to = "name"
>> from = "ANY", to = "numeric"
>> from = "ANY", to = "single"
>> from = "ANY", to = "ts"
>> from = "ANY", to = "vector"
>> from = "ANY", to = "NULL"
>> from = "foo", to = "character"
>>
>>> q()
>>
>> Save workspace image? [y/n/c]: y
>>
>>
>> (restart)
>>
>>> showMethods('coerce')
>>
>>
>> Function "coerce":
>> from = "ANY", to = "array"
>> from = "ANY", to = "call"
>> from = "ANY", to = "character"
>> from = "ANY", to = "complex"
>> from = "ANY", to = "environment"
>> from = "ANY", to = "expression"
>> from = "ANY", to = "function"
>> from = "ANY", to = "integer"
>> from = "ANY", to = "list"
>> from = "ANY", to = "logical"
>> from = "ANY", to = "matrix"
>> from = "ANY", to = "name"
>> from = "ANY", to = "numeric"
>> from = "ANY", to = "single"
>> from = "ANY", to = "ts"
>> from = "ANY", to = "vector"
>> from = "ANY", to = "NULL"
>> from = "NULL", to = "OptionalFunction"
>>
>>>
>>
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide!
>> http://www.R-project.org/posting-guide.html
>>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [R] type converters not being saved to workspace

Brian Ripley
On Tue, 11 Apr 2006, John Chambers wrote:

> (diverted to r-devel)
>
> The problem seems to be rather that loading of the saved image takes place
> _after_ the packages are attached.  So nothing that the methods package does
> in its initialization will see the relevant type converters or other methods
> objects.

I am sorry, but that is not the case: see ?Startup. The image is loaded
_before_ the packages are attached (as documented).  You can check
explicitly by

env R_DEFAULT_PACKAGES=NULL R --restore
# R starts and loads the workspace
> library(methods)

and it still does not work (as I had tried before answering).

> More generally, loading into .GlobalEnv will never cause the equivalent of
> cacheMetaData(.GlobalEnv).
>
> It would be possible to hack the C code in main/saveload.c to generate a call
> to cacheMetaData under the right circumstances, but is that the best
> solution?
> Intuitively, it's the objects containing the method/class definitions that
> should trigger actions when they are loaded (emulating what happens when the
> corresponding setMethod or setClass function call takes place).  I.e., a load
> method for these classes of objects.  Possible?

Yes, but it will not help here as the objects are loaded without methods
being loaded.

I hope one day when we have S4 objects marked in the object headers that
loading such an object will load and attach the methods package.

> It might be better, now that we're past feature freeze, to leave this as a
> "design infelicity" for the upcoming release.

Definitely.

I think that package methods needs to cache metadata in its .onAttach not
.onLoad.  In principle it affects anything setting methods for generics in
package:methods, but if this is done in a package, the dependency on
methods will ensure that methods is loaded before the package, and then
library() will run cacheMetaData on the package.


> Prof Brian Ripley wrote:
>
>> It is recommended that you use a package for this sort of thing.
>>
>> When a package is loaded, the S4 methods it contains are merged into the
>> metadata.  When the global environment is loaded, they are not.  Call
>> 'cacheMetaData(1)' to do so.
>>
>> [This looks like a bug: cacheMetaData is called on .GlobalEnv in the
>> startup code for package methods, but seems not to work when called from
>> there.  I think this is because package methods is not at that point on the
>> search path (the call is from .onLoad) and hence the coerce() generic is
>> not visible to cacheMetaData.  If you have S4 code in a package, it will
>> ensure that package methods is attached before your package is loaded.]
>>
>> On Sun, 9 Apr 2006, Joseph Wang wrote:
>>
>>> Any one can explain why this happens or any work arounds?
>>>
>>>> setClass('foo')
>>>
>>> [1] "foo"
>>>
>>>> setAs('foo', 'character', function(from) from)
>>>> showMethods('coerce')
>>>
>>>
>>> Function "coerce":
>>> from = "ANY", to = "array"
>>> from = "ANY", to = "call"
>>> from = "ANY", to = "character"
>>> from = "ANY", to = "complex"
>>> from = "ANY", to = "environment"
>>> from = "ANY", to = "expression"
>>> from = "ANY", to = "function"
>>> from = "ANY", to = "integer"
>>> from = "ANY", to = "list"
>>> from = "ANY", to = "logical"
>>> from = "ANY", to = "matrix"
>>> from = "ANY", to = "name"
>>> from = "ANY", to = "numeric"
>>> from = "ANY", to = "single"
>>> from = "ANY", to = "ts"
>>> from = "ANY", to = "vector"
>>> from = "ANY", to = "NULL"
>>> from = "foo", to = "character"
>>>
>>>> q()
>>>
>>> Save workspace image? [y/n/c]: y
>>>
>>>
>>> (restart)
>>>
>>>> showMethods('coerce')
>>>
>>>
>>> Function "coerce":
>>> from = "ANY", to = "array"
>>> from = "ANY", to = "call"
>>> from = "ANY", to = "character"
>>> from = "ANY", to = "complex"
>>> from = "ANY", to = "environment"
>>> from = "ANY", to = "expression"
>>> from = "ANY", to = "function"
>>> from = "ANY", to = "integer"
>>> from = "ANY", to = "list"
>>> from = "ANY", to = "logical"
>>> from = "ANY", to = "matrix"
>>> from = "ANY", to = "name"
>>> from = "ANY", to = "numeric"
>>> from = "ANY", to = "single"
>>> from = "ANY", to = "ts"
>>> from = "ANY", to = "vector"
>>> from = "ANY", to = "NULL"
>>> from = "NULL", to = "OptionalFunction"
>>>
>>>>
>>>
>>> ______________________________________________
>>> [hidden email] mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide!
>>> http://www.R-project.org/posting-guide.html
>>>
>>
>
>

--
Brian D. Ripley,                  [hidden email]
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [R] type converters not being saved to workspace

John Chambers-2
Well, you  may be right, but my experiments certainly suggested
otherwise (below).

But my main point is that we should look for a better approach, and I
think we agree there.

Prof Brian Ripley wrote:

> On Tue, 11 Apr 2006, John Chambers wrote:
>
>> (diverted to r-devel)
>>
>> The problem seems to be rather that loading of the saved image takes
>> place _after_ the packages are attached.  So nothing that the methods
>> package does in its initialization will see the relevant type
>> converters or other methods objects.
>
>
> I am sorry, but that is not the case: see ?Startup. The image is
> loaded _before_ the packages are attached (as documented).


Perhaps.  But then why is it that if I put some trace printing in the
.First.lib of methods, that printing comes out before the message
"Previously saved  ...."?

> You can check explicitly by
>
> env R_DEFAULT_PACKAGES=NULL R --restore
> # R starts and loads the workspace
>
>> library(methods)
>
>
> and it still does not work (as I had tried before answering).

I'm not disputing that: the methods initialization did not call
cacheMetaData for the methods package itself--it was because the fix I
implemented to explicitly cache the generics in methods did NOT work
that I inferred the point about the ordering.  (Some printout is below,
but of course I'm not asserting that the fix might not have a different
problem in it.)

--------------------------
 enterprise:~/testR [160]> R

R : Copyright 2006, The R Foundation for Statistical Computing
Version 2.4.0 Under development (unstable) (2006-04-10 r37703)
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

cacheMetaData called for methods namespace
[Previously saved workspace restored]

R> names(getMethods("coerce")@methods)
[1] "ANY"      "function"
-----------------------------------
The methods from .GlobalEnv are not found until a second cacheMetaData
is done.



>
>> More generally, loading into .GlobalEnv will never cause the
>> equivalent of cacheMetaData(.GlobalEnv).
>>
>> It would be possible to hack the C code in main/saveload.c to
>> generate a call to cacheMetaData under the right circumstances, but
>> is that the best solution? Intuitively, it's the objects containing
>> the method/class definitions that should trigger actions when they
>> are loaded (emulating what happens when the corresponding setMethod
>> or setClass function call takes place).  I.e., a load method for
>> these classes of objects.  Possible?
>
>
> Yes, but it will not help here as the objects are loaded without
> methods being loaded.
>
> I hope one day when we have S4 objects marked in the object headers
> that loading such an object will load and attach the methods package.
>
>> It might be better, now that we're past feature freeze, to leave this
>> as a "design infelicity" for the upcoming release.
>
>
> Definitely.
>
> I think that package methods needs to cache metadata in its .onAttach
> not .onLoad.  In principle it affects anything setting methods for
> generics in package:methods, but if this is done in a package, the
> dependency on methods will ensure that methods is loaded before the
> package, and then library() will run cacheMetaData on the package.
>
>
>> Prof Brian Ripley wrote:
>>
>>> It is recommended that you use a package for this sort of thing.
>>>
>>> When a package is loaded, the S4 methods it contains are merged into
>>> the metadata.  When the global environment is loaded, they are not.  
>>> Call 'cacheMetaData(1)' to do so.
>>>
>>> [This looks like a bug: cacheMetaData is called on .GlobalEnv in the
>>> startup code for package methods, but seems not to work when called
>>> from there.  I think this is because package methods is not at that
>>> point on the search path (the call is from .onLoad) and hence the
>>> coerce() generic is not visible to cacheMetaData.  If you have S4
>>> code in a package, it will ensure that package methods is attached
>>> before your package is loaded.]
>>>
>>> On Sun, 9 Apr 2006, Joseph Wang wrote:
>>>
>>>> Any one can explain why this happens or any work arounds?
>>>>
>>>>> setClass('foo')
>>>>
>>>>
>>>> [1] "foo"
>>>>
>>>>> setAs('foo', 'character', function(from) from)
>>>>> showMethods('coerce')
>>>>
>>>>
>>>>
>>>> Function "coerce":
>>>> from = "ANY", to = "array"
>>>> from = "ANY", to = "call"
>>>> from = "ANY", to = "character"
>>>> from = "ANY", to = "complex"
>>>> from = "ANY", to = "environment"
>>>> from = "ANY", to = "expression"
>>>> from = "ANY", to = "function"
>>>> from = "ANY", to = "integer"
>>>> from = "ANY", to = "list"
>>>> from = "ANY", to = "logical"
>>>> from = "ANY", to = "matrix"
>>>> from = "ANY", to = "name"
>>>> from = "ANY", to = "numeric"
>>>> from = "ANY", to = "single"
>>>> from = "ANY", to = "ts"
>>>> from = "ANY", to = "vector"
>>>> from = "ANY", to = "NULL"
>>>> from = "foo", to = "character"
>>>>
>>>>> q()
>>>>
>>>>
>>>> Save workspace image? [y/n/c]: y
>>>>
>>>>
>>>> (restart)
>>>>
>>>>> showMethods('coerce')
>>>>
>>>>
>>>>
>>>> Function "coerce":
>>>> from = "ANY", to = "array"
>>>> from = "ANY", to = "call"
>>>> from = "ANY", to = "character"
>>>> from = "ANY", to = "complex"
>>>> from = "ANY", to = "environment"
>>>> from = "ANY", to = "expression"
>>>> from = "ANY", to = "function"
>>>> from = "ANY", to = "integer"
>>>> from = "ANY", to = "list"
>>>> from = "ANY", to = "logical"
>>>> from = "ANY", to = "matrix"
>>>> from = "ANY", to = "name"
>>>> from = "ANY", to = "numeric"
>>>> from = "ANY", to = "single"
>>>> from = "ANY", to = "ts"
>>>> from = "ANY", to = "vector"
>>>> from = "ANY", to = "NULL"
>>>> from = "NULL", to = "OptionalFunction"
>>>>
>>>>>
>>>>
>>>> ______________________________________________
>>>> [hidden email] mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>>> PLEASE do read the posting guide!
>>>> http://www.R-project.org/posting-guide.html
>>>>
>>>
>>
>>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel