Getting a method or class within a file

Hi,

I want to be able to do the following:

lots of Ruby files are in a directory, each containing stuff and a method 'init_file'. I want to be able to 'require' each file, and then call the 'init_file' method within that file.

Each file will have its own 'init_file' method, so I can't just do a:

require 'file'
init_file

because the init_file method will have been defined before hand.

Is it possible, like in Perl, for an included file to return a value?

Asfand Yar Qazi schrieb:

I want to be able to do the following:

lots of Ruby files are in a directory, each containing stuff and a method 'init_file'. I want to be able to 'require' each file, and then call the 'init_file' method within that file.

Each file will have its own 'init_file' method, so I can't just do a:

require 'file'
init_file

because the init_file method will have been defined before hand.

Not that I would recommend that, but you can do

   require 'file1'
   init_file

   require 'file2'
   init_file

because the init_file method of file2 will overwrite the init_file method of file1.

But: of course this is bad style. Where do your Ruby files come from? Can't you wrap the code in each file in a class or module?

Regards,
Pit

"Asfand Yar Qazi" <ay1204@qazi.f2s.com> schrieb im Newsbeitrag news:37r4gcF5e28v0U1@individual.net...

Hi,

I want to be able to do the following:

lots of Ruby files are in a directory, each containing stuff and a method 'init_file'. I want to be able to 'require' each file, and then call the 'init_file' method within that file.

Do you want to invoke init_file *always* if you require a file or just on every first load? If it's the typical intialization stuff, here are three methods you can use (see attached).

Each file will have its own 'init_file' method, so I can't just do a:

require 'file'
init_file

because the init_file method will have been defined before hand.

Is it possible, like in Perl, for an included file to return a value?

I think you can do that with load but not require because require returns whether the file was read or not.

Kind regards

    robert

req.rb (82 Bytes)

in3.rb (45 Bytes)

in1.rb (38 Bytes)

in2.rb (38 Bytes)

Asfand Yar Qazi wrote:

Hi,

I want to be able to do the following:

lots of Ruby files are in a directory, each containing stuff and a method 'init_file'. I want to be able to 'require' each file, and then call the 'init_file' method within that file.

Each file will have its own 'init_file' method, so I can't just do a:

require 'file'
init_file

because the init_file method will have been defined before hand.

Is it possible, like in Perl, for an included file to return a value?

You can do this using the "script" lib I just mentioned on another thread.

---- main.rb ----
require 'script'

mod1 = Script.load("file1.rb")
mod2 = Script.load("file2.rb")

[mod1, mod2].each do |mod|
   mod.init_file
   puts "The value of X for #{mod.inspect} is #{mod::X}"
end

---- file1.rb ----
def init_file
   puts "init for #{__FILE__}"
end

X = "One"

---- file2.rb ----
def init_file
   puts "init for #{__FILE__}"
end

X = "Two"

···

------------------

Output:
init for /tmp/script-example/file1.rb
The value of X for #<Script:/tmp/script-example/file1.rb> is One
init for /tmp/script-example/file2.rb
The value of X for #<Script:/tmp/script-example/file2.rb> is Two

Script also defines #autoscript, which you can use like #autoload to load the modules on demand and assign them to constants.

Pit Capitain wrote:

Asfand Yar Qazi schrieb:

I want to be able to do the following:

lots of Ruby files are in a directory, each containing stuff and a method 'init_file'. I want to be able to 'require' each file, and then call the 'init_file' method within that file.

Each file will have its own 'init_file' method, so I can't just do a:

require 'file'
init_file

because the init_file method will have been defined before hand.

Not that I would recommend that, but you can do

  require 'file1'
  init_file

  require 'file2'
  init_file

because the init_file method of file2 will overwrite the init_file method of file1.

But: of course this is bad style. Where do your Ruby files come from? Can't you wrap the code in each file in a class or module?

It's also thread-unsafe.

You're right. I think what I'll do is to have a combination of a Module name and a filename that will allow there to be an init method contained within 'Module', contained within 'file'.

But then I'll have to store 2 entries: filename and module name. But I suppose that's ok. Perhaps I should use the following syntax:

Module@path/to/file.rb

to show that a module is in a certain file?

Robert Klemme wrote:

Do you want to invoke init_file *always* if you require a file or just on every first load? If it's the typical intialization stuff, here are three methods you can use (see attached).

Not always, just the first time.

I think you can do that with load but not require because require returns whether the file was read or not.

Actually, I just tested load, and it also just returns true. No 'value of last expression' returned.

