Rails 3: how to load files in /lib?

Mori picture Mori · Jul 5, 2010 · Viewed 13.9k times · Source

I'm new to rails and making some sort of noob mistake: I frequently need to count the number of lines in a file, so I'm trying to monkey patch class File like this:

class File
  def self.line_count( filename ) 
    %x{wc -l #{filename}}.split.first.to_i  
  end
end

I saved this to /lib/file_util.rb. I thought that this was supposed to be auto-required, so that I could just use it, but that doesn't work:

$ rails console
>> File.line_count('Gemfile')
NoMethodError: undefined method `line_count' for File:Class
...

So I try to require it manually, no joy:

>> require '<myproj>/lib/file_util.rb' # same result with require 'file_util.rb'
=>nil

But it works if I require it within IRB:

$ irb
>> require '<myproj>/lib/file_util.rb'
=> true
>> File.line_count('Gemfile')
=> 22

I also tried to to add the require to config/application.rb:

...
Bundler.require(:default, Rails.env) if defined?(Bundler)

require 'file_util.rb'

module <myproj>
...

and I get:

$ rails console
<myproj>/config/application.rb:9:in `require': no such file to load -- file_util.rb (LoadError)

What am I doing wrong?

Answer

Mori picture Mori · Jul 5, 2010

Ok, I seem to have mostly figured it out. Rails doesn't automatically require everything under /lib. It only auto loads when you try to use a new class name that matches a file name in lib. So if I define line_count in class FileUtil instead of File it automatically finds and loads 'file_util.rb'. But patching File and naming the patch file 'file.rb' doesn't work, since the File class is already defined, so Rails doesn't go looking for a definition.

My other problem was that I was trying to do the require too soon in the startup sequence, before Rails had a chance to enhance require to look in its directories. When I added "require 'file_util'" to config/environments/development.rb it works fine.

But this doesn't explain why I can't manually require the file from within rails console.