[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Dynamically loading and executing within a new module?

Lloyd Zusman

2/19/2005 9:42:00 PM

I'm not sure what would be the best way to accomplish the following in
ruby:

I'm writing a program that periodically looks for files in a certain
directory. If it finds new ones, I want it to ...

1. Dynamically create a new module whose name is based somehow upon the
name of the file.

2. Do a Kernel#load on the file within this newly created module.

3. Invoke a method called #init that is defined in this file (assuming
that this method is actually defined), and do the invocation within
the context of that newly-created module.

For example, suppose my directory contains the following files:

foo.module
----------
def init
puts "invoking #init within #{self}"
end

bar.module
----------
def init
puts "invoking #init within #{self}"
end

When my program encounters the "foo.module" file, I'd like it to do the
following:

- create a module called Foo (the name of the file with ".module"
stripped off and the first letter capitalized) ... or maybe
SomethingElse::Foo, to avoid collisions with existing packages

- do a load() of the "foo.module" file within the context of this
newly created Foo module (or SomethingElse::Foo module)

- check to see if the #init method is now defined within the
Foo module; if so, invoke that as a class method within the
context of that module (i.e., as if it were invoked like
Foo#init); this should cause the following message to
print:

invoking #init within Foo

What is the recommended way for accomplishing all this within Ruby?

--
Lloyd Zusman
ljz@asfast.com
God bless you.



9 Answers

ES

2/19/2005 10:07:00 PM

0


On 2/19/2005, "Lloyd Zusman" <ljz@asfast.com> wrote:

>I'm not sure what would be the best way to accomplish the following in
>ruby:
>
>I'm writing a program that periodically looks for files in a certain
>directory. If it finds new ones, I want it to ...
>
>1. Dynamically create a new module whose name is based somehow upon the
> name of the file.
>
>2. Do a Kernel#load on the file within this newly created module.
>
>3. Invoke a method called #init that is defined in this file (assuming
> that this method is actually defined), and do the invocation within
> the context of that newly-created module.
>
>For example, suppose my directory contains the following files:
>
> foo.module
> ----------
> def init
> puts "invoking #init within #{self}"
> end
>
> bar.module
> ----------
> def init
> puts "invoking #init within #{self}"
> end
>
>When my program encounters the "foo.module" file, I'd like it to do the
>following:
>
> - create a module called Foo (the name of the file with ".module"
> stripped off and the first letter capitalized) ... or maybe
> SomethingElse::Foo, to avoid collisions with existing packages
>
> - do a load() of the "foo.module" file within the context of this
> newly created Foo module (or SomethingElse::Foo module)
>
> - check to see if the #init method is now defined within the
> Foo module; if so, invoke that as a class method within the
> context of that module (i.e., as if it were invoked like
> Foo#init); this should cause the following message to
> print:
>
> invoking #init within Foo
>
>What is the recommended way for accomplishing all this within Ruby?

If you don't just want to write an actual module and then call its #init,
you could do something like this. Somewhat pseudo:

Thread.new do
if fname
mod = eval fname.capitalize
data = File.new(fname, 'r') do |f|
f.read
end
mod.module_eval data
mod.send :init, args
# ...
end
end

Or sumptin :)

> Lloyd Zusman

E



Lloyd Zusman

2/19/2005 10:23:00 PM

0

ES <ruby-ml@magical-cat.org> writes:

> On 2/19/2005, "Lloyd Zusman" <ljz@asfast.com> wrote:
>
>> [ ... ]
>>
>>When my program encounters the "foo.module" file, I'd like it to do the
>>following:
>>
>> - create a module called Foo (the name of the file with ".module"
>> stripped off and the first letter capitalized) ... or maybe
>> SomethingElse::Foo, to avoid collisions with existing packages
>>
>> - do a load() of the "foo.module" file within the context of this
>> newly created Foo module (or SomethingElse::Foo module)
>>
>> - check to see if the #init method is now defined within the
>> Foo module; if so, invoke that as a class method within the
>> context of that module (i.e., as if it were invoked like
>> Foo#init); this should cause the following message to
>> print:
>>
>> invoking #init within Foo
>>
>>What is the recommended way for accomplishing all this within Ruby?
>
> If you don't just want to write an actual module and then call its #init,
> you could do something like this. Somewhat pseudo:
>
> Thread.new do
> if fname
> mod = eval fname.capitalize
> data = File.new(fname, 'r') do |f|
> f.read
> end
> mod.module_eval data
> mod.send :init, args
> # ...
> end
> end
>
> Or sumptin :)

