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

expose #load and #r as services for script packs #243

Open
adamralph opened this issue May 12, 2013 · 23 comments
Open

expose #load and #r as services for script packs #243

adamralph opened this issue May 12, 2013 · 23 comments
Labels

Comments

@adamralph
Copy link
Contributor

As an enhancement to adamralph/scriptcs-nancy#12 instead of having to do:

> nancy.Start();
> #load "somemodules.csx"
> nancy.Refresh();
> #r "SomeMoreModules.dll"
> nancy.Add(typeof(CoolModule).Assembly);

I'd like to do:

> nancy.Start();
> nancy.Add("somemodules.csx");
> nancy.Add("SomeMoreModules.dll");

The script pack would take the script or assembly path and pass it back to the script engine which would effectively do either a #load or #r, passing back an Assembly reference which the pack would use to find new modules.

Update 2013-06-13

The above use case isn't really so important now since automatic module finding is in place, so all I'd need to do is:-

> nancy.Go();
> #load "somemodules.csx"
> nancy.Go();
> #r "SomeMoreModules.dll"
> nancy.Go();

However, another feature I really want to build in is automatic loading of modules from the file system based on convention (adamralph/scriptcs-nancy#13) and I believe I need #load and #r as services for this.

@glennblock
Copy link
Contributor

You don't need to use #r for the dll, you just need the dll in the bin folder and it will automatically load.

-----Original Message-----
From: "Adam Ralph" [email protected]
Sent: ‎5/‎12/‎2013 5:58 AM
To: "scriptcs/scriptcs" [email protected]
Subject: [scriptcs] expose #load and #r as services for script packs (#243)

As an enhancement to adamralph/scriptcs-nancy#12 instead of having to do:

nancy.Start();
#load "somemodules.csx"
nancy.Refresh();
#r "SomeMoreModules.dll"
nancy.Add(typeof(CoolModule).Assembly);
I'd like to do:
nancy.Start();
nancy.Add("somemodules.csx");
nancy.Add("SomeMoreModules.dll");
The script pack would take the script or assembly path and pass it back to the script engine which would effectively do either a #load or reference #r, passing back an Assembly reference which the pack would use to find new modules.
As an aside, it would be great if scriptcs could expose a reference to the current script assembly. At the moment I have to do Assembly.GetCallingAssembly() but this ought to be abstracted away by scriptcs.

Reply to this email directly or view it on GitHub.

@filipw
Copy link
Member

filipw commented May 12, 2013

Yes but once the REPL is running, the only way to load a DLL into the existing session context is via #r.
In that sense, it might be interesting to expose that as a service, so that script packs can orchestrate loading of new DLLs themselves when running in REPL mode.

@adamralph
Copy link
Contributor Author

Yeah, what @filipw said ;-). Also bear in mind that I want to implement adamralph/scriptcs-nancy#13

@glennblock
Copy link
Contributor

Oh this is for REPL? I missed that.

On Sun, May 12, 2013 at 11:06 AM, Adam Ralph [email protected]:

Yeah, what @filipw https://github.com/filipw said ;-). Also bear in
mind that I want to implement adamralph/scriptcs-nancy#13adamralph/scriptcs-nancy#13


Reply to this email directly or view it on GitHubhttps://github.com//issues/243#issuecomment-17782257
.

@adamralph
Copy link
Contributor Author

It is for REPL but also to allow me to do my own convention based location within a script pack.

@adamralph
Copy link
Contributor Author

@glennblock in reply to adamralph/scriptcs-nancy#13 (comment)

Ultimately what I need is, given a path to a script or assembly, I want to call something in scriptcs which does a #load or #r and then gives me back an Assembly reference. If you require that I make the distinction between script and assembly then I can do, but I think it would be nice if scriptcs could do this itself. Perhaps that's something that could come later though.

Now, I haven't thought about the internal implementation at all ;-). I don't think I'm yet qualified to. I haven't really gotten deep and dirty with the scriptcs codebase yet.

@glennblock
Copy link
Contributor

@adamralph May not be possible what you are asking. We need to spike on it. It could be a chicken and egg problem. The dll doesn't exist yet, and once it does we're not sure you can load new scripts and not lose context. The REPL functionality relies on the fact that you definitely can bring new things into an existing session, but then you have a diff dll.

