2

I have a function that generates an equation in the form of a String. I want to be able to turn that string into an Expression, and evaluate it in another function. For example:

eqs = "aval + 3.0 bval + kvec[[3]]";

Eval[eqs_, a_, b_, k_List] := 
  Module[{ans},
    ans = Evaluate[ToExpression[eqs] /. {aval -> a, bval -> b, kvec -> k}];
    Return[ans];
];

When I run the following, everything works fine.

MyEval[eqs, 1, 2, {1, 2, 3}]
10.

The problem is, I want MyEval to be part of a package. So for example,

BeginPackage["MyDumbTest`"]

MyEval::usage = "This is a dumb test."

Begin["`Private`"];

MyEval[eqs_, a_, b_, k_List] := 
  Module[{ans},
    ans = Evaluate[ToExpression[eqs] /. {aval -> a, bval -> b, kvec -> k}];
    Return[ans];
];

End[]
EndPackage[]

The function doesn't work:

Quit[]
<<`MyDumbTest

eqs = "aval + 3.0 bval + kvec[[3]]";
MyEval[eqs, 1, 2, {1, 2, 3}]

aval + 3. bval + kvec[[3]]

However, if after loading the package I open the package file (MyDumbTest.m) and execute (shift-return) the cell for MyEval, the command starts working in the notebook, and will work for the remainder of the kernel operation. Why does this happen and is there a way around it?

m_goldberg
  • 107,779
  • 16
  • 103
  • 257

1 Answers1

1

In addition to discussion in Derivative from my package function returns 0, which I highly recommend to read, you can do a little bit of string manipulation for this particular case:

(*...*)

MyEval[eqs_, a_, b_, k_List] := Module[{ vars = {"aval", "bval", "kvec"} }
, ToExpression[
    StringTemplate["Function[``, ``]"][vars, eqs]
  ][a, b, k]
]

(* ...*)

MyEval["aval + 3.0 bval + kvec[[3]]", 1, 2, {1, 2, 3}]

10.

BeginPackage["test`"];
Needs["MyDumbTest`"];

MyEval["aval + 3.0 bval + kvec[[3]]", 1, 2, {1, 2, 3}]

EndPackage[];

10.

The second example will not work with solutions from other answers.

Kuba
  • 136,707
  • 13
  • 279
  • 740