1

I'm testing out a basic Rails app and I seem to be getting some undesirable caching behavior on a library script that's being require()'ed into my controller script.

Suppose FooController.rb contains the following:

require 'utils' # a library script

class FooController
  def some_action
    @some_member = do_something() # global method defined in utils.rb
  end
end

It appears that changes to utils.rb do not take effect until I restart the Rails server. I don't believe this is due to a misconfiguration of Rails' class caching, since a) I am running in a "development" environment, and b) I can make changes directly to the controller code (e.g., to the some_action method above) that are reflected upon the next execution of the script. I've been testing this with some calls to puts that spam messages into the console.

Is there some behavior in either Ruby or Rails that would cause require()-ed scripts to remain cached? If so, is there a way to configure that behavior?

coreyward
  • 77,547
  • 20
  • 137
  • 166
Jeff Lee
  • 1,306
  • 2
  • 14
  • 20
  • This looks like a near-duplicate of http://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request and a number of other very similar questions. That one is about an engine, but both are about automatially reloading files in `/lib`. – Emily Aug 08 '11 at 21:14

2 Answers2

1

If you want to require each time the code is encountered, you really want load.

http://www.ruby-doc.org/core/Kernel.html#method-i-load

Dennis
  • 56,821
  • 26
  • 143
  • 139
coreyward
  • 77,547
  • 20
  • 137
  • 166
  • Interesting and useful, but I'm not sure if I want that either, since the library script might be referenced multiple times across the scripts involved in the current process. What I want is for the current process to respect the latest version of the referenced file. Surely that's a basic tenet of working with non-compiled languages? – Jeff Lee Aug 08 '11 at 21:16
1

Rails class reloader is relatively naive. I believe it's only intended to reload things like controllers and models, leaving anything you might be require'ing into your project alone. So, if you have some custom code in the lib directory or elsewhere that you have changed it is expected behavior for you to have to restart the Rails server.

Carl Zulauf
  • 39,378
  • 2
  • 34
  • 47
  • What happens in a production environment when you need to make a single-line change to a particular script, and class caching is enabled? Would it be necessary to restart the server for the change to take effect, or is there someway to hot-swap it? – Jeff Lee Aug 08 '11 at 21:37
  • Since Ruby is dynamic you can replace a method or class on the fly, but it's also very simple to restart the app. Usually the Rack server has a way of reloading the application without a full restart (such as touching a tmp/restart.txt file), but it does reload everything (not just a single file). – coreyward Aug 08 '11 at 21:48
  • There is also the gem active-reload, https://github.com/paneq/active_reload. I haven't used it and am not sure if it will be helpful in this scenario. – rubish Aug 08 '11 at 21:56
  • Thanks, @RubishGupta...if it's not helpful in this scenario, then it at least answers some follow-up concerns I had about Rails not respecting script modification timestamps at all. It's honestly pretty surprising to me that something like Active Reload isn't built into Rails to begin with. – Jeff Lee Aug 08 '11 at 22:05