Using eval within a function

I’m trying to build a statement for an if case within a function. Something like:

function build_string(test_value, comparator, value)
    if eval(Meta.parse("test_value" * "comparator" * "value"))
    [...]
end

… I get the error, that the parameters within the function are not known. As I already read, in the other topic, eval is only working globally and it should be avoided to use it within a function. However I’d like to get this to work. The only other option would be to make if cases which compares every possible value of the comparator parameter … but this would make the function huge.

I hope you understand what I am struggling with. :thinking:

I’m 99% sure eval is not the answer. Some alternatives:

  • Pass comparator as a function, then just call it.
  • If it must be a string, have a bunch of if comparator == "foo" ... branches.
  • Or have a global const dict mapping comparators to the function implementing it (e.g. Dict("==" => ==, ...)). This will be type-unstable.
2 Likes

eval evaluates the expression in the global scope of the containing module (cf. the documentation). You cannot use it in a function body like that. But you have noticed that yourself :slight_smile:

If comp is a function, then simply do what @Sukera wrote below. If it is unavoidably a string (for whatever reason), a macro would make this work

macro comp_string(test, comp, val)
  c = Meta.parse(comp)
  :( $c($a, $b) )
end

@comp_string("A", "<=", "B")
true

function build_string(A, comp, B)
  if @comp_string(A, comp, B)
   [...]
end
1 Like

You can avoid macros by passing in the function directly:

function build_string(A, comp, B)
  if comp(A, B)
   [...]
end

build_string(A, <=, B) # for some variables A and B
2 Likes

Sure, but I had understood OP that the requirement was to pass comp as a string. For whatever reason.

I don’t think so - else there would be no need to Meta.parse a custom built string again (in the example they’re parsing test_value <= value, just without interpolating the comparator properly/having the proper syntax), only to evaluate the resulting expression.

Huh, you’re right. Then I don’t understand OP’s objective at all.

Thanks very much! I had not expected to be able to pass the comp directly as function … very happy with the outcome =)

3 Likes