簡體   English   中英

如何在擴展S4類的R包中解決警告消息(未找到元數據對象;未導出SpatialLinesNULL類)

[英]How to resolve warning messages (metadata object not found; SpatialLinesNULL class not exported) in my R package which extends S4 classes

這是我在StackOverflow上的第一個問題,所以請更正我所做的任何協議錯誤。 但是我已經從網站上許多其他問題的答案中受益匪淺,因此在我進一步發展之前,我要感謝為該網站做出貢獻的社區

概觀

我正在使用R,使用RStudio,並在Windows 7機器上打包devtoolsroxygen2 (問題末尾的完整session_info

我正在嘗試編寫一個自己的包,它從包sp定義S4類SpatialLines子類,並且還使用包rgeos 當我使用devtools來documentload_all我的包時,我的問題與我不太了解並且無法完全解決的警告消息有關。

警告信息

第一條消息是

class "Spatial" is defined (with package slot ‘sp’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL’ 

當我解決這個問題時,通過在NAMESPACE文件中添加一個條目(沒有完全理解為什么有必要),然后對DESCRIPTION文件進行一次進一步的更改,我得到了第二條消息,到目前為止我已經被打敗了。

d> devtools::document()
Updating minweSpatialNULL documentation
Loading minweSpatialNULL
Error: class "SpatialLinesNULL" is not exported by 'namespace:rgeos'

我嘗試了什么,以及我留下的問題

我搜索並搜索了幾個尋找提示的網站,但我發現的最接近的是2011年12月的一個簡短的帖子,詢問SpatialLinesNULL來自哪里---答案是rgeos http://lists.r-forge.r-project.org/pipermail/rspatial-devel/2011-December/000033.html

我已經嘗試過嘗試去理解自己出了什么問題,然后在調試器中逐步執行代碼直到我迷路了,比我能夠更好地跟蹤以確定應該發生什么。 在這個過程中產生了一個小的(非)工作的問題的例子,如下所示。

我有3個問題。 它們在這里進行了總結,但實際上只有在下面的(不)工作玩具示例中才有意義:

  • 問題1 (在test1之后)為什么R無論如何都需要(虛擬?)超類Spatial ,為什么只有當我的代碼中定義了第二代 MyClass2
    澄清補充說我曾經認為R包裝命名空間機制在我實際使用的類有@importClassesFrom就已經處理了查找和訪問@importClassesFrom /超類的任何需要。
  • 問題2 (在測試3之后)我假設無論出於我的第一個警告信息的原因,也是這個類似信息的原因。
    我是在正確的軌道上嗎?
  • 問題3 (在test4之后)是test3的警告和隨后的錯誤我可以解決的問題(如果是這樣的話)? 或者我是否需要向rgeos包的rgeos尋求幫助(例如要求他們導出SpatialLinesNULL )?

代碼示例

我的玩具工作示例的r代碼(僅剝離roxygen注釋以節省空間)是:

MyClass1 <- setClass('MyClass1', contains = c('SpatialLines'))
MyClass2 <- setClass('MyClass2', contains = c('MyClass1'))

MyClass2第二代子類似乎很重要(如果沒有警告就會消失)。 我不懂為什么。

我使用devtoolsroxygen2對此代碼運行了一系列測試。 測試因NAMESPACE文件中的內容而異,以及DESCRIPTION文件中的Imports指令中的內容。 執行測試包括在RStudio中運行devtools::load_all() (或devtools::document() ,它沿途調用load_all() )。 發生的警告消息已在上面發布。 我在每個測試之間的干凈全局環境中重新啟動我的R會話(警告僅在我第一次運行load_alldocument )。

在跟進下面給出的答案時,我意識到我也應該嘗試使用shell命令行中的R來構建和安裝我的玩具包。

TEST1

test1有DESCRIPTION文件條目(有關完整的DESCRIPTION文件,請參閱此問題的結尾):

Imports:
    methods,
    sp

並且完整的NAMESPACE文件(從上面省略的roxygen注釋生成)是:

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

嘗試在重新啟動的R會話中運行devtools::load_all() (或devtools::document() )會生成第一個警告(如上所示)。

問題1為什么R無論如何都需要~~(虛擬?)~~超類Spatial ,為什么只有在我的代碼中定義了第二代MyClass2 澄清補充說我曾經認為R包裝命名空間機制在我實際使用的類有@importClassesFrom就已經處理了查找和訪問@importClassesFrom /超類的任何需要。

TEST2

test2通過更新NAMESPACE文件來解決問題,如警告消息所示。 沒有進行任何其他更改。

當完整的NAMESPACE文件為:時,警告消失:

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(sp,Spatial)
importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

TEST3

當我在DESCRIPTION文件中對Imports指令做了一個小的改動,即添加rgeos時,一個明顯相似的問題再次出現。 這是從test2創建test3場景的唯一更改。

Imports:
    methods,
    sp,
    rgeos

現在我收到一個警告,看起來像test1的問題,即:

class "SpatialLinesNULL" is defined (with package slot ‘rgeos’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL

據我SpatialLinesNULLSpatialLinesNULL是一個新的Spatial超類,在rgeos定義,因此它可以提供一些通用的函數和方法。

問題2我假設無論出於我的第一個警告信息的原因,也是這個類似信息的原因。
我是在正確的軌道上嗎?

TEST4

在TEST4我嘗試在test2的工作 ,即添加缺少的條目空間文件采用同樣的解決方案。 這是test4的完整NAMESPACE文件。

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(rgeos,SpatialLinesNULL)
importClassesFrom(sp,Spatial)
importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

在哪個階段我收到最后的錯誤消息:

d> devtools::document()
Updating minweSpatialNULL documentation
Loading minweSpatialNULL
Error: class "SpatialLinesNULL" is not exported by 'namespace:rgeos

在這個階段,我被困住了。

問題3來自test3的警告和隨后的錯誤我可以解決的問題(如果是這樣的話)? 或者我是否需要向rgeos包的rgeos尋求幫助(例如要求他們導出SpatialLinesNULL )?

session_info(來自test4)

d> devtools::session_info()
Session info --------------------------------------------------------------------------
 setting  value                       
 version  R version 3.1.2 (2014-10-31)
 system   x86_64, mingw32             
 ui       RStudio (0.98.953)          
 language (EN)                        
 collate  English_Australia.1252      
 tz       Australia/Sydney            

Packages ------------------------------------------------------------------------------
 package          * version    date       source        
 devtools         * 1.7.0.9000 2015-02-20 local         
 lattice          * 0.20-29    2014-04-04 CRAN (R 3.1.2)
 minweSpatialNULL * 0.0.0.9000 <NA>       local         
 Rcpp             * 0.11.4     2015-01-24 CRAN (R 3.1.2)
 rgeos            * 0.3-8      2014-09-21 CRAN (R 3.1.2)
 roxygen2         * 4.1.0.9001 2015-02-21 local         
 rstudio          * 0.98.953   2014-08-02 local         
 rstudioapi       * 0.2        2014-12-31 CRAN (R 3.1.2)
 sp               * 1.0-17     2015-01-08 CRAN (R 3.1.2)
 stringr          * 0.6.2      2012-12-06 CRAN (R 3.1.1)
d>

test4的完整文件

R / myclasses.r

#------------------------------------------------------------------------------
#' MyClass1
#' 
#' A subclass of SpatialLines
#' 
#' MyClass1 is a subclass of sp::SpatialLines.
#' @importClassesFrom sp SpatialLines Spatial
#' @importFrom sp SpatialLines
#' @importClassesFrom rgeos SpatialLinesNULL
MyClass1 <- setClass('MyClass1', contains = c('SpatialLines'))

#------------------------------------------------------------------------------
#' MyClass2
#' 
#' A subclass of MyClass1
#' 
#' MyClass2 is a subclass of MyClass1 and a 2nd generation subclass of
#' sp::SpatialLines.
#' @importClassesFrom sp SpatialLines
MyClass2 <- setClass('MyClass2', contains = c('MyClass1'))

描述文件

Package: minweSpatialNULL
Title: Minimum Example of my Problem with SpatialLinesNULL
Version: 0.0.0.9000
Authors@R: person("Geoff", "Lee", , "geoff.lee@gmail.com", role = c("aut", "cre"))
Description: (Hopefully) demonstrates my problem with warnings
  that I cannot seem to eradicate. 
Depends: R (>= 3.1.2)
Imports:
    methods,
    sp,
    rgeos
License: GPL (>= 2.0)
LazyData: true

NAMESPACE文件

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(rgeos,SpatialLinesNULL)
importClassesFrom(sp,Spatial)
importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

結論

非常感謝您提供的任何幫助,建議或指導! 即使只是關於我如何提出一個更好的問題:-)

謝謝你提出這個廣泛的問題。 我有兩個建議來改進它。 首先,提供一個可重現的示例,在這種情況下,它將是一個最小的包,讓我們重現您的警告或錯誤消息。 例如,

MyClass1 <- setClass('MyClass1', contains = c('SpatialLines'))
MyClass2 <- setClass('MyClass2', contains = c('MyClass1'))

sp加載的會話中工作正常,但是在包代碼中執行此操作時出現的問題。 創建這樣的包意味着做了很多猜測工作:我們沒有看到你完整的NAMESPACE ,因此不知道你導出了什么,並希望在加載你的包之后在R會話中工作。 第二:將您的問題與使用devtools引起的問題隔離開來(即,使用構建和安裝軟件包的標准R軟件包開發術語)。

根據您提供的內容,我只能回答:

  • Q1: Spatial不是一個虛擬類,它存在,因為它定義了所有派生類的共同點(CRS和一個邊界框),並且它是必需的,因為為它定義了對所有派生類進行操作的方法。 需要它的MyClass2與你的包有關,我沒有
  • Q2:我無法回答,因為你沒有顯示導致Q1的警告。 此外, SpatialLinesNULL不是Spatial的超類,而是SpatialLines的超類,由

    setClassUnion("SpatialLinesNULL", c("SpatialLines", "NULL"))

  • 問題3:您可以嘗試編譯導出此類的rgeos的修改版本; 如果你提供了一個很好的用例(一個可以重現你的問題的最小包), rgeos一個開發人員會調查它。

這個答案匯集了我所學到的與我提出的一系列問題有關的所有信息,以便遇到遇到類似問題的其他人。

事實證明,回答問題的順序與答案相反更容易。

真正解決我的具體問題的方面是由@Edzer Pebesma提供的 - 我感謝你。

約翰·錢伯斯回答了我在r-devel郵件列表上提出的問題的更具體的后續問題,這確實有助於彌補我對為什么發出警告信息的理解上的空白 - 我也非常感謝他的指導和幫助。

以下解釋中的任何錯誤完全屬於我自己!

此問題和答案中引用的玩具包的test4版本曾在http://github.com/Geoff99/Examples/tree/SpatialLinesNULL < - 其他的github倉庫中的 - >文件夾SpatialLinesNULL的文件夾SpatialLinesNULL中找到可以通過從NAMESPACE和DESCRIPTION文件中刪除一行或兩行來構造測試序列的版本。

2017年5月6日更新 - test4版本代碼移至https://gist.github.com/Geoff99/29be25bce4cd4c918921bf68769c6a39

問題3(測試后4)

來自test3的警告和隨后的錯誤我可以解決的問題(如果是這樣的話)? 或者我是否需要向rgeos包的維護者尋求幫助(例如要求他們導出SpatialLinesNULL)?

test3的警告是

class "SpatialLinesNULL" is defined (with package slot ‘rgeos’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL

並且來自test4的錯誤消息是

d> devtools::document()
Updating minweSpatialNULL documentation
Loading minweSpatialNULL
Error: class "SpatialLinesNULL" is not exported by 'namespace:rgeos

對此的最佳解決方案是接近rgeos包的rgeos並要求他們導出警告和錯誤消息中提到的缺少的SpatialLinesNULL類。 Edzer Pebesma為我回答了這個問題,並對rgeos包進行了必要的更新,對此我非常感激。 在安裝了包rgeos的升級版本之后,我可以簡單地將importClassesFrom(rgeos,SpatialLinesNULL)到我的玩具包的NAMESPACE文件中,並且警告消失了。

如果您遇到類似情況的不同套餐,那就是我推薦的策略。

懷疑有一種方法可以自己解決這個問題(主要是通過在我的包的命名空間環境中手動制作關於SpatialLinesNULL class的缺失元數據的副本,這基本上是methods包在發出警告后自行執行的操作)---但是這是一個混亂的黑客 ,我將不會解釋如何。 如果你真的需要在將來的某個階段做到這一點,問題1(下面)的答案會收集我需要理解的信息,以弄清楚如何進行黑客攻擊

問題2(測試后3)

我假設無論出於我的第一個警告信息的原因是什么,也是這個類似信息的原因。 我是在正確的軌道上嗎?

test3的警告是

class "SpatialLinesNULL" is defined (with package slot ‘rgeos’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL

test1的第一個警告是

class "Spatial" is defined (with package slot ‘sp’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL’ 

答案是肯定的 ,兩條消息出於同樣的原因。

警告消息都是由名為.findOrCopyClass的函數生成的,它是方法包中的內部(即非導出)函數。 要查看此函數的代碼,必須使用:::運算符。 methods:::.findOrCopyClass鍵入R控制台。 (這需要加載方法包,它幾乎總是如此)。 .findOrCopyClass在找不到定義類的元數據時發出此警告,因此必須復制元數據。

請參閱下文,了解元數據是什么,為什么需要將其包含在我的玩具包的命名空間中,以及(我最好的猜測)為什么會發出此警告。

.findOrCopyClasssetIs ,它是methods包中的導出函數。 反過來setIs被方法函數setClass調用(幾次),我在玩具包示例中調用它。 鍵入?setIs?setClass以獲取有關這些函數的更多信息。 或者,如果要查看源代碼,只需在R控制台中鍵入setIssetClass即可。

問題1(測試后1)

為什么R還需要~~(虛擬?)~~超類空間~~,為什么只有當我在我的代碼中定義了第二代MyClass2時~~?

澄清補充說:我曾經認為R包裝命名空間機制在我實際使用的類中有@importClassesFrom會考慮找到和訪問@importClassesFrom /超類的任何需要。

首先道歉和糾正。

  • 原問題的一部分問:

    為什么只有當我的代碼中定義了第二代MyClass2時?

    是完全錯的。 盡管我在發布問題之前進行了檢查,但我必須在不知不覺中仍然在我的globalenv()緩存一些隱藏的信息。 即使我的玩具包中只定義了MyClass1 ,也存在潛在的問題。

  • Spatial不是虛擬類。 SpatialLinesNULL 一個虛擬類。 超類是否是虛擬的與此問題無關。

  • 這個問題確實有很大關系
    • 定義超類的地方(在我的玩具示例中, Spatial來自spSpatialLinesNULL來自rgeos
    • 是否從該包導出超類定義(在玩具示例中, sprgeos
    • 和R因此能否以及如何找到超定義時,它被檢查和安裝新的軟件包(如minweSpatialNuULL它使用一個類(如) SpatialLines ),其父母包括超(如SpatialSpatialLinesNULL )。

缺少的元數據警告消息是什么

以下是methods包的文檔部分注釋。 我花了一段時間來掌握,但這與我開始時的低知識基礎有關。 文檔非常有用,如果你做到這一點,我建議你閱讀它。 我發現?setClass?Classes?getClassDef?classMetaName?setIs特別有價值。

setClass做了什么

來自?setClass文檔(重點由我添加):

創建一個類定義,指定表示(插槽)和/或此類中包含的類(超類),以及其他可選的詳細信息。 作為副作用,類定義存儲在指定的環境中 生成器函數作為setClass()的值返回,如果類不是虛擬的,則適合於從類創建對象。

methods:::.findOrCopyClass發出的警告消息與類定義的創建和存儲有關。 類定義是(或存儲在?中)元數據對象。

什么是元數據對象

?Classes文檔:

類定義是包含R對象類的形式定義的對象,...和

定義類時,將存儲包含有關該類的信息對象。 該對象(稱為定義類的元數據 )不存儲在類的名稱下(以允許程序員編寫該名稱的生成函數),而是存儲在特殊構造的名稱下。 要檢查類定義,請調用getClass 元數據對象中信息包括

  • 插槽......
  • 超級班 ......
    • 有關類和特定超類之間關系的信息被編碼為類SClassExtension的對象。 超類(有時是子類)的此類對象的列表包含在定義類的元數據對象中
  • 原型......

methods包就是創建和管理這些元數據對象(對於S4類,並且盡可能為舊的S3類創建和管理)。

新類的元數據對象(例如MyClass1 )包含有關其定義中任何槽的信息(因為MyClass1指定contains = c('SpatialLines')它繼承SpatialLines類中的所有槽,在包sp定義)。

重要的是,類的元數據對象必須包含有關任何超類的信息 - 否則新類如何從其父類(即超類)繼承任何內容? 不管怎樣,有關超類的信息必須一直到達繼承樹。 在該示例中, MyClass1具有一個超類SpatialLines的距離,因此繼承了SpatialLines所有更遠的祖先,無論他們是誰。

  • 我想我在某個地方讀過,但是錯誤地指出了鏈接,元數據對象可能處於兩種狀態 - 不完整或完整。 在不完整的狀態中,新類的超類列表(例如MyClass1 )可能(尚未)在繼承鏈中一直填充,而在使用類定義時,R必須遍歷繼承鏈,並填寫了完整的家譜譜 檢查或安裝包時,必須完成繼承鏈 - 如果之前尚未完成,則必須在install.packages步驟中完成。
如何查看元數據對象

使用getClassgetClassDef 查看給定類的元數據對象。

文檔?getClass?getClassDef解釋了哪些環境R搜索元數據對象。 需要注意的一個關鍵事項是, 找到包中定義的類的元數據對象之前,必須至少加載一個包。

以下是我的玩具包( minweSpatialNULL )中的一些示例,它們加載了版本0.3-9的rgeos ,它確實導出了SpatialLinesNULL類。 請注意:

  • MyClass1知道它的所有父超類(通常的情況),和
  • 盡管rgeos本身對MyClass1MyClass2一無所知,但SpatialLinesNULL (它是rgeos包中定義的Class Union幾乎知道它的所有子

     d> getClass('MyClass1') Class "MyClass1" [package "minweSpatialNULL"] Slots: Name: lines bbox proj4string Class: list matrix CRS Extends: Class "SpatialLines", directly Class "Spatial", by class "SpatialLines", distance 2 Class "SpatialLinesNULL", by class "SpatialLines", distance 2 Known Subclasses: "MyClass2" d> getClass('SpatialLinesNULL') Extended class definition ( "ClassUnionRepresentation" ) Virtual Class "SpatialLinesNULL" [package "rgeos"] No Slots, prototype of class "NULL" Known Subclasses: Class "NULL", directly Class "SpatialLines", directly Class ".NULL", by class "NULL", distance 2, with explicit coerce Class "SpatialLinesDataFrame", by class "SpatialLines", distance 2 Class "MyClass2", by class "MyClass1", distance 3 d> 
  • 實際上,有點好奇SpatialLinesNULL知道MyClass2因為它是MyClass1的子類,但似乎沒有直接提到MyClass1本身。 我還沒弄清楚為什么呢。

為什么超類列表可以更改

關於為什么我的玩具MyClass1類的超類列表在我沒有更改我的包而不是將rgeos添加到玩具包的DESCRIPTION文件中的Imports指令時,我感到困惑。

原因是方法包非常聰明。 除了定義子類之外,還可以在定義該類之后 ,將父超類插入到的族樹(繼承鏈)中。

一種簡單的方法是使用setClassUnion (類型?setClassUnion來解釋)。 這就是rgeos在定義SpatialLinesNULLSpatialLinesNULL - 它為SpatialLines創建了一個新的父SpatialLines 這就是為什么只要我在玩具包DESCRIPTION文件中添加了rgeos條目, rgeosMyClass1突然獲得另一個超類。 在交互式設置中,可能會發生類似的事情,這取決於我是否加載(或附加和加載) rgeos包。

事后也有一種更復雜的方式來添加祖先 - 參見?setIs

元數據對象的名稱

與所有其他對象一樣,R通過其名稱查找元數據對象。 如果在包中定義了對象,則該對象的名稱存在

  • 包的命名空間環境(例如environment: namespace:minweSpatialNULL ),或
  • 包的導入環境(例如environment: imports:minweSpatialNULL )。

再次從?Classes文檔中:

定義類時,將存儲包含有關該類的信息的對象。 該對象(稱為定義類的元數據)不存儲在類的名稱下 (以允許程序員編寫該名稱的生成函數), 而是存儲在特殊構造的名稱下。

您可以使用方法包提供的classMetaName函數找到特殊構造的名稱 - 有關詳細信息,請參閱?methods::classMetaName

從我的玩具包中獲取的元數據對象名稱的示例是:

 d> classMetaName('MyClass1') [1] ".__C__MyClass1" 

因為領先. 該元數據對象的名稱(即.__C__MyClass1 ),通常是隱藏的,當你ls包的命名空間環境-但你可以用它看all.names = TRUE參數ls

 d> # Recall that MyClass1 is the name I chose for the generator function d> # returned by setClass when I defined the class MyClass1 d> env_toy_package <- environment(MyClass1) d> ls(env_toy_package, all.names=TRUE) [1] ".__C__MyClass1" ".__C__MyClass2" ".__DEVTOOLS__" [4] ".__NAMESPACE__." ".__S3MethodsTable__." ".packageName" [7] "MyClass1" "MyClass2" d> 

如果你查看包命名空間環境的parent.env (即imports:minweSpatialNULL命名空間環境),你會發現MyClass1超類的隱藏名稱,這就是.findOrCopyClass正在尋找的東西,所以它們可以放在那里! 。

 d> parent.env(env_toy_package) <environment: 0x0000000008df59d8> attr(,"name") [1] "imports:minweSpatialNULL" d> ls(parent.env(env_toy_package), all.names = TRUE) [1] ".__C__Spatial" ".__C__SpatialLines" ".__C__SpatialLinesNULL" [4] "library.dynam.unload" "SpatialLines" "system.file" d> 
最后 ,'。findOrCopyClass`警告的內容是什么

.findOrCopyClass發出警告時,例如:

 class "Spatial" is defined (with package slot 'sp') but no metadata object found to revise subclass information---not exported? Making a copy in package 'minweSpatialNULL' 

該函數讓我知道它無法找到隱藏的名稱.__C__Spatial它搜索的命名空間中的空間並修改該名稱綁定的對象中的元數據。 它知道隱藏名稱應該在哪里---它必須來自包sp ,因為來自SpatialLines類的元數據對象本身表示其父超類( Spatial )所在的位置。 一個祖先超類中的元數據對象的完整規范包括package含其中定義所述祖先超類的包的名稱屬性, 以防萬一兩個現有加載的包恰好選擇了相同的名稱的一類!

這就是為什么importClassesFrom從缺少的超類工作 - 它將缺少的隱藏名稱帶入imports:minweSpatialNULL minweSpatialNULL玩具包的imports:minweSpatialNULL環境,點.findOrCopyClass可以從中找到它們,並在必要時更新它們。

為什么.findOrCopy會發出警告

我想知道為什么.findOrCopyClass告訴我它找不到元數據對象,當它說下一件事是它在我的包命名空間中制作副本時! 我在r-devel郵件列表上提出了這個問題,John Chambers親切地為我回答了這個問題(我強調了這個問題):

查找類定義的目的是更新新關系的條目,如警告消息所示。 這要求保存定義的命名空間是可寫的

在子類信息的情況下, 如果原始命名空間不是當前正在加載的包,則很可能被鎖定 復制定義以更新子類信息似乎是唯一合理的選擇,並且不需要警告消息。

修訂版將省略此消息。

我剩下的概念問題與對象名稱 (例如函數或類(確切地說,函數對象或類元數據對象))之間的差異以及對象本身發生的情況之間的差異有關。 或者換句話說,是否需要更新命名空間(可能是鎖定的),或者對象本身的(狀態)是否需要更新。

事實證明,' findorCopyClasses並沒有抱怨它找不到(非導出的)超類,而是它無法在超類的值可以更改的地方找到它。

鎖定意味着什么

?base::bindenv文檔說:

“具有命名空間的包的命名空間環境在加載時會被鎖定。”

一個鎖定的環境意味着

“阻止在環境中添加或刪除變量綁定。除非綁定已被鎖定,否則仍可以更改變量的值”

但是一些實驗表明,除了包命名空間環境被鎖定外,imports:namespace中的綁定也被鎖定。 鎖定綁定意味着:

“無法更改鎖定綁定的值”。

因此,由於超類元數據對象來自另一個包(例如rgeos ),因此它在其他包的命名空間中的綁定被鎖定,因此其值不能被更改。 或者就示例而言,當方法包想要將Myclass1MyClass2添加到SpatialLinesNULL '擁有'的子類列表時,它發現它不能因為SpatialLinesNULL的綁定(或者確切地說是隱藏名稱的綁定) .__C__SpatialLinesNULL )已被鎖定。 因此有關需要復制的消息!

復制的替代方法可能是臨時解鎖otherpackage的命名空間中的綁定,更新對象,並重新綁定綁定 - 但由於我剛剛學習了鎖定環境和綁定,我不知道它的后果可能是什么是。 我會獨自離開。

好的,如果未導出所需的超類,如何破解解決方案

警告我沒有測試過這么多,無論如何這是一個主意,但如果你真的非常渴望得到警告信息消失......

步驟1。 查看警告消息,找到缺少的超類的(文本)名稱及其來源。

第2步。 使用classMetaName查找缺少的未導出超類的隱藏和損壞的名稱。 對於超類MissingSuperclass它可能是.__C__MissingSuperclass

第三步。 在調用setClass創建自己的類之前,使用:::方法訪問元數據對象(即donorpackage:::.__C__MissingSuperclass )並在屬於您的包的適當環境中為其指定適當的名稱(即.__C__MissingSuperclass )。

正如我已經說過的那樣,這是一個非常糟糕的主意,因為在腳下射擊自己會非常容易,為什么還要煩惱,因為在發出警告信息之后,這基本上就是.findOrCopyClasssetIs似乎做的事情。無論如何。

結束

如果您已經讀過這篇文章,我希望這對您有所幫助! 我已經寫了這么長的時間,主要是作為未來我的教程:-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM