Mod_ruby and module space


(Sean O'Dell) #1

It seems that if I execute a script using mod_ruby, I cannot call
functions in modules that I write. Here’s a quick example:

SCRIPT1.RBX:
require "script2.rbx"
TestMod::test()

SCRIPT2.RBX
module TestMod
def TestMod::test()
print(“test”)
end
end

Using the ruby command-line interpreter, the code above works just fine.
But under mod_ruby, I get an error along the lines of “TestMod::test
is not a function of TestMod.”

It seems like, although script1.rbx can load script2.rbx properly, it
can’t see the module TestMod, or it can’t see functions of it.

Why is that?

Sean

(Sean O'Dell) #2

Sean O’Dell wrote:

It seems that if I execute a script using mod_ruby, I cannot call
functions in modules that I write. Here’s a quick example:

SCRIPT1.RBX:
require "script2.rbx"
TestMod::test()

SCRIPT2.RBX
module TestMod
def TestMod::test()
print(“test”)
end
end

Using the ruby command-line interpreter, the code above works just fine.
But under mod_ruby, I get an error along the lines of “TestMod::test is
not a function of TestMod.”

It seems like, although script1.rbx can load script2.rbx properly, it
can’t see the module TestMod, or it can’t see functions of it.

No one has any idea what causes this or how I can get around it?

Sean

(Wakou Aoyama) #3

Hi,

mod_ruby/lib/apache/ruby-run.rb

  load(filename, true)

Ruby Language Reference Manual

···

load(file[, priv])
If the optional argument priv is true, loading and evaluating is done
under the unnamed module, to avoid global name space pollution.


Wakou Aoyama wakou@ruby-lang.org


(James) #4

It seems like, although script1.rbx can load script2.rbx properly, it
can’t see the module TestMod, or it can’t see functions of it.

No one has any idea what causes this or how I can get around it?

This works for me:

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

script 1.rbx

require 'script2’
TestMod::test()

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

I renamed script2.rbx to script2.rb, and called it from a web browser.
Worked fine.

James

···

Sean


(Kent Dahl) #5

Sean O’Dell wrote:

No one has any idea what causes this

Sorry, I get the same problems. Though it screams error when trying to
require an .rbx file. Requiring it as an .rb does the silent failure you
describe.

or how I can get around it?

Have you tried load? That seems to work for me.

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


(Sean O'Dell) #6

Kent Dahl wrote:

Sean O’Dell wrote:

No one has any idea what causes this

Sorry, I get the same problems. Though it screams error when trying to
require an .rbx file. Requiring it as an .rb does the silent failure you
describe.

or how I can get around it?

Have you tried load? That seems to work for me.

Oh, did I use require in my example…oops. Yes, I use load, require
doesn’t work. The problem isn’t loading the module, it’s using
functions within a module. When I call functions from one ruby file
which has loaded another ruby file, I can’t call any module functions in
that other ruby file from the first ruby file.

Sean

(Kent Dahl) #7

Sean O’Dell wrote:

Oh, did I use require in my example…oops. Yes, I use load, require
doesn’t work. The problem isn’t loading the module, it’s using
functions within a module. When I call functions from one ruby file
which has loaded another ruby file, I can’t call any module functions in
that other ruby file from the first ruby file.

Well, using those functions worked for me when I loaded the module as an
…rb file.

Uhm, not sure what I did, but this works for me:

script2.rb # Notice, no X

module TestMod
def TestMod::test()
print(“test”)
end
end

> > script1.rbx

load “script2.rb” # Or require “script2” as suggested by James
TestMod::test()
puts # Without this, Netscape replies “Document contained no data.”

Looks like perhaps some flushing problem in mod_ruby? I get “test” as a
result by this on my server.
I’m on ruby 1.6.7 (2002-03-01) [i586-linux], with mod_ruby-0.9.8

HTH

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


(Sean O'Dell) #8

Kent Dahl wrote:

Sean O’Dell wrote:

Oh, did I use require in my example…oops. Yes, I use load, require
doesn’t work. The problem isn’t loading the module, it’s using
functions within a module. When I call functions from one ruby file
which has loaded another ruby file, I can’t call any module functions in
that other ruby file from the first ruby file.

Well, using those functions worked for me when I loaded the module as an
.rb file.

Uhm, not sure what I did, but this works for me:

script2.rb # Notice, no X

module TestMod
def TestMod::test()
print(“test”)
end
end

> > script1.rbx

load “script2.rb” # Or require “script2” as suggested by James
TestMod::test()
puts # Without this, Netscape replies “Document contained no data.”

Looks like perhaps some flushing problem in mod_ruby? I get “test” as a
result by this on my server.
I’m on ruby 1.6.7 (2002-03-01) [i586-linux], with mod_ruby-0.9.8

Actually, my actual test over here used an .rb file, not an .rbx…but
it shouldn’t make a difference with require/load, eh?

So, you can call module functions in one script file from other script
files in mod_ruby? Weird…I wonder what the heck is going on.

Sean

(Sean O'Dell) #9

Kent Dahl wrote:

Sean O’Dell wrote:

Oh, did I use require in my example…oops. Yes, I use load, require
doesn’t work. The problem isn’t loading the module, it’s using
functions within a module. When I call functions from one ruby file
which has loaded another ruby file, I can’t call any module functions in
that other ruby file from the first ruby file.

Well, using those functions worked for me when I loaded the module as an
.rb file.

Uhm, not sure what I did, but this works for me:

script2.rb # Notice, no X

module TestMod
def TestMod::test()
print(“test”)
end
end

> > script1.rbx

load “script2.rb” # Or require “script2” as suggested by James
TestMod::test()
puts # Without this, Netscape replies “Document contained no data.”

Looks like perhaps some flushing problem in mod_ruby? I get “test” as a
result by this on my server.
I’m on ruby 1.6.7 (2002-03-01) [i586-linux], with mod_ruby-0.9.8

Ah ha!

Okay, the culprit seems to be when the module is defined before the load
call which loads another file which also uses the module. Here’s an
example (you can cut and paste these verbatim):

TESTSCR.RBX:

module TestMod
end

load "testmod.rb"
TestMod::testfunc()

TESTMOD.RB:

require "cgi"
require “PageTemplate”

module TestMod
@cgi = CGI.new

def TestMod::testfunc()
@cgi.print(“testfunc\r\n”)
end

begin
@cgi.print(“HTTP/1.1 200 OK\r\n”)
@cgi.print(“Content-Type: text/plain\r\n\r\n”)

 @cgi.print("start\r\n")

rescue Exception => e
@cgi.out do
"An error occurred!
" +
“Please report the following message to the administrator:
” +

"

#{e.message}
\n#{e.backtrace.join(’
\n’)}
"
end
end
end

Note that this works fine from the Ruby command-line. However, under
mod_ruby it hoses. If you comment out the first two lines in
testscr.rbx, it works fine. For some reason, having the module already
defined when the other file is loaded causes some sort of problem. Not
sure why, exactly. Actually, I moved the module definition to right
after the load and the same thing happens.

What’s going on? Why does having the module definition in the first
file crash mod_ruby when I try to call that function? Why is
command-line Ruby perfectly happy with it?

Sean

(Kent Dahl) #10

Sean O’Dell wrote:

Note that this works fine from the Ruby command-line. However, under
mod_ruby it hoses. If you comment out the first two lines in
testscr.rbx, it works fine. For some reason, having the module already
defined when the other file is loaded causes some sort of problem. Not
sure why, exactly. Actually, I moved the module definition to right
after the load and the same thing happens.

Hmm. But if I move the empty module definition into a third .rb file and
require that separately, all appears well again.

What’s going on? Why does having the module definition in the first
file crash mod_ruby when I try to call that function? Why is
command-line Ruby perfectly happy with it?

Does it really crash? Or do you mean merely it doesn’t work? I haven’t
had Apache die on me yet, or any such thing…

I have an idea what is going on, but I’m going to investigate a bit
more, just in case I’m sticking my foot in my mouth. But for now, I’m
getting
/home/httpd/html/ruby/test/testscr.rbx:10:
undefined method `testfunc’ for
#<Module 0lx2aead188>::TestMod (NameError)
and the nameless module before TestMod makes me think that mod_ruby is
wrapping the loaded code, to avoid it cluttering the namespace of other
mod_ruby programs? And this might confuse you (and Ruby) with regards to
just which TestMod you are accessing.

But big foot in mouth disclaimer as I haven’t found a good way to test
this yet, nor couldn’t find anything in the mod_ruby sources at first
glance…

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


(Kent Dahl) #11

Kent Dahl wrote:

I have an idea what is going on, but I’m going to investigate a bit
more, just in case I’m sticking my foot in my mouth. But for now, I’m
getting
/home/httpd/html/ruby/test/testscr.rbx:10:
undefined method `testfunc’ for
#<Module 0lx2aead188>::TestMod (NameError)
and the nameless module before TestMod makes me think that mod_ruby is
wrapping the loaded code, to avoid it cluttering the namespace of other
mod_ruby programs? And this might confuse you (and Ruby) with regards to
just which TestMod you are accessing.

Ah, yes, try this on for size:

module TestMod
end

load "testmod.rb"
puts TestMod.to_s
::TestMod::testfunc()
puts “—#{TestMod::methods.size} vs #{::TestMod::methods.size}—”

Which retorts “—60 vs 61—” to me. It seems like the load of the
script is wrapped in the nameless module, but anything that script
requires or loads goes to the toplevel non the less. Still haven’t found
the source in mod_ruby that does this, but I’m convinced :slight_smile:

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


(Sean O'Dell) #12

Kent Dahl wrote:

Kent Dahl wrote:

I have an idea what is going on, but I’m going to investigate a bit
more, just in case I’m sticking my foot in my mouth. But for now, I’m
getting
/home/httpd/html/ruby/test/testscr.rbx:10:
undefined method `testfunc’ for
#<Module 0lx2aead188>::TestMod (NameError)
and the nameless module before TestMod makes me think that mod_ruby is
wrapping the loaded code, to avoid it cluttering the namespace of other
mod_ruby programs? And this might confuse you (and Ruby) with regards to
just which TestMod you are accessing.

Which retorts “—60 vs 61—” to me. It seems like the load of the
script is wrapped in the nameless module, but anything that script
requires or loads goes to the toplevel non the less. Still haven’t found
the source in mod_ruby that does this, but I’m convinced :slight_smile:

That’s the conclusion I came to here, that the first script is in an
anonymous namespace and the loaded module seems to be in another
namespace altogether…guess it’s time to report that. I just switched
to having my scripts executed as CGI programs using command-line ruby.
mod_ruby has some fundamental things I don’t like about it, like not
being able to completely clean up the interpreter between uses. Between
that feature and Ruby’s garbage collection system, preserving resources
seems to be a forgotten relic of ancient programming techniques or
something. I wish there was more focus on making things clean and tight.

Sean

(Kent Dahl) #13

Sean O’Dell wrote:

That’s the conclusion I came to here, that the first script is in an
anonymous namespace and the loaded module seems to be in another
namespace altogether…guess it’s time to report that.

The loaded (or required) module falls into the toplevel namespace, where
it should be. (Or requiring any library would get very messy indeed.)

BTW: A nice thing I hadn’t seen anywhere in the mod_ruby documentation;
the lib/apache/ruby-debug.rb variant which outputs exception info to the
client. (It really should have been default in the installation for
mod_ruby_nubies like myself. :slight_smile:

I just switched
to having my scripts executed as CGI programs using command-line ruby.
mod_ruby has some fundamental things I don’t like about it, like not
being able to completely clean up the interpreter between uses.

Is it really that bad? I mean, the resources that take up space is
mostly compiled code, such as the required files that still lingers in
memory (and makes subsequent calls to the script faster, I would assume,
since the requires would just return at once) and whatever hasn’t been
taken by a GC just yet. I wouldn’t think that any other junk would float
around. But I’m not intimate with the details of mod_ruby…

Between
that feature and Ruby’s garbage collection system, preserving resources
seems to be a forgotten relic of ancient programming techniques or
something. I wish there was more focus on making things clean and tight.

I know what you mean, but as for this case, with webservers and
server-side scripts, I think that the resource-eating is fairly
proportional to the speedgains. (Now, as for running Ruby stuff on a
handheld that isn’t one of the new $500 monsters, I totally agree :-))

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


(Sean O'Dell) #14

Kent Dahl wrote:

Sean O’Dell wrote:

That’s the conclusion I came to here, that the first script is in an
anonymous namespace and the loaded module seems to be in another
namespace altogether…guess it’s time to report that.

The loaded (or required) module falls into the toplevel namespace, where
it should be. (Or requiring any library would get very messy indeed.)

BTW: A nice thing I hadn’t seen anywhere in the mod_ruby documentation;
the lib/apache/ruby-debug.rb variant which outputs exception info to the
client. (It really should have been default in the installation for
mod_ruby_nubies like myself. :slight_smile:

I just switched
to having my scripts executed as CGI programs using command-line ruby.
mod_ruby has some fundamental things I don’t like about it, like not
being able to completely clean up the interpreter between uses.

Is it really that bad? I mean, the resources that take up space is
mostly compiled code, such as the required files that still lingers in
memory (and makes subsequent calls to the script faster, I would assume,
since the requires would just return at once) and whatever hasn’t been
taken by a GC just yet. I wouldn’t think that any other junk would float
around. But I’m not intimate with the details of mod_ruby…

I’m going to use mod_ruby where I can…but it does freak me out.
Luckily, I’m going to be hosting Apache in a chroot’d environment from
now on, so scripts run by multiple clients on the same machine won’t
have to share environments. I’m sure Apache 2.0 with its threading will
help make that a non-issue, but under 1.3, virtual hosting with Ruby and
Apache would be a security nightmare.

What’s really sad is, the only thing I could count on to clean up a Ruby
script was the complete shutting down of the interpreter between each
script. But mod_ruby took that away! :frowning:

Between
that feature and Ruby’s garbage collection system, preserving resources
seems to be a forgotten relic of ancient programming techniques or
something. I wish there was more focus on making things clean and tight.

I know what you mean, but as for this case, with webservers and
server-side scripts, I think that the resource-eating is fairly
proportional to the speedgains. (Now, as for running Ruby stuff on a
handheld that isn’t one of the new $500 monsters, I totally agree :-))

Possibly…throwing memory at the Ruby GC issue isn’t so bad, I guess.

Sean

(Sean O'Dell) #15

Kent Dahl wrote:

BTW: A nice thing I hadn’t seen anywhere in the mod_ruby documentation;
the lib/apache/ruby-debug.rb variant which outputs exception info to the
client. (It really should have been default in the installation for
mod_ruby_nubies like myself. :slight_smile:

BTW, where is that module? I’d like to set it up here.

Sean

(Kent Dahl) #16

In the mod_ruby-0.9.8 source, it is in the lib/apache/ directory. The .rb
file contains documentation how to set it up. I think it is installed
along with the normal one, so you just need to change the httpd.conf:

== Example of httpd.conf

RubyRequire apache/ruby-debug
<Location /ruby-debug>
SetHandler ruby-object
RubyHandler Apache::RubyDebug.instance

=end

The only differences is the RubyRequire and RubyHandler lines.

···

On Wed, 5 Jun 2002, Sean O’Dell wrote:

Kent Dahl wrote:
BTW: A nice thing I hadn’t seen anywhere in the mod_ruby documentation;
the lib/apache/ruby-debug.rb variant which outputs exception info to the
client. (It really should have been default in the installation for
mod_ruby_nubies like myself. :slight_smile:

BTW, where is that module? I’d like to set it up here.


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


(Sean Chittenden) #17

> > BTW: A nice thing I hadn't seen anywhere in the mod_ruby documentation;
> > the lib/apache/ruby-debug.rb variant which outputs exception info to the
> > client. (It really should have been default in the installation for
> > mod_ruby_nubies like myself. :slight_smile:
>
> BTW, where is that module? I'd like to set it up here.

In the mod_ruby-0.9.8 source, it is in the lib/apache/ directory. The .rb
file contains documentation how to set it up. I think it is installed
along with the normal one, so you just need to change the httpd.conf:

== Example of httpd.conf

  RubyRequire apache/ruby-debug
  <Location /ruby-debug>
  SetHandler ruby-object
  RubyHandler Apache::RubyDebug.instance
  </Location>

=end

The only differences is the RubyRequire and RubyHandler lines.

Along the lines of debugging and quality, there's another approach
worth considering here:

http://sean.chittenden.org/programming/ruby/mod_ruby/apachecon-2002/intro_to_mod_ruby/html/node35.html

Catching all web errors and saving them has done wonders for me for
squashing bugs. One thing that I like about this approach is that I
don't have to worry about catching every exception in my scripts: I
just let this one script handle all uncaught exceptions and act
accordingly. Keeps consistency high and the amount of typing low.
-sc

···

--
Sean Chittenden


(Kent Dahl) #18

Sean Chittenden wrote:

http://sean.chittenden.org/programming/ruby/mod_ruby/apachecon-2002/intro_to_mod_ruby/html/node35.html

Catching all web errors and saving them has done wonders for me for
squashing bugs. One thing that I like about this approach is that I
don’t have to worry about catching every exception in my scripts: I
just let this one script handle all uncaught exceptions and act
accordingly. Keeps consistency high and the amount of typing low.

Neat!

Methinks this might even make tech-support people happy:

  • “So you got [obscure error message] at 18:07?”
  • "Oh dear, you’re inside my PC right now, aren’t you?"
    cue customer hangs up and pulls all plugs

( Ok, ok… I stole that off something I read the other day. )

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 4. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)