在TCL中声明常量是什么方法?

时间:2020-10-10 18:25:11

标签: tcl

我在其他地方读过,可以使用关键字set在TCL中创建常量。但是,当我查看math包的源代码时,我发现math常量是以不同的方式声明的。请参阅下面的code

package provide math::constants 1.0.1

# namespace constants
#    Create a convenient namespace for the constants
#
namespace eval ::math::constants {
    #
    # List of constants and their description
    #
    variable constants {
        pi        3.14159265358979323846   "ratio of circle circumference and diameter"
        e         2.71828182845904523536   "base for natural logarithm"
        ln10      2.30258509299404568402   "natural logarithm of 10"
        phi       1.61803398874989484820   "golden ratio"
        gamma     0.57721566490153286061   "Euler's constant"
        sqrt2     1.41421356237309504880   "Square root of 2"
        thirdrt2  1.25992104989487316477   "One-third power of 2"
        sqrt3     1.73205080756887729533   "Square root of 3"
        radtodeg  57.2957795131            "Conversion from radians to degrees"
        degtorad  0.017453292519943        "Conversion from degrees to radians"
        onethird  1.0/3.0                  "One third (0.3333....)"
        twothirds 2.0/3.0                  "Two thirds (0.3333....)"
        onesixth  1.0/6.0                  "One sixth (0.1666....)"
        huge      [find_huge]              "(Approximately) largest number"
        tiny      [find_tiny]              "(Approximately) smallest number not equal zero"
        eps       [find_eps]               "Smallest number such that 1+eps != 1"
    }
    namespace export constants print-constants
}
  1. 变量常量”是字典吗?看来是这样。但是变量是什么关键字?
  2. 为什么我们需要 namespace eval 然后又需要 namespace export ?我的意思是为什么不只说一次命名空间:: math :: constants并留在那儿呢?
  3. 我们为什么需要此行 namespace导出常量print-constants
  4. 为什么不只使用TCL set命令创建常量?
  5. 是真的我们不能在TCL中真正拥有常量(例如C中的const关键字),并且所有内容都可以重新定义为我们想要的东西吗?这不会对这种语言造成安全性问题吗?

1 个答案:

答案 0 :(得分:2)

  1. “变量常量”是字典吗?看来是这样。但是哪个关键字是变量?

不是(或者是,而是偶然)。它定义的每个事物在定义中都有三个 words ,字典中每个映射条目严格都有两个单词。

variable命令记录在:https://www.tcl-lang.org/man/tcl8.6/TclCmd/variable.htm

  1. 为什么我们同时需要namespace evalnamespace export?我的意思是为什么不只说一次namespace ::math::constants而就这样呢?
  2. 我们为什么需要此行namespace export constants print-constants

namespace export定义了哪些命令是从名称空间导出的,即哪些命令可以由其他地方namespace import使用。不假设所有命令都已导出。不假设名称空间会导出与其自身名称相同的命令。不会导出变量(但是可以实现类似的效果;在命名空间变量之间很少这样做)。

如果您在namespace ensemble中使用默认值,或者继续使用TclOO,则此更改。那些 do 做(记录!)默认假设。

变量和命令完全是不同的东西。它们使用不同的名称空间(即,每个名称空间中具有不同的哈希表),并且不能混淆。 math::constants程序包提供了执行其他操作的命令,但这只是该程序包的一个功能,并不通用。

许多名称空间从不导出任何命令。没关系的始终可以使用完全限定的名称来访问命令和变量。

  1. 为什么不只使用TCL set命令创建常量?

您可以在全局名称空间中。按照惯例,通用库会尝试将其留给Tcl本身(尽管Tcl还保留了一些名称空间,尤其是::tcl)和应用程序,即代码。

但是在非根名称空间中,出于我认为最好将其视为错误的严重丑陋原因,最好使用variable命令创建变量。从技术上讲,这不是错误,而是变量解析的极端结果,我非常讨厌。 (我认为它会从Tcl 9.0中消失。)用可能的另一种方式来做,但是可能不行,而且您确实不希望仅使用 might < / em>在生产中工作。当在全局名称空间中存在一个具有相同名称的现有变量时,就会发生问题……而仅仅是UGH!

setvariable在此方面的差异是Tcl自己的软件包中存在许多错误的原因。

  1. 是真的我们不能在TCL中真正拥有常量(例如C中的const关键字),并且所有内容都可以重新定义为我们想要的东西吗?这不会对这种语言造成安全性问题吗?

通常来说,这没有安全性问题。原因有很多:

  1. 值(不是变量)在其模型中是不变的;如果某物具有价值,它就不会从脚下突变出来。
  2. 您可以使用适当的轨迹来模拟常量,但这并不常见。毕竟,仍然有可能unset变量并且不能真正被阻塞;例如,如果删除包含的名称空间,则必须起作用。一旦可以删除,就不能保证它是常量。
  3. Tcl使用解释器作为其基本安全边界,并且严格控制从子解释器到其父解释器的访问能力,主要是通过返回值或调用交叉解释器别名命令(这与执行系统调用,但轻量级除外)。不受信任的代码可以在不会造成破坏的环境中运行,但仍具有您想要赋予它的额外功能(由您决定如何防止滥用)。

其他语言中常量的主要用途是什么?嗯,有各种类型的枚举(在Tcl中,您将使用项目名称或名称列表,但都无法将其映射为其他名称),然后有您所描述的特殊常量。这些通常不是安全令牌,而是如果有人将pi设置为3.0,那么他们只会得到错误的答案。在他们身上!

Tcl不会阻止您在自己的解释器中引起问题。您确实可以执行诸如替换whileforeach之类的操作(在某些情况下这样做很有用)。但是,如果您弄错了,您所要做的就是给自己带来麻烦。我曾经决定为所有按其操作命名的按钮制作图标图像,然后简短地想知道为什么每次对open文件的调用都停止工作。哦,很好。

但是一个解释器中的操作不能会影响另一解释器中发生的事情,除非另一个解释器给予了许可(或者这是父解释器中的操作影响了它的一个或多个子代)。这就是安全域的障碍。不要在受信任的上下文中评估不受信任的代码。只是不要。