Jonas Follesø
2010-Jul-22 13:13 UTC
[Ironruby-core] IronRuby, Silverlight and executing code dynamically in the browser
I''m toying around with the idea of a simple in-browser "coding environment" for IronRuby, think JSFiddle but for DLR languages. I''m fairly new to IronRuby, but have lots of Silverlight experience. I have gotten the basics up and running, but have ran into a couple issues. My initial idea was to use the virtual file system the IronPython Silverlight Host creates when it downloads files included using <script> tags. However, turns out this virtual file system is read-only, so I cannot write new Ruby files after the application is loaded. My second idea was to simply use the DynamicEngine and simply execute the code. The code I''ve written looks something like this: def run_tests code = window.eval("codeEditor.getCode()").to_s test = window.eval("testEditor.getCode()").to_s puts code begin dyneng = DynamicEngine.new engine = dyneng.runtime.get_engine("ruby") scope = dyneng.create_scope errorFormatter = ErrorFormatter::Sink.new resultCode engine.create_script_source_from_string(code).compile(errorFormatter).execute(scope) resultTest engine.create_script_source_from_string(test).compile(errorFormatter).execute(scope) puts resultCode puts resultTest rescue => ex puts ex.to_s end end It basically gets two pieces of Ruby code, then creates a new engine, creates script source, compiles it, and then executes it. If I do this with valid Ruby code everything works as expected. However, if I try to execute invalid code I was expecting my error handler to execute. But this does not happen. All I get is an error in the FireBug console saying: "Error calling method on NPObject!" So does anyone have suggestions on how to handle errors when executing the code dynamically in the browser. Secondly, does anyone have suggestions for alternative approaches to implementing this - i.e. make the virtual file system writable (write to isolated storage perhaps?). Best regards, Jonas Folles? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20100722/71809aea/attachment.html>
Charles Strahan
2010-Jul-22 22:16 UTC
[Ironruby-core] IronRuby, Silverlight and executing code dynamically in the browser
Hey Jonas, nice running into here (love your blog)! You could try writing your own virtual filesystem. Check out my blog for some inspiration: http://charlesstrahan.com/blog/2010/05/05/enumerating-resources-in-silverlight/ I''m currently working on just that. My current project (porting RPG Maker XP to Silverlight - already finished the desktop port) requires such functionality for enumerating file system entries (think Dir.glob), and saving game state to "disk". I''m trying to tease out my VFS into something extensible; you can find my code here: http://github.com/cstrahan/silverlightvfs There''s not much there, but perhaps the PathUtil could be handy: http://github.com/cstrahan/silverlightvfs/blob/master/src/SilverlightVFS/PathUtil.cs The more I work on abstracting out the core of the VFS, the more I feel like it''s hard to make a "one-fits-all" sort of solution; the use cases can vary a lot. I almost think it would be better to publish some guidance and a reference implementation, rather than try to create some architecture that is either too abstract or, conversely, not extensible enough to be useful... Let me know where you go with your project - it sounds cool. Cheers, -Charles On Thu, Jul 22, 2010 at 8:13 AM, Jonas Folles? <jonas at follesoe.no> wrote:> I''m toying around with the idea of a simple in-browser "coding environment" > for IronRuby, think JSFiddle but for DLR languages. I''m fairly new to > IronRuby, but have lots of Silverlight experience. I have gotten the basics > up and running, but have ran into a couple issues. > > My initial idea was to use the virtual file system the IronPython > Silverlight Host creates when it downloads files included using <script> > tags. However, turns out this virtual file system is read-only, so I cannot > write new Ruby files after the application is loaded. > > My second idea was to simply use the DynamicEngine and simply execute the > code. The code I''ve written looks something like this: > > def run_tests > code = window.eval("codeEditor.getCode()").to_s > test = window.eval("testEditor.getCode()").to_s > > puts code > > begin > dyneng = DynamicEngine.new > engine = dyneng.runtime.get_engine("ruby") > scope = dyneng.create_scope > > errorFormatter = ErrorFormatter::Sink.new > > resultCode > engine.create_script_source_from_string(code).compile(errorFormatter).execute(scope) > resultTest > engine.create_script_source_from_string(test).compile(errorFormatter).execute(scope) > > puts resultCode > puts resultTest > rescue => ex > puts ex.to_s > end > end > > It basically gets two pieces of Ruby code, then creates a new engine, > creates script source, compiles it, and then executes it. If I do this with > valid Ruby code everything works as expected. However, if I try to execute > invalid code I was expecting my error handler to execute. But this does not > happen. All I get is an error in the FireBug console saying: > > "Error calling method on NPObject!" > > So does anyone have suggestions on how to handle errors when executing the > code dynamically in the browser. Secondly, does anyone have suggestions for > alternative approaches to implementing this - i.e. make the virtual file > system writable (write to isolated storage perhaps?). > > Best regards, > Jonas Folles? > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20100722/e4af87b5/attachment-0001.html>
Jonas Follesø
2010-Jul-23 09:06 UTC
[Ironruby-core] IronRuby, Silverlight and executing code dynamically in the browser
Hi Charles, And thanks for the comment about my blog - really appreciate it! I had a look at your blog post for a custom virtual file system - and I do think that is the best long-term approach. This would enable a nice "in browser" coding experience where you can add files, reference other files etc. all client side running in the browser. If you look at the code in the http://github.com/ironruby/ironruby/blob/master/Hosts/Silverlight/Microsoft.Scripting.Silverlight/BrowserVirtualFilesystem.csfile, there is a class called IsolatedStorageVirtualFilesystem that extends the BrowserVirtualFileSystem. The class overrides the GetFileInternal method, throwing an not implemented exception, and have a TODO comment. So I guess this would be a good starting point. Alternatively you could extend the HttpVirtualFilesystem, which is the file system used by the standard Browser PAL. The HttpVirtualFileSystem will use the XapVirtualFileSystem to check if a file exists in the XAP, if not it will try to download it. My suggestion would be to add an extra check - if it doesn''t exist on the server, then check Isolated Storage. You would probably also have to extend BrowserScriptHost class and BrowserPAL, which currently expose the BrowserVirtualFileSystem, and instead use the IsolatedStorageVirtualFileSystem, as well as changing the OpenInputFileStream method, which throws an exception if any other file mode than Open or Read is passed in. This is the exception that bites you if you dry to use Ruby file APIs to write a file in a standard DLR app today. It would be nice if someone who worked on the Silverlight hosting environment for IronRuby could chip in with suggestions on how to best implement write support in the virtual file system. I would be more than happy trying to implement this and submit a patch. As for your blog post on enumerating resources that looks handy - as file enumeration is also something that would be useful (when the app loads it would be nice to check which files have been stored in isolated storage, and that way enabling devs to save their work in isolated storage between sessions). I had a look at your SilverlightVFS code - but I guess the thing I don''t quite get is the proper way to "blog" a new file system into the Silverlight PAL. - Jonas On Fri, Jul 23, 2010 at 12:16 AM, Charles Strahan < charles.c.strahan at gmail.com> wrote:> Hey Jonas, nice running into here (love your blog)! > > You could try writing your own virtual filesystem. Check out my blog for > some inspiration: > > http://charlesstrahan.com/blog/2010/05/05/enumerating-resources-in-silverlight/ > > I''m currently working on just that. My current project (porting RPG Maker > XP to Silverlight - already finished the desktop port) requires such > functionality for enumerating file system entries (think Dir.glob), and > saving game state to "disk". I''m trying to tease out my VFS into something > extensible; you can find my code here: > http://github.com/cstrahan/silverlightvfs > > There''s not much there, but perhaps the PathUtil could be handy: > > http://github.com/cstrahan/silverlightvfs/blob/master/src/SilverlightVFS/PathUtil.cs > > The more I work on abstracting out the core of the VFS, the more I feel > like it''s hard to make a "one-fits-all" sort of solution; the use cases can > vary a lot. I almost think it would be better to publish some guidance and > a reference implementation, rather than try to create some architecture that > is either too abstract or, conversely, not extensible enough to be useful... > > Let me know where you go with your project - it sounds cool. > > Cheers, > -Charles > > > On Thu, Jul 22, 2010 at 8:13 AM, Jonas Folles? <jonas at follesoe.no> wrote: > >> I''m toying around with the idea of a simple in-browser "coding >> environment" for IronRuby, think JSFiddle but for DLR languages. I''m fairly >> new to IronRuby, but have lots of Silverlight experience. I have gotten the >> basics up and running, but have ran into a couple issues. >> >> My initial idea was to use the virtual file system the IronPython >> Silverlight Host creates when it downloads files included using <script> >> tags. However, turns out this virtual file system is read-only, so I cannot >> write new Ruby files after the application is loaded. >> >> My second idea was to simply use the DynamicEngine and simply execute the >> code. The code I''ve written looks something like this: >> >> def run_tests >> code = window.eval("codeEditor.getCode()").to_s >> test = window.eval("testEditor.getCode()").to_s >> >> puts code >> >> begin >> dyneng = DynamicEngine.new >> engine = dyneng.runtime.get_engine("ruby") >> scope = dyneng.create_scope >> >> errorFormatter = ErrorFormatter::Sink.new >> >> resultCode >> engine.create_script_source_from_string(code).compile(errorFormatter).execute(scope) >> resultTest >> engine.create_script_source_from_string(test).compile(errorFormatter).execute(scope) >> >> puts resultCode >> puts resultTest >> rescue => ex >> puts ex.to_s >> end >> end >> >> It basically gets two pieces of Ruby code, then creates a new engine, >> creates script source, compiles it, and then executes it. If I do this with >> valid Ruby code everything works as expected. However, if I try to execute >> invalid code I was expecting my error handler to execute. But this does not >> happen. All I get is an error in the FireBug console saying: >> >> "Error calling method on NPObject!" >> >> So does anyone have suggestions on how to handle errors when executing the >> code dynamically in the browser. Secondly, does anyone have suggestions for >> alternative approaches to implementing this - i.e. make the virtual file >> system writable (write to isolated storage perhaps?). >> >> Best regards, >> Jonas Folles? >> >> _______________________________________________ >> Ironruby-core mailing list >> Ironruby-core at rubyforge.org >> http://rubyforge.org/mailman/listinfo/ironruby-core >> >> > > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20100723/7297e72b/attachment.html>