20

I have the following in the file a.rb:

require foo

and i need to unload foo, to load the foo from b.rb, c.rb and other files.

How i can do?

tapioco123
  • 3,235
  • 10
  • 36
  • 42
  • what is foo, and why do you have classes with the same name doing different things in different files? – Doon Aug 06 '10 at 14:22
  • in a.rb: class Foo ... end I need it because i have to run Foo.bar in each rb file, and i cant edit rb files. – tapioco123 Aug 06 '10 at 14:25
  • is each Foo.bar different? or are they the same Foo? – Doon Aug 06 '10 at 14:49
  • each Foo.bar is a function that does different things, and i need to run them all – tapioco123 Aug 06 '10 at 14:54
  • so you have 1 file, the requires a.rb, b.rb,c.rb. and each of the a.rb, b,rb, c.rb require's 'foo' but a different foo, to do a different thing? Err my head hurts just thinking about it. well if you just keep opening up the Foo class, and replacing bar, does that work, or does each file have to require foo from an external source? – Doon Aug 06 '10 at 15:03
  • No,no no. I have 1 file, that need to run Foo.bar placed inside many rb files. simply. – tapioco123 Aug 06 '10 at 15:06
  • why can't you make something like `class B; def bar;...end; end`, `class C;def bar;...end; end` - so only the method `bar` remains the same and could easily be called without all that unloading magic? – lwe Aug 06 '10 at 15:13
  • I said "i can't edit rb files" – tapioco123 Aug 06 '10 at 15:16
  • you don't have to edit the files, in ruby you can re-open the class, and change/add to it from any file. Once the class is loaded in you can change it dynamically on the fly, that is what @lwe and I are talking about. But I am still at a loss to what exactly you are trying to do with With 1 file calling Foo.bar in other files... – Doon Aug 06 '10 at 15:33
  • as i said below, the method is not overrided, and its called always in the first object that i requie – tapioco123 Aug 06 '10 at 18:15
  • I can't imagine why you would want to do this. – Venkat D. Mar 16 '11 at 21:23

2 Answers2

28
Object.send(:remove_const, :Foo)

assuming your class is named Foo.

lwe
  • 2,625
  • 20
  • 19
  • irb(main):002:0> require 'timeout' => true irb(main):004:0> Object.send(:remove_const, :Timeout) => Timeout irb(main):005:0> require 'timeout' => false – tapioco123 Aug 06 '10 at 14:29
  • mhh, yes, because require checks if it has already loaded that lib, maybe you need to use `load` instead of `require`... why do you need to unload that const anyway? can't you use modules or anything to shield them? PS: you need to append the file extension in `load` – lwe Aug 06 '10 at 15:11
  • but aren't there multiple files, so this shouldn't be a problem at all? so shouldn't some hacky magic like `%w{a b c d}.each { |f| require(f); Foo.bar; Object.send(:remove_const, :Foo) }` work "as expected" in your case - though I don't really recommend it. Just seems strange, having all these .rb files defining the same class + method. – lwe Aug 06 '10 at 15:45
  • ^^ it works, `a.rb`, `b.rb`, `c.rb` and `d.rb` look like: `class Foo; def self.bar; puts __FILE__ end end` and then I have the main loop as described above in a file named `prg.rb`... and the output is, as expected :) => `./a.rb ./b.rb ./c.rb ./d.rb` – lwe Aug 06 '10 at 15:49
  • Sorry but for me after the first cycle defined?(Foo) returns false – tapioco123 Aug 06 '10 at 17:23
  • %w{a b c d}.each { |f| require(f); Foo.bar if defined?(Foo); Object.send(:remove_const, :Foo) } – tapioco123 Aug 06 '10 at 17:24
3

I am not sure about the unloading part, but using load instead of require will always reload the file. However, when you use load you will need to include the .rb so in your case it would be load 'foo.rb' .

See http://www.fromjavatoruby.com/2008/10/require-vs-load.html

Kernel#load docs
Kernel#require docs

gerryster
  • 650
  • 1
  • 6
  • 11
  • 1
    The problem with this, is if you define an instance variable inside of a class, and load the file, and then remove the instance variable, and then load the file again, the instance variable still exists even though you removed it. Reason is because when you define a class twice, the second definition adds onto what already exists, rather than completely redefining it. – Jeff Davenport Jan 28 '17 at 23:57
  • In a production environment that shouldn't be stopped, this would allow access to methods that were intended to be deleted from the class and "reloaded" using load – Jeff Davenport Jan 28 '17 at 23:59