Re: RailsDispatcher and files in "lib"

Andre Nathan <[email protected]> Fri, 05 Jan 2007 11:20:10 -0200
Newsgroups gmane.comp.apache.mod-ruby
Message-ID <[email protected]>
--=-6aBpZ9p1ryW1VQZPkZ9j
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

OK, I got it to work. I'm attaching the current patch in case someone
else ends up having this problem. I'll try to contact Shugo to ask him
if this is the correct fix for the problem.

Andre


On Thu, 2007-01-04 at 16:27 -0200, Andre Nathan wrote:
> On Thu, 2007-01-04 at 00:06 -0200, Andre Nathan wrote:
> > [Wed Jan 03 23:53:27 2007] [error]
> > mod_ruby: /usr/lib/ruby/1.8/apache/rails-dispatcher.rb:262:in
> > `eval': /usr/lib/ruby/1.8/apache/rails-dispatcher.rb:441:in
> > `const_missing': uninitialized constant Ozimodo (NameError)
> 
> In environment.rb, ozimodo does this:
> 
> Dir[File.join(THEME_DIR, 'tumble', 'types', '*')].each do |f|
>   TYPES[File.basename(f).sub(/^_/,'').sub('.rhtml','')] =
>     Ozimodo::TypeParser.parse_file(f)
> end
> 
> and that's where the error comes from. With the patch attached, I
> managed to make the Ozimodo module to be found, but now it can't see the
> TypeParser class that's defined inside it:
> 
> [Thu Jan 04 15:54:18 2007] [error]
> mod_ruby: /usr/lib/ruby/1.8/apache/rails-dispatcher.rb:262:in
> `eval': /usr/lib/ruby/1.8/apache/rails-dispatcher.rb:459:in
> `const_missing': uninitialized constant TypeParser (NameError)
> 
> What happens is the following: in the "Module#const_missing" definition
> in rails-dispatcher.rb, there is the following code:
> 
>   require_dependency(file_path)
>   if env.module.const_defined?(class_id)
>     return env.module.const_get(class_id)
>   else
>     raise LoadError
>   end
> 
> file_path is "ozimodo/type_parser", and class_id is :TypeParser. The
> call to require_dependency works (as "lib/ozimodo/type_parser.rb"
> exists) and the file is loaded, but the TypeParser constant is not
> defined in env.module (Apache::RailsDispatcher::CURRENT_MODULE), but in
> Apache::RailsDispatcher::CURRENT_MODULE::Ozimodo instead. I still
> couldn't figure out the correct way to make it find the constants
> recusively in submodules of env.module... I'll see if I get some idea
> from the rails source now...
> 
> Does anyone know if Shugo reads this list? Is there any working
> interface for bug reports or for sending patches?
> 
> Thanks,
> Andre

--=-6aBpZ9p1ryW1VQZPkZ9j
Content-Disposition: attachment; filename=rails-dispatcher.patch
Content-Type: text/x-patch; name=rails-dispatcher.patch; charset=utf-8
Content-Transfer-Encoding: 7bit

--- rails-dispatcher.rb.orig	2007-01-04 16:34:59.933478520 -0200
+++ rails-dispatcher.rb	2007-01-05 11:15:18.522770348 -0200
@@ -98,7 +98,7 @@
     end
 
     def handler(r)
-      if !/\Adispatch\.(cgi|fcgi|rb)\z/.match(r.filename) &&
+      if !/\Adispatch\.(cgi|fcgi|rb)\z/.match(File.basename(r.filename)) &&
         File.file?(r.filename)
         return DECLINED
       end
@@ -419,6 +419,19 @@
     return name__.sub(/\AApache::RailsDispatcher::CURRENT_MODULE::/, "")
   end
 
+  def as_load_path
+    if self == Object || self == Kernel ||
+      self == Apache::RailsDispatcher::CURRENT_MODULE
+      ''
+    elsif is_a? Class
+      parent == self ? '' : parent.as_load_path
+    else
+      name.split('::').collect do |word|
+        word.underscore
+      end * '/'
+    end
+  end
+
   def const_missing(class_id)
     env = Apache::RailsDispatcher.current_environment
     unless env
@@ -431,12 +444,18 @@
       file_name = class_id.to_s.demodulize.underscore
       file_path = as_load_path.empty? ? file_name : "#{as_load_path}/#{file_name}"
       require_dependency(file_path)
-      if env.module.const_defined?(class_id)
-        return env.module.const_get(class_id)
+      if const_defined?(class_id)
+        return const_get(class_id)
       else
         raise LoadError
       end
     rescue LoadError => e
+      # Look for a directory in the load path that we ought to load.
+      if $LOAD_PATH.any? { |base| File.directory? "#{base}/#{file_path}" }
+        mod = Module.new
+        env.module.const_set class_id, mod
+        return env.module.const_get(class_id)
+      end
       raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
     end
   end

--=-6aBpZ9p1ryW1VQZPkZ9j--