Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to hook into require #34

Open
Papipo opened this issue Aug 7, 2024 · 3 comments
Open

Add support to hook into require #34

Papipo opened this issue Aug 7, 2024 · 3 comments

Comments

@Papipo
Copy link

Papipo commented Aug 7, 2024

Hi!

I have this app in which users can provide their lua scripts. I don't have those in the filesystem so I need to intercept require calls somehow (I will be returning them from the database or as chunks from ETS).

An option is to override require itself, but I think that adding a searcher after the preload one is more lua-esque.

In case it's better to just override require, how would yo approach returning preloaded modules?
Basically I don't know if luerl provides a mechanism to hook into require and if we can wrap it in this lib.

Thanks!

@Papipo
Copy link
Author

Papipo commented Aug 8, 2024

Alternatively, creating a separate function (ie. import) that works like require but allows to return modules, that's also fine.

@Papipo
Copy link
Author

Papipo commented Aug 9, 2024

This works, I can return anything from the imported script:

defmodule ErluaTest do
  use ExUnit.Case
  doctest Erlua
  import Lua

  defmodule Custom do
    @imports %{
      "custom" => ~LUA"""
        return {
          greet = function(name)
            print("Printed hello, " .. name)
          end,
          template = function(name)
            return "Templating hello, " .. name
          end
      }
      """
    }

    def import([], [path], state) do
      {:ok, ret, state} = Luerl.New.do(state, @imports[path])
      {ret, state}
    end
  end

  test "Loading lua scripts dynamically" do
    entrypoint = ~LUA"""
      print("I am the entrypoint")
      local imported = import("custom")
      imported.greet("world")
      print("gonna print a rendered template: " .. imported.template("world"))
    """

    result =
      Lua.new()
      |> Lua.set!([:import], {Custom, :import, []})
      |> Lua.eval!(entrypoint)
  end
end

But as you can see I had to use Luerl do, you can't use eval! there.
Also, conceptually I don't know if the import function should reuse the state or use a blank slate. I like the latter to avoid unexpected side effects.

@davydog187
Copy link
Contributor

Hello @Papipo, I'm still thinking about ways to do this. I'll get back to you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants