cosmos72 / gomacro

Interactive Go interpreter and debugger with REPL, Eval, generics and Lisp-like macros

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I would like a full working example how to inject my application context(types and functions) in the REPL

naidishuli opened this issue · comments

Hello @naidishuli,
to inject variables into gomacro REPL, you can use one of the two techniques shown in https://github.com/cosmos72/gomacro/blob/master/_example/glycerine1/main.go

To inject functions, you can use the first technique above, possibly replacing the fragment reflect.ValueOf(&x).Elem() with reflect.ValueOf(myFunction)

To inject types, you can compile and execute something like:

import (
	"reflect"
	"github.com/cosmos72/gomacro/imports"
)

func init() {
	imports.Packages["my/package/full/path"] = imports.Package{
		Binds:    map[string]reflect.Value{},
		Types:    map[string]reflect.Type{
			"MyType": reflect.TypeOf((*MyType)(nil)).Elem(),
		},
		Proxies:  map[string]reflect.Type{},
		Untypeds: map[string]string{},
		Wrappers: map[string][]string{},
	}
}

and then import "my/package/full/path" from REPL.

Please tell if the instructions above are sufficient, or you need a more detailed step-by-step procedure

Hi @cosmos72 thanks for you answer, but the examples here https://github.com/cosmos72/gomacro/blob/master/_example/glycerine1/main.go are showing how to import when using the interpreter. Instead I want to be able to import my local project(or part of it) into the REPL itself in order to run live code during development. Something similar to the rails console. Whenever I try to import it in relation to the set go path it doesn't work. I assume because whenever I do the import statement it tries the the 'go get ...' command. My project is not in github and even if it is, I want the repl to get the local version. I tried to redirect with the replace rules in the go.mod that exists in the gomacro.imports project that is automatically created, but still doesn't work. Anything else I'm missing here?

I tried the above also, no success... hope this helps to clear what I'm trying to achieve

Hello @naidishuli,
thanks for the detailed explanation.

Unluckily this is not supported at the moment:
from gomacro prompt, you can only import publicly downloadable packages.

Some other user proposed the same (or equivalent) enhancement, i.e. allow importing local packages: it was suggested in gophernotes, which provides a GUI on top of gomacro - see gopherdata/gophernotes#237

@cosmos72 if you were able to inject local package in the interpreter than it should not be too hard to do the same for the prompt REPL, anything I can help with? Cause I think that this is really an important and big feature and something that would really help during development and be valuable to a lot ot developers.

It can be implemented, but the two things are not as similar as they may appear at first sight:

  1. Importing a local package from gomacro REPL means compiling and starting a vanilla gomacro (with no knowledge about local packages) then telling it to somehow find a certain local package on disk, compile it as a plugin, and load it. Feasible, but not implemented (yet).

  2. Injecting a local package into the interpreter means: having a Go executable already compiled and running, which contains both the local package and the interpreter as compiled Go libraries, then calling some gomacro library function to inform it about the types, functions, variables and constants defined by the local package but not registered yet in the packages known by the interpreter.

Of course, as a quick-and-dirty solution, one could implement 2. then start a REPL, which effectively means creating a modified gomacro which is compiled and linked against a local package and thus knows about it.
Now that I think about it, there is even a semi-standard procedure to create such a modified gomacro - I can explain the details if you need, but they basically boil down to my first comment above.

@cosmos72 thank you for your time on explaining this! I'll try to make it happen, any further explanation would be very helpful!

Commit 3026d9a adds the ability to import Go packages from a local filesystem directory. Supported syntaxes are:

  import "."
  import ".."
  import "./some/relative/path"
  import "../some/relative/path"
  import "/some/absolute/path"