函数范围内的eval(访问函数args) [英] eval in function scope (accessing function args)

查看:134
本文介绍了函数范围内的eval(访问函数args)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出:

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

如果我只是将其视为一个字符串(在运行解析和评估之前),它将看起来不错:

If I just look at it as a string (prior to running parse and eval) it looks fine:

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

但是,eval似乎并不知道已经传递给mutate_copy函数的基因.

However, eval doesn't seem to know about gene that has been passed into the mutate_copy function.

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

How do I access the gene argument that's been passed into the mutate copy?

我尝试过:

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

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

But that expands the gene in the string which is not what I want.

推荐答案

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

Don't use eval! In almost all cases, unless you really know what you're doing, you shouldn't be using eval. And in this case, eval simply won't work because it operates in the global (or module) scope and doesn't have access to the variables local to the function (like the argument gene).

虽然您发布的代码不足以作为一个最小的工作示例,但我可以对您要在此处执行的操作进行一些猜测.

While the code you posted isn't quite enough for a minimal working example, I can take a few guesses as to what you want to do here.

代替map(x->("mutate_copy(gene.$x)"),all_fields_except_score),您可以动态查找字段名称:

Instead of map(x->("mutate_copy(gene.$x)"),all_fields_except_score), you can dynamically look up the field name:

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

这是一种特殊的语法,最终可能会被getfield(gene, x)代替.不过,任何一种都可以立即使用.

This is a special syntax that may eventually be replaced by getfield(gene, x). Either one will work right now, though.

然后代替eval(parse("$(T)("*join(all_fields_except_score,",")*")")),直接调用T并"splat"字段值:

And then instead of eval(parse("$(T)("*join(all_fields_except_score,",")*")")), call T directly and "splat" the field values:

T(all_fields_except_score...)

我认为字段顺序在所有这些转换中都应该是稳定的,但是它看起来非常脆弱(您取决于得分是最后一个字段,并且所有构造函数的参数与其字段的顺序相同) .看起来您正在尝试执行deepcopy这类操作,但未对score字段进行初始化.您也可以使用Base的 deepcopy ,然后将分数递归设置为零.

I think the field order should be stable through all those transforms, but it looks a pretty fragile (you're depending on the score being the last field, and all constructors to have their arguments in the same order as their fields). It looks like you're trying to perform a deepcopy sort of operation, but leaving the score field uninitialized. You could alternatively use Base's deepcopy and then recursively set the scores to zero.

这篇关于函数范围内的eval(访问函数args)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