[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Loading a file without cluttering the global namespace

Benjamin Hepp

7/2/2005 9:59:00 AM

Hello,

I'm trying to build a module-mechanism in ruby so that I am able to load a
ruby-file without cluttering up the global namespace of the program.

For example I want to be able to load a ruby-file, search for methods in
it, possibly execute one of them and then "unload" the file. When I call
Kernel#load with wrap = true, everything of the new file is put into an
anonymous Module, but every other file loaded in the new file itself is
put into the global namespace again.

My questions:

Is it at all possible to prevent this? If so, how to do it?
Can I access the anonymous Module in an easy manner?
How to delete/undefine a class or a method?

Thanks in advance
Benjamin Hepp
10 Answers

Austin Ziegler

7/2/2005 10:30:00 AM

0

On 7/2/05, Benjamin Hepp <benjamin-hepp@t-online.de> wrote:
> Is it at all possible to prevent this? If so, how to do it?

Not cleanly. There's a few examples of wrapped loads that allow you to
load into a random namespace; I've done one myself as a theoretical
example.

Ultimately, though, this isn't the way that Ruby was meant to be used.

What problem are you trying to solve? There might be another way.

-austin
--
Austin Ziegler * halostatue@gmail.com
* Alternate: austin@halostatue.ca


Benjamin Hepp

7/2/2005 11:04:00 AM

0

On Sat, 02 Jul 2005 19:30:25 +0900, Austin Ziegler wrote:

> Not cleanly. There's a few examples of wrapped loads that allow you to
> load into a random namespace; I've done one myself as a theoretical
> example.

Where can I find those examples? I don't know what to search for.


> What problem are you trying to solve? There might be another way.

Well I want to write a FastCGI-Server in ruby. Depending on the queried
website it should load the specific ruby-file based on some pattern.

When I now have a file using GD for example, the loaded GD.so would hang
around all the time. If I changed the file so that it wouldn't use GD
anymore I would have to restart the server so that GD.so doesn't lie
around in the memory forever (until the next reboot at least).

Starting a new ruby-interpreter for every file isn't an option because it
would take to long.

Writing the FastCGI-Server in C isn't an option as well because when I
initialize the ruby-interpreter (ruby_init()) a second time, all loaded
files are still available to the interpreter. Otherwise I could have
reinitialized the interpreter every few hours or so.

Benjamin Hepp

Andrew Walrond

7/2/2005 11:32:00 AM

0

This is what I do in Heretix:

#
# Packages is a container class for all package classes.
# it is used to prevent the Package class names from polluting the global namespace
#
module Packages
# Some package files need to 'require' other package files. The inline function
# ensures that the inclusion occurs within the Packages module as load() and require()
# both pollute the global namespace. If package files need to include other package
# files (eg perl module needs perl.rb) they must use inline() rather than require()
# or load(), which are removed to prevent their use (in the Package.load() function).
#
def Packages.inline(filename)
Packages.module_eval(IO.read(filename),filename)
end
end

def Package.load()

# Load the package classes into the Packages namespace. load() and require()
# both pollute the global namespace, so use some trickery instead. If package
# files need to include other package files (eg perl module needs perl.rb)
# they must use inline() rather than require() or load(), which are removed
# so that relevant warnings are produced when package developers forget...
#
Kernel#remove_method :require
Kernel#remove_method :load
HERETIXDIR.cd {
Dir.glob('core/packages/*.rb').each { |fn| Packages.inline(fn) }
Dir.glob('contrib/packages/*.rb').each { |fn| Packages.inline(fn) }
}

...


Benjamin Hepp

7/2/2005 12:35:00 PM

0

On Sat, 02 Jul 2005 20:32:15 +0900, Andrew Walrond wrote:

> This is what I do in Heretix:
>
> ...
>

Thanks so far.
By overwriting Kernel#load and Kernel#require I could live with this
method. The only problem I still have is how to load a .so file this way.
I need something like module_eval(IO.read(filename)) for .so files. I
guess this is impossible, right?

Benjamin Hepp

Joel VanderWerf

7/2/2005 7:36:00 PM

0

Benjamin Hepp wrote:
> Hello,
>
> I'm trying to build a module-mechanism in ruby so that I am able to load a
> ruby-file without cluttering up the global namespace of the program.
>
> For example I want to be able to load a ruby-file, search for methods in
> it, possibly execute one of them and then "unload" the file. When I call
> Kernel#load with wrap = true, everything of the new file is put into an
> anonymous Module, but every other file loaded in the new file itself is
> put into the global namespace again.
>
> My questions:
>
> Is it at all possible to prevent this? If so, how to do it?
> Can I access the anonymous Module in an easy manner?
> How to delete/undefine a class or a method?

A partial answer is the script library:

http://raa.ruby-lang.org/proj...

It cannot unload a library, and it cannot change what namespace .so
extensions put their definitions in, but:

* It wraps a loaded file (and its "local dependencies") in an instance
of the Script class, which is a subclass of Module.

* You can then assign this Script instance to a local var, constant, or
whatever:

script = Script.load("my-script.rb")

* Top level method defs and constant defs in the wrapped file(s) can be
accessed as methods or constants of this instance:

script.foo()
script::Foo

* The "local dependencies" are defined to be any .rb files that can be
found relative to the dir of the main script. This is handled by
redefining #load and #require in the context of the Script instance. If
the specified path is not found locally (or is a .so), then it falls
back to Kernel#require.

* There's also an autoloading feature.

And there's another library to do this kind of thing:

http://codeforpeople.com/lib/ruby...


Ara.T.Howard

7/2/2005 8:28:00 PM

0

Robert Klemme

7/3/2005 12:41:00 PM

0

Benjamin Hepp <benjamin-hepp@t-online.de> wrote:
> Hello,
>
> I'm trying to build a module-mechanism in ruby so that I am able to
> load a ruby-file without cluttering up the global namespace of the
> program.
>
> For example I want to be able to load a ruby-file, search for methods
> in it, possibly execute one of them and then "unload" the file. When
> I call Kernel#load with wrap = true, everything of the new file is
> put into an anonymous Module, but every other file loaded in the new
> file itself is put into the global namespace again.
>
> My questions:
>
> Is it at all possible to prevent this? If so, how to do it?
> Can I access the anonymous Module in an easy manner?
> How to delete/undefine a class or a method?
>
> Thanks in advance
> Benjamin Hepp

I wonder why noone mentioned Kernel#load so far:
http://www.ruby-doc.org/core/classes/Kernel.ht...

Did I overlook something?

Kind regards

robert

Andrew Walrond

7/3/2005 1:01:00 PM

0

On Sunday 03 July 2005 13:45, Robert Klemme wrote:
> Benjamin Hepp <benjamin-hepp@t-online.de> wrote:
> > I call Kernel#load with wrap = true, everything of the new file is
> > put into an anonymous Module, but every other file loaded in the new
> > file itself is put into the global namespace again.

WRT below, see above. Caffeine topup required, perhaps?

;)

>
> I wonder why noone mentioned Kernel#load so far:
> http://www.ruby-doc.org/core/classes/Kernel.ht...
>
> Did I overlook something?
>
> Kind regards
>
> robert


Robert Klemme

7/3/2005 1:37:00 PM

0

Andrew Walrond <andrew@walrond.org> wrote:
> On Sunday 03 July 2005 13:45, Robert Klemme wrote:
>> Benjamin Hepp <benjamin-hepp@t-online.de> wrote:
>>> I call Kernel#load with wrap = true, everything of the new file is
>>> put into an anonymous Module, but every other file loaded in the new
>>> file itself is put into the global namespace again.
>
> WRT below, see above. Caffeine topup required, perhaps?
>
> ;)

Darn! I knew it had to be something trivial... :-)

robert

>
>>
>> I wonder why noone mentioned Kernel#load so far:
>> http://www.ruby-doc.org/core/classes/Kernel.ht...
>>
>> Did I overlook something?
>>
>> Kind regards
>>
>> robert


Benjamin Hepp

7/3/2005 6:07:00 PM

0

Hello,

Thanks to all the replies.

I will have to live with .so-files polluting my global namespace but the
problem with .rb files is solved now by overwriting load and require.

Greetings
Benjamin Hepp