@glennblock
Copy link
Contributor

@adamralph I'll just stay quiet until we know more. We may be able to support this scenario but takes some investigation.

@glennblock
Copy link
Contributor

I am 99% sure we can get this working in the REPL no problem, as today each repl command is evaluating new code into the same session.

@glennblock
Copy link
Contributor

I am just not sure about the implications of doing this from within the middle of code that Roslyn is executing. But the more I think about it, I am thinking there should be a way, that is using the REPL as a reference point.

@adamralph
Copy link
Contributor Author

So I tried this:

> var x= 20;
> x
20
> #load "foo.csx"
> new Foo().Speak()
Foo speaks
> x
20
>

The value of x persists. Does that imply this would work for #load?

@glennblock
Copy link
Contributor

@adamralph we also have to make sure this could be supported in mono. We need @dragan to weigh in there.

@adamralph
Copy link
Contributor Author

@glennblock OK, I thought at bit more about what you are saying above and I get it now. You're concerned with the difference between scriptcs code doing stuff to the session DLL from oustide it vs the DLL doing the same thing to itself. This is all fascinating stuff 😉

@filipw
Copy link
Member

filipw commented May 12, 2013

@adamralph re: the code you posted - in REPL it works since session is persisted between executions of subsequent code lines.

In "normal" script execution you'd have the whole script compiled to an in memory assembly on startup, which poses a bit of a challenge - since having an dynamic inline load would mean you'd be trying to modify an existing assembly from within that assembly :-) Not saying that it's impossible though, we will try to come up with some ideas

@glennblock
Copy link
Contributor

Yes, it works in the REPL. If it did not that would be a pretty weak REPL :-) it works because we cache the Roslyn session and reuse it each time a line is compiled.

I am not sure however it will work if we compile into the season while code is executing. It might work though, have to test

-----Original Message-----
From: "Filip W" [email protected]
Sent: ‎5/‎12/‎2013 4:01 PM
To: "scriptcs/scriptcs" [email protected]
Cc: "Glenn Block" [email protected]
Subject: Re: [scriptcs] expose #load and #r as services for script packs(#243)

@adamralph re: the code you posted - in REPL it works since session is persisted between executions of subsequent code lines.
In "normal" script execution you'd have the whole script compiled to an in memory assembly on startup, which poses a bit of a challenge - since having an dynamic inline load would mean you'd be trying to modify an existing assembly from within that assembly :-) Not saying that it's impossible though, we will try to come up with some ideas

Reply to this email directly or view it on GitHub.

@adamralph
Copy link
Contributor Author

Thanks for putting effort into this one. If this works out it could make for a truly rails-like deployment scenario. I'm starting to envisage actually running production sites with this. I might never compile a line of C# again! ;-)

@filipw
Copy link
Member

filipw commented May 14, 2013

This is a rough spike, but it works :-)

2013-05-13_1939

@adamralph
Copy link
Contributor Author

Very cool! Have you tried getting it to work with assemblies yet?

@glennblock
Copy link
Contributor

Nice one Filip!!!!

@PeteGoo
Copy link

PeteGoo commented Oct 7, 2013

@filipw Is this still alive? I need a way of dynamically executing all scripts in a "scripts" folder, preferably at a time of my choosing.

@glennblock
Copy link
Contributor

Well it has been 3 years, but I started working on this with a diff approach, an Eval function. Basically you call Eval and it runs the code dynamically. It supports #load, etc and inherits the references from the parent / shares the same session.

Screenshot below

screen shot 2017-01-22 at 1 07 47 pm

@filipw @PeteGoo @adamralph thoughts?

@glennblock
Copy link
Contributor

And the reverse works as well, variables flow in automatically. Though maybe I should have an option to disable that.

screen shot 2017-01-22 at 1 13 39 pm

@glennblock
Copy link
Contributor

glennblock commented Jan 23, 2017

Been iterating on this more, and now the experience is more pythonic (thanks to a suggestion for @craignicol). You can create multiple sessions and reuse them. If you pass nothing, a new one will be created for you. If you want to allow access to the outer session, you use Env.Session.

screen shot 2017-01-22 at 6 09 22 pm

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

No branches or pull requests

4 participants