当我运行此代码时:
to myself1
create-turtles 1
let a "a"
ask turtle 0 [
show a
show self
ask patch-here [
show a
show self
show myself
]
]
end
我得到了这个输出:
(turtle 0): "a"
(turtle 0): (turtle 0)
(patch 0 0): "a"
(patch 0 0): (patch 0 0)
(patch 0 0): (turtle 0)
因此,ask patch
代码区self
内部引用了修补程序,而myself
引用了turtle 0
。
这就是NetLogo用户手册(和示例代码)所期望的。
我不清楚为什么self
应该引用补丁而不是turtle 0
。
不可否认,自从我编写任何Java以来已经很长时间了,但我的理解是匿名函数中的this
指的是嵌入函数的对象。相比之下,上面代码中的self
指的是运行代码的补丁 - 而不是self
在词汇上出现的乌龟。此外,可以从代码块中访问本地变量a
。
决定使代码块本地self
,可能是为了提供一种方法来引用正在执行该块的代理,这要求NetLogo定义另一种方式来引用调用上下文。这是myself
的函数,如示例输出所示。
更一般地说,即使在单独的函数中使用,myself
似乎也会引用调用乌龟。
to myself2
let a "a"
ask turtle 0 [
show a
show self
ask patch-here [ myself2' ]
]
end
to myself2'
; show a
show self
show myself
end
输出结果为:
(turtle 0): "a"
(turtle 0): (turtle 0)
(patch 0 0): (patch 0 0)
(patch 0 0): (turtle 0)
因此可以从单独的函数访问myself
并返回调用乌龟。但似乎相似的变量a
无法访问。如果show a
未被注释掉,NetLogo会发出一条错误消息,指出a
中未定义myself2'
。 (换句话说,NetLogo一般不会实现动态范围,即使这些示例似乎表明它适用于self
和myself
。)
所以,对不起长时间的预备。我的问题是关于解释用于self
和myself
的准动态范围的最佳方法,而不是用于a
等局部变量。公平地说self
和myself
只是 ad hoc 特殊情况,还是有更好的方式来讨论它?
答案 0 :(得分:0)
很棒的问题。
self
和myself
所代表的概念根本不存在于其他编程语言中。其他编程语言没有“#34;代理执行此代码的概念”,因为这些语言首先不是基于代理的。
OO语言中与this
的任何类比都是最好的,并且在最坏的情况下会产生误导。
self
和myself
在定义时非常有用,如果它们没有出现在语言中,并且有定义,那么您在尝试编码各种各样的东西。这是我能给出的最好的简短答案,为什么他们被定义为:他们有用。
至于a
等局部变量的范围行为,我认为这是一个单独的问题。您当然可以想象尝试提出某种基于代理的局部变量定义,其中a
类似于临时创建代理变量。对我而言,这样的设计是否可行或甚至是可取的并不是显而易见的,但无论如何,我们并没有这样做,我认为我们甚至没有认真研究过这种可能性
NetLogo中的局部变量与其他词法范围的语言中的局部变量完全相同。他们没有参与基于代理的语言性质。