我正在阅读Hands-on Programing with R,他在一个例子中创建了以下函数:
setup <- function(deck){
DECK <- deck
DEAL <- function(){
card <- deck[1,]
assign("deck",deck[-1,],envir = parent.env(environment()))
card
}
SHUFFLE <- function(){
random <- sample(1:52,52)
assign("deck",DECK[random,],envir = parent.env(environment()))
}
list(deal=DEAL, shuffle=SHUFFLE)
}
cards <- setup(deck)
deal <- cards$deal
shuffle <- cards$shuffle
甲板是here。
当我第一次呼叫deal
时,显示的环境为<environment: 0x9eea314>
。然后我开始处理函数deal()
,我发现如果再次调用setup(deck)
,交易功能将被重置。我这样做了,deal
的环境变为<environment: 0xad77a60>
,但令我惊讶的是,当我处理deal()
时,它已经停止了。我打电话给deal
,我看到事实上环境并没有改变。
发生了什么事?当我第一次设置交易功能时,无论我调用setup(deck)
多少次它都不会改变,或者我在其他环境中创建其他函数处理,而范围规则无法达到?
答案 0 :(得分:3)
我认为问题在于您想要查看的“牌组”位于cards
- 对象内。在shuffle()
之后,我们可以看到此行为:
> deal()
face suit value
17 ten clubs 10
> str(deck)
'data.frame': 52 obs. of 3 variables:
$ face : Factor w/ 13 levels "ace","eight",..: 6 8 5 11 7 2 9 10 3 4 ...
$ suit : Factor w/ 4 levels "clubs","diamonds",..: 4 4 4 4 4 4 4 4 4 4 ...
$ value: int 13 12 11 10 9 8 7 6 5 4 ...
所以我确实看到了你的困惑。我和你一样,期待在牌组中看到51张牌,我期待随机排列牌值和套牌(我们也看不到),但让我们继续......
> deal()
face suit value
37 three diamonds 3
> deal()
face suit value
23 four clubs 4
> str(cards)
现在让我们尝试找到deck
和shuffle
函数操纵的“真实”deal
- 对象,它显然与{{1}不同在deck
中保持不变的对象。 R函数实际上是闭包,它是代码和封闭环境的组合。考虑到这一点,让我们检查globalenv()
:
cards
现在检查> str(cards)
List of 2
$ deal :function ()
..- attr(*, "srcref")=Class 'srcref' atomic [1:8] 4 15 8 7 15 7 4 8
.. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x7f84081d3780>
$ shuffle:function ()
..- attr(*, "srcref")=Class 'srcref' atomic [1:8] 10 18 13 7 18 7 10 13
.. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x7f84081d3780>
内第一个函数的 environment :
cards
现在看一下那个环境中“deck”的价值:
> ls(env=environment(cards[[1]]))
[1] "DEAL" "deck" "DECK" "SHUFFLE"
所以我认为我们已经找到了我们应该关注的实际“甲板”对象(因为它具有正确的数字和随机排序),并且它不是{{1中的那个仍然(未改变)的那个}}。此外,这两个功能的环境是共享的:
str(environment(cards[[1]])$deck)
'data.frame': 49 obs. of 3 variables:
$ face : Factor w/ 13 levels "ace","eight",..: 4 1 13 7 11 13 8 2 2 3 ...
$ suit : Factor w/ 4 levels "clubs","diamonds",..: 4 1 4 1 3 3 4 3 4 1 ...
$ value: int 4 1 2 9 10 2 12 8 8 5 ...
...但是,如果在游戏过程中意外执行了globalenv()
,我认为游戏“语义”可能存在问题:
environment(cards[[2]])
#<environment: 0x7f84081702a8>
environment(cards[[1]])
#<environment: 0x7f84081702a8>