- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当前深入的documentation on variable binding目标是Rebol2。有人可以提供Rebol 2和Rebol 2之间差异的摘要吗?
最佳答案
某处实际上没有摘要,因此让我们看一下基础知识,也许比Bindology非正式得多。让拉迪斯拉夫为R3和Red写他的论文的新版本。我们将按重要性顺序讨论基本差异。
对象和函数上下文
这是最大的不同。
在R2中,基本上有两种上下文:常规对象上下文和system/words
。两者都具有静态绑定,这意味着一旦运行bind
函数,单词绑定便会指向带有真实指针的特定对象。system/words
上下文可以在运行时进行扩展以包含新单词,但其他所有对象均不可以。函数使用常规对象上下文,并且当您递归调用函数时,有些黑客会窃取值块。self
单词只是对象上下文中第一个单词的常规单词,有一个显示骇客无法显示上下文中的第一个单词。函数上下文没有该单词,因此它们无法正确显示第一个常规单词。
在R3中,几乎所有这些都不同。
在R3中,还有两种上下文:常规和堆栈本地。对象,模块,绑定循环,use
,除了功能以外的所有内容都使用常规上下文,并且它们像system/words
一样是可扩展的(是的,“是”,我们将介绍)。旧的定长对象不见了。函数使用堆栈局部上下文,这些上下文(除非存在我们尚未看到的错误)不应该扩展,因为那样会弄乱堆栈框架。与旧的system/words
一样,您不能缩小上下文,因为从上下文中删除单词会破坏这些单词的任何绑定。
如果要在常规上下文中添加单词,则可以使用bind/new
,bind/set
,resolve/extend
或append
或其他调用这些功能的函数,具体取决于所需的行为。这是R3中bind
和append
函数的新行为。
像以前一样,将单词绑定到常规上下文和堆栈局部上下文是静态的。价值查询是另一回事。对于常规上下文,通过直接指向值插槽的静态块的简单指针间接完成值查找。对于堆栈局部上下文,值块由堆栈框架链接并从那里引用,因此要找到正确的框架,您必须执行O(stack-depth)的堆栈遍历。有关详细信息,请参见bug #1946-我们稍后将讨论原因。
哦,self
不再是一个普通的单词,它是一个绑定技巧,一个关键字。当您将单词块绑定到对象或模块上下文时,它将绑定关键字self
,该关键字被评估为对上下文的引用。但是,可以设置一个内部标志,该标志表示上下文是“无私的”,这将关闭该self
关键字。关闭该关键字后,您实际上可以在上下文中使用单词self
作为字段。绑定循环,use
和函数上下文为其上下文设置无私标志,而selfless?
函数对此进行检查。
该模型在涉及相当多的CureCode火焰战争中得到了完善和记录,就像R2的模型在1999-2000年间由REBOL邮件列表火焰战争记录的那样。 :-)
功能与闭包
当我在上面谈论堆栈局部函数上下文时,我指的是function!
类型函数所使用的上下文。 R3有很多函数类型,但是其中大多数都是一种或多种本机函数,并且本机函数不使用这些堆栈局部上下文(尽管它们确实获得了堆栈框架)。用于Rebol代码的唯一函数类型是function!
和新的closure!
类型。闭包与常规功能有很大不同。
创建function!
时,就是在创建函数。它构造一个堆栈局部上下文,将代码体绑定到该上下文,并将代码体和规范捆绑在一起。调用该函数时,它将创建一个带有对该函数上下文的引用的堆栈框架,并运行代码块。如果它在函数上下文中具有访问字,它将执行堆栈查找以找到正确的帧,然后从那里获取值。非常坦率的。
另一方面,创建closure!
时,将创建一个函数生成器。它设置规范和函数主体与function!
几乎相同,但是当您调用闭包时,它将创建一个新的常规无私上下文,然后对该主体进行bind/copy
,将对函数上下文的所有引用更改为副本中对新常规上下文的引用。然后,当它执行复制的正文时,所有闭包单词引用都与对象上下文的引用一样静态。
两者之间的另一个区别是它们在函数运行之前,函数运行期间和函数运行之后的行为。
在R2中,当函数未运行时,function!
上下文仍然存在,但是该函数的顶级调用的值块也仍然存在。只有递归调用才能获得新的价值块,顶级调用则保留了持久的价值块,就像我所说的那样。更糟糕的是,函数返回时不会清除顶级值块,因此最好确保您没有引用任何敏感内容,或者在函数返回时不要回收(使用also
函数进行清理,这就是我要做的)。
在R3中,当函数不运行时,function!
上下文仍然存在,但是值块根本不存在。所有功能调用的行为都类似于R2中的递归调用,但更好的是,因为它的设计完全向下,而是引用了堆栈框架。该堆栈框架的范围是动态的(如果需要历史记录,请跟踪Lisp风扇),因此,只要该函数在当前堆栈上运行(是的,“当前”,我们将介绍),可以使用它的单词之一来获取该函数最近一次调用的值。一旦该函数的所有嵌套调用返回,作用域中将没有任何值,并且您只会触发一个错误(错误的错误,但我们将对此进行修复)。
绑定到待办事项列表中的范围外功能词也有一个无用的限制,可以很快修复。有关详细信息,请参见bug #1893。
对于closure!
函数,在闭包运行之前,上下文根本不存在。一旦关闭开始运行,上下文便会创建并持久存在。如果再次或递归调用闭包,则会创建另一个持久上下文。从闭包泄漏的任何单词仅指的是在特定的闭包运行期间创建的上下文。
当函数或闭包未运行时,您无法获得绑定到R3中的函数或闭包上下文的单词。对于功能,这是一个安全问题。对于闭包,这是一个定义问题。
闭包被认为非常有用,以至于我和Ladislav都将它们分别移植到R2,这在不同的时间独立地产生了相似的代码,这很奇怪。我认为Ladislav的版本早于R3,并成为R3的closure!
类型的灵感来源。我的版本基于测试该类型的外部行为,并尝试在R2中为R2 / Forward复制它,因此很有趣的是,closure
的解决方案最终与Ladislav的原始解决方案非常相似,直到我才看到很久以后。我的版本从2.7.7开始包含在R2本身中,作为closure
,to-closure
和closure?
函数,并且closure!
字与R2中的function!
分配了相同的类型值。
全局与局部上下文
这是真正有趣的地方。
在Bindology中,有大量文章讨论了“全局”上下文(原来是system/words
)和“局部”上下文之间的区别,这对R2来说是相当重要的区别。在R3中,该区别无关紧要。
在R3中,system/words
不见了。没有一个“全局”上下文。按照R2的含义,所有常规上下文都是“本地”的,这使得“本地”的含义无用。对于R3,我们需要一套新的条款。
对于R3,唯一重要的区别是上下文是否是相对于任务的,因此“全局”上下文的唯一有用含义是不直接相对于任务的上下文,而“局部”上下文是相对于任务的上下文。在这种情况下,“任务”将是task!
类型,基本上是当前模型中的OS线程。
目前,在R3中,到目前为止(几乎是相对于任务)只有堆栈变量,这意味着相对于堆栈的函数上下文也应该相对于任务。这就是为什么stack walk必要的原因,因为否则我们将需要在每个函数上下文中保留和维护TLS指针。所有常规上下文都是全局的。
要考虑的另一件事是,根据该计划(到目前为止尚未实现),用户上下文system/contexts/user
和system
本身也旨在与任务相关,因此即使按照R3标准,它们也将被视为“本地”。 ”。而且由于system/contexts/user
基本上是R3与R2的system/words
最接近的东西,因此这意味着脚本认为它们的“全局”上下文实际上应该在R3中是任务本地的。
R3确实有几个称为sys
和lib
的系统全局上下文,尽管它们的使用与R2的全局上下文完全不同。同样,所有模块上下文都是全局的。
有可能(而且很普遍)存在仅从任务本地根引用中引用的全局定义的上下文,这样会使这些上下文实际上间接地成为任务本地的。当从“用户代码”调用绑定循环,use
,闭包或私有模块时,通常会发生这种情况,这基本上意味着非模块脚本已绑定到system/contexts/user
。从技术上讲,从模块调用的函数也是如此(因为函数是堆栈局部的),但是这些引用通常最终会分配给全局的模块字。
不,我们也没有同步。尽管如此,这还是R3设计最终应该拥有的模型,并且已经部分实现了。有关更多详细信息,请参见module binding article。
另外,R3现在具有真实的符号表,而不是使用system/words
作为临时符号表。这意味着R3中有效地消除了用来快速击中的单词限制R2。我不知道有任何应用程序达到了新的限制,甚至没有确定该限制有多高,尽管显然超过了上百万个不同的符号。现在我们可以访问它了,我们应该检查源代码以弄清楚。
加载和使用
末节。 use
函数使用none
初始化其单词,而不是不设置它们。并且因为没有R2中的“全局”上下文,所以load
不必完全绑定单词。 load
绑定到哪个上下文取决于module binding article中提到的情况,尽管除非另行指定,否则它将明确地将单词绑定到system/contexts/user
。两者现在都是夹层函数。
拼写和别名
R3与R2基本相同,默认情况下,单词绑定不区分大小写。单词本身是保留大小写的,如果使用区分大小写的方法进行比较,则会发现单词之间的区别仅在于大小写不同。
但是,在对象或函数上下文中,当一个单词映射到值槽时,则另一个单词绑定到该上下文或在运行时查找,只有大小写不同的单词才被认为是同一个单词,并且映射到相同的单词价值槽。
但是,发现使用alias
函数显式创建的别名,其中别名单词的拼写在其他方面有所不同,而不仅仅是大小写破坏了对象和函数上下文。在R2中,他们在system/words
中解决了这些问题,这使alias
太笨拙,无法在演示中使用,而不是很危险。
因此,我们完全删除了外部可见的alias
函数。内部别名功能仍然有效,因为它仅对通常被认为与上下文查找等效的单词进行别名,这意味着上下文不会中断。但是,我们现在建议使用演示中的alias
本地化和其他技巧(如果实践中从未使用过),请使用老式的方法,即使用新的拼写为另一个单词赋值,该方法已经完成。
字词类型issue!
类型现在是单词类型。您可以绑定它。到目前为止,没有人利用能够约束问题的优势,而只是使用提高的操作速度。
就是有意改变了。其余大部分差异可能是上述情况的副作用,甚至可能是错误或尚未实现的功能。 R3中甚至可能存在某些类似R2的行为,这也是错误或尚未实现的功能的结果。如有疑问,请先询问。
关于binding - 关于Rebol 2和3之间的绑定(bind)行为差异的总结是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14818324/
我需要修复 getLineNumberFor 方法,以便如果 lastName 的第一个字符位于 A 和 M 之间,则返回 1;如果它位于 N 和 Z 之间,则返回 2。 在我看来听起来很简单,但我不
您好,感谢您的帮助!我有这个: 0 我必须在每次点击后增加“pinli
Javascript 中是否有一种方法可以在不使用 if 语句的情况下通过 switch case 结构将一个整数与另一个整数进行比较? 例如。 switch(integer) { case
我有一列是“日期”类型的。如何在自定义选项中使用“之间”选项? 最佳答案 请注意,您有2个盒子。 between(在SQL中)包含所有内容,因此将框1设置为:DATE >= startdate,将框2
我有一个表,其中包含年、月和一些数字列 Year Month Total 2011 10 100 2011 11 150 2011 12 100 20
这个问题已经有答案了: Extract a substring between double quotes with regular expression in Java (2 个回答) how to
我有一个带有类别的边栏。正如你在这里看到的:http://kees.een-site-bouwen.nl/ url 中类别的 ID。带有 uri 段(3)当您单击其中一个类别时,例如网页设计。显示了一
这个问题在这里已经有了答案: My regex is matching too much. How do I make it stop? [duplicate] (5 个答案) 关闭 4 年前。 我
我很不会写正则表达式。 我正在尝试获取括号“()”之间的值。像下面这样的东西...... $a = "POLYGON((1 1,2 2,3 3,1 1))"; preg_match_all("/\((
我必须添加一个叠加层 (ImageView),以便它稍微移动到包含布局的左边界的左侧。 执行此操作的最佳方法是什么? 尝试了一些简单的方法,比如将 ImageView 放在布局中并使用负边距 andr
Rx 中是否有一些扩展方法来完成下面的场景? 我有一个开始泵送的值(绿色圆圈)和其他停止泵送的值(簧片圆圈),蓝色圆圈应该是预期值,我不希望这个命令被取消并重新创建(即“TakeUntil”和“Ski
我有一个看起来像这样的数据框(Dataframe X): id number found 1 5225 NA 2 2222 NA 3 3121 NA 我有另一个看起来
所以,我正在尝试制作正则表达式,它将解析存储在对象中的所有全局函数声明,例如,像这样 const a = () => {} 我做了这样的事情: /(?:const|let|var)\s*([A-z0-
我正在尝试从 Intellivision 重新创建 Astro-Smash,我想让桶保持在两个 Angular 之间。我只是想不出在哪里以及如何让这个东西停留在两者之间。 我已经以各种方式交换了函数,
到处检查但找不到答案。 我有这个页面,我使用 INNER JOIN 将两个表连接在一起,获取它们的值并显示它们。我有这个表格,用来获取变量(例如开始日期、结束日期和卡号),这些变量将作为从表中调用值的
我陷入了两个不同的问题/错误之间,无法想出一个合适的解决方案。任何帮助将不胜感激 上下文、FFI 和调用大量 C 函数,并将 C 类型包装在 rust 结构中。 第一个问题是ICE: this pat
我在 MySQL 中有一个用户列表,在订阅时,时间戳是使用 CURRENT_TIMESTAMP 在数据库中设置的。 现在我想从此表中选择订阅日期介于第 X 天和第 Y 天之间的表我尝试了几个查询,但不
我的输入是开始日期和结束日期。我想检查它是在 12 月 1 日到 3 月 31 日之间。(年份可以更改,并且只有在此期间内或之外的日期)。 到目前为止,我还没有找到任何关于 Joda-time 的解决
我正在努力了解线程与 CPU 使用率的关系。有很多关于线程与多处理的讨论(一个很好的概述是 this answer )所以我决定通过在运行 Windows 10、Python 3.4 的 8 CPU
我正在尝试编写 PHP 代码来循环遍历数组以创建 HTML 表格。我一直在尝试做类似的事情: fetchAll(PDO::FETCH_ASSOC); ?>
我是一名优秀的程序员,十分优秀!