函数范围中的eval(访问函数args)

时间:2015-03-05 16:00:40

标签: eval julia

假设:

abstract ABSGene
type NuGene <: Genetic.ABSGene
     fqnn::ANN
     dcqnn::ANN
     score::Float32
 end

 function mutate_copy{T<:ABSGene}(gene::T)
     all_fields_except_score = filter(x->x != :score, names(T))
     all_fields_except_score =  map(x->("mutate_copy(gene.$x)"),all_fields_except_score)
     eval(parse("$(T)("*join(all_fields_except_score,",")*")"))
 end

 ng = NuGene()

 mutated_ng = mutate_copy(ng)

结果:

ERROR: gene not defined
in mutate_copy at none:4

如果我只是将它看作一个字符串(在运行parse和eval之前),它看起来很好:

"NuGene(mutate_copy(gene.fqnn),mutate_copy(gene.dcqnn))"

然而,eval似乎并不知道已经传递给mutate_copy函数的基因。

如何访问已传递给mutate副本的基因参数?

我试过了:

function mutate_copy{T<:ABSGene}(gene::T)
  all_fields_except_score = filter(x->x != :score, names(T))
  all_fields_except_score =  map(x->   ("mutate_copy($gene.$x)"),all_fields_except_score)
  eval(parse("$(T)("*join(all_fields_except_score,",")*")"))

end

但是这扩展了字符串中的基因,这不是我想要的。

1 个答案:

答案 0 :(得分:2)

不要使用eval!几乎在所有情况下,除非您确实知道您正在做什么,否则您不应该使用eval。在这种情况下,eval根本无法工作,因为它在全局(或模块)范围内运行,并且无法访问函数本地的变量(如参数{{1 }})。

虽然你发布的代码对于一个最小的工作示例来说还不够,但我可以猜测你想在这里做些什么。

您可以动态查找字段名称,而不是gene

map(x->("mutate_copy(gene.$x)"),all_fields_except_score)

这是一种特殊语法,最终可能被map(x->mutate_copy(gene.(x)), all_fields_except_score) 取代。但是,现在任何一个都可以正常工作。

然后代替getfield(gene, x),直接致电eval(parse("$(T)("*join(all_fields_except_score,",")*")")),&#34; splat&#34;字段值:

T

我认为通过所有这些变换,字段顺序应该是稳定的,但它看起来非常脆弱(你依赖于得分是最后一个字段,所有构造函数的参数顺序与它们的顺序相同字段)。看起来您正在尝试执行T(all_fields_except_score...) 类型的操作,但是将得分字段保持未初始化状态。您也可以使用Base deepcopy然后递归设置为零。