eval icon indicating copy to clipboard operation
eval copied to clipboard

bindings support

Open eed3si9n opened this issue 2 years ago • 6 comments

Do you have any plans to add bindings support so that it is possible to pass values in addition to the simple code evaluation?

Originally posted by @krakadzeyau-clarabridge in https://github.com/eed3si9n/eval/issues/4#issuecomment-1519949168

eed3si9n avatar Apr 24 '23 15:04 eed3si9n

See the last example in https://eed3si9n.com/eval/.

Eval() by default takes the current classpath - https://github.com/eed3si9n/eval/blob/fc91162462f155567211ff5d70b221678db6febc/src/main/scala-3/com/eed3si9n/eval/Eval.scala#L268-L269, so you should be able to define an object with the bindings and import the object?

I don't see a big upside to implementing binding feature that would effectively to emulate the object creation, which depends on having some specific classpath.

eed3si9n avatar Apr 24 '23 15:04 eed3si9n

I am not a Scala programmer actually. I only need to pass some code to my Gatling-based performance tests, and this code requires access to objects in the scope in which it is executed. Below is a "model" of the use case:

import com.eed3si9n.eval.Eval

@main
def eed3si9n_eval(): Unit =
    val name = "evaluation"
    val code=s"""
println("Hello " + name)
"""
    val eval = Eval()
    eval.evalInfer(code)

This code throws com.eed3si9n.eval.EvalException: "Not found: name". If your library can help me, I would appreciate it.

krakadzeyau-clarabridge avatar Apr 24 '23 16:04 krakadzeyau-clarabridge

To be more specific. This is a hardcoded setUp() method call and another call on the SetUp object it creates:

    setUp(
        plot.inject(. . .))
            .maxDuration(inject_maxDuration)

To be able to inject the code from a Jenkins job parameter I need access to the plot variable during the code evaluation. Is it possible via the library?

krakadzeyau-clarabridge avatar Apr 24 '23 16:04 krakadzeyau-clarabridge

An example from Groovy:

int i = 42
Eval.x(i, "println x") // prints "42"

I believe something like this was possible in Scala 2 via the Script Engine, but Scala 3 does not support bindings (I hope it is a temporary issue).

krakadzeyau-clarabridge avatar Apr 24 '23 17:04 krakadzeyau-clarabridge

Here's what I mean:

build.sbt

ThisBuild / scalaVersion := "3.2.0"
libraryDependencies += ("com.eed3si9n.eval" % "eval" % "0.2.0").cross(CrossVersion.full)
run / fork := true

Test.scala

import com.eed3si9n.eval.Eval

object Binding:
  val name = "evaluation"

@main
def main(): Unit =
    val code=s"""
import Binding.*
"Hello " + name
"""
    val eval = Eval()
    val result = eval.evalInfer(code)
    println(result.getValue(this.getClass.getClassLoader))

output

sbt:foo> run
[info] compiling 1 Scala source to /private/tmp/bar/target/scala-3.2.0/classes ...
[info] running (fork) main
[info] Hello evaluation

eed3si9n avatar Apr 24 '23 17:04 eed3si9n

Thank you! I will try to use it in my test code.

krakadzeyau-clarabridge avatar Apr 24 '23 17:04 krakadzeyau-clarabridge