Pd 补丁中可能存在的错误
Possible bug in Pd patch
我做了一个很简单的patch,当bang被触发的时候,就是触发一个0-2之间的唯一数字,也就是没有数字重复。
按照我设置的方式,它在理论上是有效的。甚至我的编程导师都说理论上应该可行,而且他通常是一个非常聪明的人。他被非正式地称为学院的棺材。
更多细节:
这种情况发生在 purr 数据和纯数据中,设置完全相同。
没有使用外部库。只是普通的 Vanilla 对象。
由于似乎没有办法附加实际文件本身,我将改为 post 代码图像:
问题在于深度优先处理(由 Pd 使用)和相关的堆栈展开,因为这可能导致将 [select]
的第二个输入设置为旧值(你没有没想到)。
例子
注:select:in0
表示[select]
最左边的入口,...[random]
生成的数字用粗体表示(1
) 并且补丁输出的数字以粗斜体显示(例如 3
)
假设 [select]
被初始化为 0
并且 [random 3]
对象输出一个列表 2 0 0 2 0 2 ...
(提示:[seed 96(
).
预期输出为 2 0 2 0 2 ...
,但实际输出为 2 0 2 2 2 ...
现在如果你连续发送 [bang(
到随机生成器会发生什么:
random
生成 2
2
被发送到 sel:in0
,它与 0
进行比较(不匹配)
- 从
sel:out1
(拒收出口)送出,显示号码2
- 之后,号码被发送到
sel:in1
,将其内部状态设置为 2
。
random
生成 0
0
被发送到 sel:in0
,它与 2
进行比较(不匹配)
- 从
sel:out1
发出,显示号码0
- 之后,号码被发送到
sel:1
,将其内部状态设置为 0
。
random
生成 0
0
被发送到 sel:in0
,它将它与 0
进行比较(匹配!)
- 并通过
sel:out0
(比赛出口)发送爆炸
- 触发对
random
的新调用,现在生成 2
2
被发送到 sel:in0
,它与 0
进行比较(不匹配)
- 从
sel:out1
发出,显示号码2
- 之后,号码被发送到
sel:1
,将其内部状态设置为 2
。
- 之后号码
0
(仍在 trigger:out0
中等待)被发送到 sel:1
,将其内部状态设置为 0
!!!
random
生成 0
0
被发送到 sel:in0
,它将它与 0
进行比较(匹配!)
- 并通过
sel:out0
发送一个 bang
- 触发对
random
的新调用,现在生成 2
2
被发送到 sel:in0
,它与 0
进行比较
- 从
sel:out1
发出,显示号码2
- 之后,号码被发送到
sel:1
,将其内部状态设置为 2
。
- 之后号码
0
(仍在 trigger:out0
中等待)被发送到 sel:1
,将其内部状态设置为 0
!!!
如您所见,在#3 的末尾,[select]
的内部状态是 0
,尽管 [random]
生成的最后一个数字是 2
(因为 [trigger]
最左边的出口只会在 发送 2
之后发送到 0
,由于堆栈展开)。
解决方案
解决方法很简单:确保[select]
的状态包含最后显示的值,而不是堆栈上生成的最后一个值。修改内部状态时避免反馈。
例如(使用本地 send/receive 以获得更好的 ASCII 艺术)
[r [=10=]-again]
|
[bang(
|
[random 3]
|
| [r [=10=]-last]
| |
[select]
| |
| [t f f]
| | |
| | [s [=10=]-last]
| |
| [print]
|
[s [=10=]-again]
我做了一个很简单的patch,当bang被触发的时候,就是触发一个0-2之间的唯一数字,也就是没有数字重复。
按照我设置的方式,它在理论上是有效的。甚至我的编程导师都说理论上应该可行,而且他通常是一个非常聪明的人。他被非正式地称为学院的棺材。
更多细节:
这种情况发生在 purr 数据和纯数据中,设置完全相同。
没有使用外部库。只是普通的 Vanilla 对象。
由于似乎没有办法附加实际文件本身,我将改为 post 代码图像:
问题在于深度优先处理(由 Pd 使用)和相关的堆栈展开,因为这可能导致将 [select]
的第二个输入设置为旧值(你没有没想到)。
例子
注:select:in0
表示[select]
最左边的入口,...[random]
生成的数字用粗体表示(1
) 并且补丁输出的数字以粗斜体显示(例如 3
)
假设 [select]
被初始化为 0
并且 [random 3]
对象输出一个列表 2 0 0 2 0 2 ...
(提示:[seed 96(
).
预期输出为 2 0 2 0 2 ...
,但实际输出为 2 0 2 2 2 ...
现在如果你连续发送 [bang(
到随机生成器会发生什么:
random
生成2
2
被发送到sel:in0
,它与0
进行比较(不匹配)- 从
sel:out1
(拒收出口)送出,显示号码2
- 从
- 之后,号码被发送到
sel:in1
,将其内部状态设置为2
。
random
生成0
0
被发送到sel:in0
,它与2
进行比较(不匹配)- 从
sel:out1
发出,显示号码0
- 从
- 之后,号码被发送到
sel:1
,将其内部状态设置为0
。
random
生成0
0
被发送到sel:in0
,它将它与0
进行比较(匹配!)- 并通过
sel:out0
(比赛出口)发送爆炸- 触发对
random
的新调用,现在生成2
2
被发送到sel:in0
,它与0
进行比较(不匹配)- 从
sel:out1
发出,显示号码2
- 从
- 之后,号码被发送到
sel:1
,将其内部状态设置为2
。
- 触发对
- 并通过
- 之后号码
0
(仍在trigger:out0
中等待)被发送到sel:1
,将其内部状态设置为0
!!!
random
生成0
0
被发送到sel:in0
,它将它与0
进行比较(匹配!)- 并通过
sel:out0
发送一个 bang- 触发对
random
的新调用,现在生成2
2
被发送到sel:in0
,它与0
进行比较- 从
sel:out1
发出,显示号码2
- 从
- 之后,号码被发送到
sel:1
,将其内部状态设置为2
。
- 触发对
- 并通过
- 之后号码
0
(仍在trigger:out0
中等待)被发送到sel:1
,将其内部状态设置为0
!!!
如您所见,在#3 的末尾,[select]
的内部状态是 0
,尽管 [random]
生成的最后一个数字是 2
(因为 [trigger]
最左边的出口只会在 发送 2
之后发送到 0
,由于堆栈展开)。
解决方案
解决方法很简单:确保[select]
的状态包含最后显示的值,而不是堆栈上生成的最后一个值。修改内部状态时避免反馈。
例如(使用本地 send/receive 以获得更好的 ASCII 艺术)
[r [=10=]-again]
|
[bang(
|
[random 3]
|
| [r [=10=]-last]
| |
[select]
| |
| [t f f]
| | |
| | [s [=10=]-last]
| |
| [print]
|
[s [=10=]-again]