从 Elixir 中的 Code.eval 字符串获取地图值
Get map value from Code.eval string in Elixir
我试图通过 运行ning 代码获取地图的值。eval_string/1 但失败并出现错误:
warning: variable "data" does not exist and is being expanded to "data()", please use parentheses to remove the ambiguity or change the variable name
nofile:1
** (CompileError) nofile:1: undefined function data/0
(elixir 1.10.2) lib/code.ex:332: Code.eval_string_with_error_handling/3
main.exs:65: RulesEngine.evaluate_object_by_condition/2
(elixir 1.10.2) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
main.exs:17: RulesEngine.evaluate_object_by_condition/2
代码是:
@doc "Evaluate condition"
@default_op "="
def evaluate_object_by_condition(data, condition) do
IO.puts("Evaluando una regla en particular:")
IO.inspect(condition)
IO.inspect(data)
attr = condition.attr
value = condition.value
IO.inspect(attr)
eval_data = Code.eval_string(attr)
op = Map.get(condition, "op", @default_op)
IO.puts("DATA to EVAL")
IO.inspect(eval_data)
# value_type = Map.get(condition, "type")
# Hacer type checking y agregar a value_type
## Falta obtener el valor del objeto
# res = evaluate("=", value, obj.value)
true
end
然后我运行:
obj = %{
value: 1,
tiene_beca: 1,
tiene_credito: 1
}
condition= %{
attr: "data.tiene_beca",
value: 1
}
RulesEngine.evaluate_object_by_condition(obj, rules_or)
所以我试图获取 data.tiene_beca 的值,并从字符串中获取该变量名,这才是在 elixir 中执行此操作的正确方法?
首先,考虑您是否真的需要所有这些灵活性。 Code.eval_string
在没有任何检查或限制的情况下运行代码,因此这可能会在代码中打开一个安全漏洞。我会做这样的事情:
["data", field_name] = String.split(attr, ".")
field_name = String.to_existing_atom(field_name)
eval_data = data[field_name]
就是说,您的代码无法正常工作的原因是 Code.eval_string
无法访问调用函数中的局部变量,因此您需要显式地将变量作为绑定传递:
eval_data = Code.eval_string(attr, [data: data])
我试图通过 运行ning 代码获取地图的值。eval_string/1 但失败并出现错误:
warning: variable "data" does not exist and is being expanded to "data()", please use parentheses to remove the ambiguity or change the variable name
nofile:1
** (CompileError) nofile:1: undefined function data/0
(elixir 1.10.2) lib/code.ex:332: Code.eval_string_with_error_handling/3
main.exs:65: RulesEngine.evaluate_object_by_condition/2
(elixir 1.10.2) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
main.exs:17: RulesEngine.evaluate_object_by_condition/2
代码是:
@doc "Evaluate condition"
@default_op "="
def evaluate_object_by_condition(data, condition) do
IO.puts("Evaluando una regla en particular:")
IO.inspect(condition)
IO.inspect(data)
attr = condition.attr
value = condition.value
IO.inspect(attr)
eval_data = Code.eval_string(attr)
op = Map.get(condition, "op", @default_op)
IO.puts("DATA to EVAL")
IO.inspect(eval_data)
# value_type = Map.get(condition, "type")
# Hacer type checking y agregar a value_type
## Falta obtener el valor del objeto
# res = evaluate("=", value, obj.value)
true
end
然后我运行:
obj = %{
value: 1,
tiene_beca: 1,
tiene_credito: 1
}
condition= %{
attr: "data.tiene_beca",
value: 1
}
RulesEngine.evaluate_object_by_condition(obj, rules_or)
所以我试图获取 data.tiene_beca 的值,并从字符串中获取该变量名,这才是在 elixir 中执行此操作的正确方法?
首先,考虑您是否真的需要所有这些灵活性。 Code.eval_string
在没有任何检查或限制的情况下运行代码,因此这可能会在代码中打开一个安全漏洞。我会做这样的事情:
["data", field_name] = String.split(attr, ".")
field_name = String.to_existing_atom(field_name)
eval_data = data[field_name]
就是说,您的代码无法正常工作的原因是 Code.eval_string
无法访问调用函数中的局部变量,因此您需要显式地将变量作为绑定传递:
eval_data = Code.eval_string(attr, [data: data])