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代码类似的函数名和设置,因此如果您想要支持更复杂的类型字符串,您可以看到我是如何简化的。这一切都有道理。非常感谢。如果你不介意的话,我还有一个问题。您的更新似乎暗示了几乎所有的符号