Julia 检查是否可以安全评估符号

Julia 检查是否可以安全评估符号,julia,Julia,我有一个字符串x。我认为x是类型的字符串表示,该类型是Number的子类型。例如,x可能采用值“Float64”。我可以使用以下方法检查此问题: eval(parse(x)) <: Number eval(parse(x))编辑:此解决方案不安全。阅读评论。我离开它是因为它仍然很有教育意义 eval可以选择将模块作为其第一个参数 您可以在一个裸模块(baremodule)中对其进行求值,因此该命令无法访问标准库(这样它就不会造成太大的危害) 编辑:此解决方案不安全。阅读评论。我离开它是因

我有一个字符串
x
。我认为
x
是类型的字符串表示,该类型是
Number
的子类型。例如,
x
可能采用值
“Float64”
。我可以使用以下方法检查此问题:

eval(parse(x)) <: Number

eval(parse(x))编辑:此解决方案不安全。阅读评论。我离开它是因为它仍然很有教育意义

eval
可以选择将模块作为其第一个参数

您可以在一个裸模块(
baremodule
)中对其进行求值,因此该命令无法访问标准库(这样它就不会造成太大的危害)


编辑:此解决方案不安全。阅读评论。我离开它是因为它仍然很有教育意义

eval
可以选择将模块作为其第一个参数

您可以在一个裸模块(
baremodule
)中对其进行求值,因此该命令无法访问标准库(这样它就不会造成太大的危害)

一揽子计划必须解决这个问题。通过解析字符串,然后在对其求值之前检查结果。如果解析后的字符串是它认为是的,那么它知道在
Main
命名空间中进行计算应该是安全的。这允许它从主命名空间中拾取
baremodule
中不可用的自定义类型


更多详细信息:解析任意字符串后,可以检查返回的对象,以查看其计算是否“安全”:

julia> dump(parse("Int"))
Symbol Int

julia> dump(parse("Vector{Int}"))
Expr
  head: Symbol curly
  args: Array(Any,(2,))
    1: Symbol Vector
    2: Symbol Int
  typ: Any

julia> dump(parse("""rm("/")"""))
Expr
  head: Symbol call
  args: Array(Any,(2,))
    1: Symbol rm
    2: ASCIIString "/"
  typ: Any
我们希望确保永远不会
eval
一个可以调用任意行为的表达式。根据您对类型语法的支持程度,您的解决方案可能非常简单,也可能与我上面链接的HDF5解决方案一样复杂。如果您只是追求简单的、未经参数化的类型,我们可以大大简化:

is_valid_type_expression(ex::Symbol) = true
is_valid_type_expression(ex) = false

function julia_type(string)
    ex = parse(string)
    if is_valid_type_expression(ex)
        try
            typ = eval(Main, ex)
            isa(typ, Type) && typ <: Number && return typ
        end
    end
    error("unsupported type: $string")
end

julia> julia_type("String")
ERROR: unsupported type: String
 in julia_type at none:9

julia> julia_type("Int")
Int64

julia> julia_type("""rm("/")""")
ERROR: unsupported type: rm("/")
 in julia_type at none:9
类型表达式(ex::Symbol)=true是否有效
类型表达式(ex)=假
函数类型(字符串)
ex=解析(字符串)
if是有效的类型表达式(ex)
尝试
典型值=评估值(主、ex)
isa(典型类型)和典型类型(“字符串”)
错误:不支持的类型:字符串
在julia_中,键入无:9
julia>julia_类型(“Int”)
Int64
julia>julia_类型(“rm(“/”))
错误:不支持的类型:rm(“/”)
在julia_中,键入无:9
请注意,任何比符号更复杂的内容都不允许
eval
'ed。在
eval
对表达式进行赋值后,我们会检查以确保该类型是一个类型,并且它是
Number
的子类型。除了内置子类型之外,这还允许自定义子类型
Number
,因为我们在
Main
命名空间中对其进行评估。

包必须处理此问题。通过解析字符串,然后在对其求值之前检查结果。如果解析后的字符串是它认为是的,那么它知道在
Main
命名空间中进行计算应该是安全的。这允许它从主命名空间中拾取
baremodule
中不可用的自定义类型


更多详细信息:解析任意字符串后,可以检查返回的对象,以查看其计算是否“安全”:

julia> dump(parse("Int"))
Symbol Int

julia> dump(parse("Vector{Int}"))
Expr
  head: Symbol curly
  args: Array(Any,(2,))
    1: Symbol Vector
    2: Symbol Int
  typ: Any

julia> dump(parse("""rm("/")"""))
Expr
  head: Symbol call
  args: Array(Any,(2,))
    1: Symbol rm
    2: ASCIIString "/"
  typ: Any
我们希望确保永远不会
eval
一个可以调用任意行为的表达式。根据您对类型语法的支持程度,您的解决方案可能非常简单,也可能与我上面链接的HDF5解决方案一样复杂。如果您只是追求简单的、未经参数化的类型,我们可以大大简化:

is_valid_type_expression(ex::Symbol) = true
is_valid_type_expression(ex) = false

function julia_type(string)
    ex = parse(string)
    if is_valid_type_expression(ex)
        try
            typ = eval(Main, ex)
            isa(typ, Type) && typ <: Number && return typ
        end
    end
    error("unsupported type: $string")
end

julia> julia_type("String")
ERROR: unsupported type: String
 in julia_type at none:9

julia> julia_type("Int")
Int64

julia> julia_type("""rm("/")""")
ERROR: unsupported type: rm("/")
 in julia_type at none:9
类型表达式(ex::Symbol)=true是否有效
类型表达式(ex)=假
函数类型(字符串)
ex=解析(字符串)
if是有效的类型表达式(ex)
尝试
典型值=评估值(主、ex)
isa(典型类型)和典型类型(“字符串”)
错误:不支持的类型:字符串
在julia_中,键入无:9
julia>julia_类型(“Int”)
Int64
julia>julia_类型(“rm(“/”))
错误:不支持的类型:rm(“/”)
在julia_中,键入无:9

请注意,任何比符号更复杂的内容都不允许
eval
'ed。在
eval
对表达式进行赋值后,我们会检查以确保该类型是一个类型,并且它是
Number
的子类型。除了内置子类型之外,这还允许自定义子类型
Number
,因为我们在
Main
名称空间中对其进行评估。

我很确定有一些偷偷的方法可以打破
baremodule
<代码>评估(M,:(Core.interference.println(“FOOEY”))
@MattB。悄悄的谢谢你的信息!更简单的是:
eval(M,:(Main.Base.println(“我可以访问所有函数”))
感谢您的回复。遗憾的是,事情并不是这么简单:-)我很确定有一些鬼鬼祟祟的方法可以打破
的光模块<代码>评估(M,:(Core.interference.println(“FOOEY”))
@MattB。悄悄的谢谢你的信息!更简单的是:
eval(M,:(Main.Base.println(“我可以访问所有函数”))
感谢您的回复。可惜事情不是这么简单:-)谢谢你的回复。恐怕我不太明白解决办法。无论输入是
Expr(parse(“Float64”)
还是
Expr(parse(“HelloWorld”))
,链接函数
都是有效的\u type\u ex
看起来将返回
true
。我的元编程技能基本上是不存在的,所以这几乎肯定是问题的根源。你有没有可能在回答中再详细一点?抱歉,再次感谢。没问题。查看我的更新。我使用了与HDF5代码类似的函数名和设置,因此如果您想要支持更复杂的类型字符串,您可以看到我是如何简化的。这一切都有道理。非常感谢。如果你不介意的话,我还有一个问题。您的更新似乎暗示了几乎所有的
符号