Many thanks

Joel VanderWerf wrote:

Asfand Yar Qazi wrote:

Hi,

I want to be able to do the following:

lots of Ruby files are in a directory, each containing stuff and a method 'init_file'. I want to be able to 'require' each file, and then call the 'init_file' method within that file.

Each file will have its own 'init_file' method, so I can't just do a:

require 'file'
init_file

because the init_file method will have been defined before hand.

Is it possible, like in Perl, for an included file to return a value?

You can do this using the "script" lib I just mentioned on another thread.

---- main.rb ----
require 'script'

mod1 = Script.load("file1.rb")
mod2 = Script.load("file2.rb")

[mod1, mod2].each do |mod|
  mod.init_file
  puts "The value of X for #{mod.inspect} is #{mod::X}"
end

---- file1.rb ----
def init_file
  puts "init for #{__FILE__}"
end

X = "One"

---- file2.rb ----
def init_file
  puts "init for #{__FILE__}"
end

X = "Two"

------------------

Output:
init for /tmp/script-example/file1.rb
The value of X for #<Script:/tmp/script-example/file1.rb> is One
init for /tmp/script-example/file2.rb
The value of X for #<Script:/tmp/script-example/file2.rb> is Two

Script also defines #autoscript, which you can use like #autoload to load the modules on demand and assign them to constants.

ahhh..........

this may be useful

It sounds like you're basically doing a plugin framework.

Ruwiki uses something like this when reading its Token classes. Look
at lib/ruwiki/wiki/tokens.rb to see how I do it.

There is a plugin framework (FreeBASE) that may also be suitable for
you in this instance.

···

On Sun, 20 Feb 2005 20:54:42 +0900, Asfand Yar Qazi <ay1204@qazi.f2s.com> wrote:

Pit Capitain wrote:
> Asfand Yar Qazi schrieb:
>
>> I want to be able to do the following:
>>
>> lots of Ruby files are in a directory, each containing stuff and a
>> method 'init_file'. I want to be able to 'require' each file, and
>> then call the 'init_file' method within that file.
>>
>> Each file will have its own 'init_file' method, so I can't just do a:
>>
>> require 'file'
>> init_file
>>
>> because the init_file method will have been defined before hand.
>
>
> Not that I would recommend that, but you can do
>
> require 'file1'
> init_file
>
> require 'file2'
> init_file
>
> because the init_file method of file2 will overwrite the init_file
> method of file1.
>
> But: of course this is bad style. Where do your Ruby files come from?
> Can't you wrap the code in each file in a class or module?
>

It's also thread-unsafe.

You're right. I think what I'll do is to have a combination of a
Module name and a filename that will allow there to be an init method
contained within 'Module', contained within 'file'.

But then I'll have to store 2 entries: filename and module name. But
I suppose that's ok. Perhaps I should use the following syntax:

Module@path/to/file.rb

to show that a module is in a certain file?

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

Austin Ziegler wrote:

But then I'll have to store 2 entries: filename and module name. But
I suppose that's ok. Perhaps I should use the following syntax:

Module@path/to/file.rb

to show that a module is in a certain file?

It sounds like you're basically doing a plugin framework.

I want to be able to load up objects 'on demand', i.e. when they're needed and not before. In a very simple way, nothing fancy.

Ruwiki uses something like this when reading its Token classes. Look
at lib/ruwiki/wiki/tokens.rb to see how I do it.

There is a plugin framework (FreeBASE) that may also be suitable for
you in this instance.

Ah, thanks I'll take a look.

Asfand Yar Qazi wrote:

Austin Ziegler wrote:

But then I'll have to store 2 entries: filename and module name. But
I suppose that's ok. Perhaps I should use the following syntax:

Module@path/to/file.rb

to show that a module is in a certain file?

It sounds like you're basically doing a plugin framework.

I want to be able to load up objects 'on demand', i.e. when they're needed and not before. In a very simple way, nothing fancy.

Kernel#autoload might be of use if you have a discrete set of files?

Ruwiki uses something like this when reading its Token classes. Look
at lib/ruwiki/wiki/tokens.rb to see how I do it.

There is a plugin framework (FreeBASE) that may also be suitable for
you in this instance.

Ah, thanks I'll take a look.

E

ES wrote:

I want to be able to load up objects 'on demand', i.e. when they're needed and not before. In a very simple way, nothing fancy.

Kernel#autoload might be of use if you have a discrete set of files?

Think loading up Actors in Areas of a Game - no discreteness here :slight_smile: