I am using JRuby in an eclipse plugin for my product. I have a bunch of
scripts that define a DSL and perform operations for me. I want to be
able
to dynamically reload these scripts whenever required. The scripts could
change themselves on file system and moreover the location of the
scripts
could also change. I could even have multiple copies on file system of
slightly modified/changed scripts. Each time I want scripts from a
specific
location to be utilized.
As I have understood so far, using “load” instead of “require” should do
the job. So now if before calling any Ruby methods/functions I use “load
‘XXX.rb’”, it will reload the XXX.rb utilizing the new changes.
PROBLEM:
In my code I am using ScriptingContainer to run scriplets to access ruby
functions. I set load paths on this scripting container to indicate from
which locations the scripts should be loaded. However, the problem is
that
on subsequent calls and even with different instances of
ScriptingContainer, I have noticed that the scripts that were loaded the
first time are utilized every time. “load” reloads them, but after
loading
those scripts once, the next time I might need to load similar scripts
from
a different location but its not happening.
My assumption was that utilizing a different scripting container
instance
should have done the job but it seems that the load paths are globally
set
somewhere and calling “setLoadPath” on new ScriptingContainer instances
either does not modify existing paths or only appends. If the latter
case
is true then probably when searching for scripts they are always found
on
oldest paths set and newer load paths get ignored.
Seems there is no direct answer to this question, could someone point me
in
some direction to look it for myself? Should I try debugging JRuby code
to
see what actually is happening, or maybe there are some features that I
can
play around with to achieve the desired behavior.
Are you trying to load a script with a method ‘foo’ that does one thing
and then trying to load a different script which also has a method ‘foo’
that does something different - so that the program calling the method
‘foo’ can be ignorant of the changes?
I think you mostly understood my problem, except that the script files
also
have the same name. This is why I expect to just change the
ScriptingContainer instance and set a different list of load paths and
expect the scripts with the same name and same methods (different
versions
though) to be reloaded and used by the program.
I haven’t tried loading scripts with absolute paths, but I can try that
and
will let you know. I would still prefer a different solution though
because
in most cases I know that my scripts will not change on file system.
However, I still need to be able to select a different directory
of ‘similar’ scripts each time. If setting load path technique had
worked,
I would have used “require” so that scripts are loaded once in each
ScriptingContainer, to avoid a performance hit.
I think you mostly understood my problem, except that the script files
also
have the same name. This is why I expect to just change the
ScriptingContainer instance and set a different list of load paths and
expect the scripts with the same name and same methods (different
versions
though) to be reloaded and used by the program.
I haven’t tried loading scripts with absolute paths, but I can try that
and
will let you know. I would still prefer a different solution though
because
in most cases I know that my scripts will not change on file system.
However, I still need to be able to select a different directory
of ‘similar’ scripts each time. If setting load path technique had
worked,
I would have used “require” so that scripts are loaded once in each
ScriptingContainer, to avoid a performance hit.
I think you mostly understood my problem, except that the script files also have
the same name. This is why I expect to just change the ScriptingContainer instance
and set a different list of load paths and expect the scripts with the same name
and same methods (different versions though) to be reloaded and used by the
program.
ScriptingContainer takes a LocalContextScope as one of its configuration
parameters. The default value is LocalContextScope.SINGLETON, which
shares a single runtime across all ScriptingContainer instances.
If you want each ScriptingContainer to be independent, you’ll need to
select one of the three other options1. LocalContextScope.SINGLETHREAD
is the simplest one – it basically tells the ScriptingContainer not to
pay attention to threads. The others are for more complex concurrency
situations.
Thanks Rhett, this seems like the thing I need to work with. I will try
it
out and let you know. I had actually looked through the context
parameter
that ScriptingContainer takes but I missed the details. Thanks for
pointing
me to it again.
Waqas Ilyas
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.