Giter Club home page Giter Club logo

Comments (6)

xiaq avatar xiaq commented on June 20, 2024 1

@IngwiePhoenix Glad that you figured out most the stuff :)

The reason you can't get a return value is a consequence of Elvish's language semantics: there's simply no concept of return values in Elvish. Instead, Elvish has outputs, and to "return" something you'll need to write it out with put (for value outputs) or echo (for byte output) or similar commands and capture it.

I've added a doc that specifically answers this question: https://github.com/elves/elvish/blob/master/docs/elvish-as-library.md (beware that the godoc pages on pkg.go.dev takes a while to refresh). The examples for Evaler.Eval in particular shows how to get "return" values from Elvish code.

from elvish.

xiaq avatar xiaq commented on June 20, 2024 1

So if I want a real return value, I would have to execute the snippet and then make the code set a global value which I can then pick off the context - so, something remotely similiar to $?. Hey, works for me - simple enough. :)

That, or capture the output if you don't need it for other purposes (and like in Elvish itself, you can pass structured values using builtins like put).

Thanks for the additions!

Np!

from elvish.

krader1961 avatar krader1961 commented on June 20, 2024

Embedding any code written in Go inside an app written in another language is problematic. Some of the challenges are due to the Go runtime, how types are defined in each language, and memory ownership. It also creates a tight coupling that causes its own problems. There are other challenges such as how to translate Elvish exceptions over the FFI. One relatively recent article that discusses how to do this is https://www.dolthub.com/blog/2023-02-01-embedding-go-in-c/. I can't speak for the project owner but I doubt this will ever be done and certainly not in the near future. There are just too many other enhancements that could be made which would add considerably more value. Rather than attempting to embed Elvish in a different program using FFI it is likely to be simpler to use an RPC mechanism to interact with an Elvish shell.

from elvish.

IngwiePhoenix avatar IngwiePhoenix commented on June 20, 2024

Oh - I was more talking about something like

import "src.elv.sh/pkg/..."
func main() {
  var context = Elvish.create()
  context.run(...)
}

But I guess I have to dig through the source more and start with cnd/elvish to find that. Still, thanks for the blog post, that was quite interesting!

from elvish.

IngwiePhoenix avatar IngwiePhoenix commented on June 20, 2024

Dug around a while and came to this:

  • An Evaler (...pkgs/eval) and a Parser (...pkgs/parser) are needed.
  • elvish uses this to set up it's Evaler:

    elvish/pkg/shell/shell.go

    Lines 99 to 132 in cee682c

    func (p *Program) makeEvaler(stderr io.Writer, interactive bool) *eval.Evaler {
    ev := eval.NewEvaler()
    var errRc error
    ev.RcPath, errRc = rcPath()
    switch {
    case !interactive || p.noRC:
    // Leave ev.ActualRcPath empty
    case p.rc != "":
    // Use explicit -rc flag value
    var err error
    ev.EffectiveRcPath, err = filepath.Abs(p.rc)
    if err != nil {
    fmt.Fprintln(stderr, "Warning:", err)
    }
    default:
    if errRc == nil {
    // Use default path stored in ev.RcPath
    ev.EffectiveRcPath = ev.RcPath
    } else {
    fmt.Fprintln(stderr, "Warning:", errRc)
    }
    }
    libs, err := libPaths()
    if err != nil {
    fmt.Fprintln(stderr, "Warning: resolving lib paths:", err)
    } else {
    ev.LibDirs = libs
    }
    mods.AddTo(ev)
    return ev
    }
  • This here illustrates how to best make a Parser:
    src := parse.Source{Name: name, Code: code, IsFile: true}

So, whilst there is no "made for embedding" API, it is actually quite easy to set this up - and as it is mostly contained in structures, it should? be threadsafe.

However, there is no way to "return" a value from the script to the parent, as far as I can tell. That said, there is some interesting stuff here: https://github.com/elves/elvish/blob/cee682c489925b47d8d46f9afdc31acc19557d10/pkg/eval/vals/struct_map.go

So I imagine it would be possible to just bind a function to the Evaler that would act as a "return" to the host by wrapping the actual code - which, in the tool I want to make, wouldn't be a big problem, since most of the scripts run are rather short snippets, so wrapping them isn't a big deal.

Would be neat to have a plain pkgs/embed module that simplifies this a little; might make it myself in fact, this doesn't seem too difficult - at least, at present. o.o

from elvish.

IngwiePhoenix avatar IngwiePhoenix commented on June 20, 2024

So if I want a real return value, I would have to execute the snippet and then make the code set a global value which I can then pick off the context - so, something remotely similiar to $?. Hey, works for me - simple enough. :)

Thanks for the additions!

from elvish.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.