Thanks. This makes sense.

However, the "eval fname.capitalize" part doesn't create a new module,
and that's part of what is confusing me about all this. Given a string
"Foo", what do I do to it in order to create a module object with that
name?


--
Lloyd Zusman
ljz@asfast.com
God bless you.



Lloyd Zusman

2/19/2005 10:47:00 PM

0

Lloyd Zusman <ljz@asfast.com> writes:

> ES <ruby-ml@magical-cat.org> writes:
>
>>
>> [ ... ]
>>
>> If you don't just want to write an actual module and then call its #init,
>> you could do something like this. Somewhat pseudo:
>>
>> Thread.new do
>> if fname
>> mod = eval fname.capitalize
>> data = File.new(fname, 'r') do |f|
>> f.read
>> end
>> mod.module_eval data
>> mod.send :init, args
>> # ...
>> end
>> end
>>
>> Or sumptin :)
>
> Thanks. This makes sense.
>
> However, the "eval fname.capitalize" part doesn't create a new module,
> and that's part of what is confusing me about all this. Given a string
> "Foo", what do I do to it in order to create a module object with that
> name?

Actually, I now realize that I don't need a bona fide named module, but
rather, just a way to associate a name with a module. Therefore, I
think that I can do it more or less like this:

modhash = Hash.new
if fname then
if modhash.has_key?(fname) then
mod = modhash[fname]
else
mod = Module.new
modhash[fname] = mod
end
data = File.new(fname, 'r') do |f|
f.read
end
mod.module_eval data
mod.send :init, args
end

Does this make sense?


--
Lloyd Zusman
ljz@asfast.com
God bless you.



Christoph R.

2/19/2005 11:11:00 PM

0

Lloyd Zusman schrieb:

>However, the "eval fname.capitalize" part doesn't create a new module,
>and that's part of what is confusing me about all this. Given a string
>"Foo", what do I do to it in order to create a module object with that
>name?
>
>
use Module#new - for example

---
MyNameSpace.const_set fname.capitalize, Module.new
---

You can automate things

class MyModule < Module
def initialize(fname)
::MyNameSpace.const_set fname.capitalize, self
# maybe add the the MyModule method
# using the text file ....
end
end

/Christoph


Christoph R.

2/19/2005 11:25:00 PM

0

Lloyd Zusman schrieb:

>Actually, I now realize that I don't need a bona fide named module, but
>rather, just a way to associate a name with a module. Therefore, I
>think that I can do it more or less like this:
>
> modhash = Hash.new
> if fname then
> if modhash.has_key?(fname) then
> mod = modhash[fname]
> else
> mod = Module.new
> modhash[fname] = mod
> end
> data = File.new(fname, 'r') do |f|
> f.read
> end
> mod.module_eval data
> mod.send :init, args
> end
>
>Does this make sense?
>
>
>
>
You can also use MyNameSpace#const_get
with a rescue clause

/Christoph


ES

2/20/2005 1:13:00 AM

0


On 2/19/2005, "Lloyd Zusman" <ljz@asfast.com> wrote:

>Lloyd Zusman <ljz@asfast.com> writes:
>
>> ES <ruby-ml@magical-cat.org> writes:
>>
>>>
>>> [ ... ]
>>>
>>> If you don't just want to write an actual module and then call its #init,
>>> you could do something like this. Somewhat pseudo:
>>>
>>> Thread.new do
>>> if fname
>>> mod = eval fname.capitalize
>>> data = File.new(fname, 'r') do |f|
>>> f.read
>>> end
>>> mod.module_eval data
>>> mod.send :init, args
>>> # ...
>>> end
>>> end
>>>
>>> Or sumptin :)
>>
>> Thanks. This makes sense.
>>
>> However, the "eval fname.capitalize" part doesn't create a new module,
>> and that's part of what is confusing me about all this. Given a string
>> "Foo", what do I do to it in order to create a module object with that
>> name?
>
>Actually, I now realize that I don't need a bona fide named module, but
>rather, just a way to associate a name with a module. Therefore, I
>think that I can do it more or less like this:
>
> modhash = Hash.new
> if fname then
> if modhash.has_key?(fname) then
> mod = modhash[fname]
> else
> mod = Module.new
> modhash[fname] = mod
> end
> data = File.new(fname, 'r') do |f|
> f.read
> end
> mod.module_eval data
> mod.send :init, args
> end
>
>Does this make sense?

Yes, but I'm not sure if I understand why you're doing this in the first
place. Why don't you just create a named module, store it in a file and
load
it when requested instead of just storing the code that'll go in the
module?

> Lloyd Zusman

E



Lloyd Zusman

2/20/2005 2:23:00 AM

0

ES <ruby-ml@magical-cat.org> writes:

> On 2/19/2005, "Lloyd Zusman" <ljz@asfast.com> wrote:
>>
>> [ ... ]
>>
>>Actually, I now realize that I don't need a bona fide named module, but
>>rather, just a way to associate a name with a module. Therefore, I
>>think that I can do it more or less like this:
>>
>> modhash = Hash.new
>> if fname then
>> if modhash.has_key?(fname) then
>> mod = modhash[fname]
>> else
>> mod = Module.new
>> modhash[fname] = mod
>> end
>> data = File.new(fname, 'r') do |f|
>> f.read
>> end
>> mod.module_eval data
>> mod.send :init, args
>> end
>>
>>Does this make sense?
>
> Yes, but I'm not sure if I understand why you're doing this in the
> first place. Why don't you just create a named module, store it in a
> file and load it when requested instead of just storing the code
> that'll go in the module?

Because I want to share code (via symbolic links) and associate it with
several modules, each module being named differently, based on the file
in which it resides. Also, I may change the names of these files from
time to time, and when I do, I don't want to also have to remember to
also change the module names contained in these files.

By dynamically naming the modules in the ways we have been discussing,
this allows me to have a unique namespace for each file-based module
that I create, even if several files share the same contents via
symbolic links. And this is ensured no matter how many renames
or symbolic link changes I make.

--
Lloyd Zusman
ljz@asfast.com
God bless you.



Lloyd Zusman

2/20/2005 2:43:00 AM

0

Christoph <chr_mail@gmx.net> writes:

> Lloyd Zusman schrieb:
>
>>Actually, I now realize that I don't need a bona fide named module, but
>>rather, just a way to associate a name with a module. Therefore, I
>>think that I can do it more or less like this:
>>
>> modhash = Hash.new
>> if fname then
>> if modhash.has_key?(fname) then
>> mod = modhash[fname]
>> else
>> mod = Module.new
>> modhash[fname] = mod
>> end
>> data = File.new(fname, 'r') do |f|
>> f.read
>> end
>> mod.module_eval data
>> mod.send :init, args
>> end
>>
>>Does this make sense?
>>
>>
>>
>>
> You can also use MyNameSpace#const_get
> with a rescue clause

Yes ... makes sense. Thanks.

--
Lloyd Zusman
ljz@asfast.com
God bless you.



Lloyd Zusman

2/20/2005 2:44:00 AM

0

Christoph <chr_mail@gmx.net> writes:

> Lloyd Zusman schrieb:
>
>>However, the "eval fname.capitalize" part doesn't create a new module,
>>and that's part of what is confusing me about all this. Given a string
>>"Foo", what do I do to it in order to create a module object with that
>>name?
>>
>>
> use Module#new - for example
>
> ---
> MyNameSpace.const_set fname.capitalize, Module.new
> ---
>
> You can automate things
>
> class MyModule < Module
> def initialize(fname)
> ::MyNameSpace.const_set fname.capitalize, self
> # maybe add the the MyModule method
> # using the text file ....
> end
> end
> /Christoph

Aha! ... that's a great idea. I love how ruby (like Smalltalk) makes
classes, objects, etc. into first-class objects.

--
Lloyd Zusman
ljz@asfast.com
God bless you.