Dynamically changing class methods

(henrikbrink) #1

Hello!

Im making an application that loads and uses the methods of a class
dynamically. The class can then be altered while the application is
running, and the application loads the file containing the class every
time it is needed.

The strange thing is: It works fine when i add a method to the class.
The new method shows up. But if i remove a method, it acts as if it was
still there. How can that be?

Here's the code used to get the methods:

    load "#{file}.rb"
    myclass = Object.const_get "MyClass"
    myclass_inst = myclass.new
    methods = myclass_inst.methods

If I am not clear enough, please ask.

Regards, Henrik

(Bill Atkins) #2

How are you removing the method?

···

On 8/11/05, henrikbrink <henrikbrink@gmail.com> wrote:

Hello!

Im making an application that loads and uses the methods of a class
dynamically. The class can then be altered while the application is
running, and the application loads the file containing the class every
time it is needed.

The strange thing is: It works fine when i add a method to the class.
The new method shows up. But if i remove a method, it acts as if it was
still there. How can that be?

Here's the code used to get the methods:

    load "#{file}.rb"
    myclass = Object.const_get "MyClass"
    myclass_inst = myclass.new
    methods = myclass_inst.methods

If I am not clear enough, please ask.

Regards, Henrik

--
Bill Atkins

(David A. Black) #3

Hi --

Hello!

Im making an application that loads and uses the methods of a class
dynamically. The class can then be altered while the application is
running, and the application loads the file containing the class every
time it is needed.

The strange thing is: It works fine when i add a method to the class.
The new method shows up. But if i remove a method, it acts as if it was
still there. How can that be?

Here's the code used to get the methods:

   load "#{file}.rb"
   myclass = Object.const_get "MyClass"
   myclass_inst = myclass.new
   methods = myclass_inst.methods

If you do this:

   class MyClass
     def some_method
       # ...
     end
   end

and then, later, do this:

   class MyClass
   end

(i.e., don't define some_method), some_method is still there. The
effects of opening a class multiple times are cumulative. This is the
case whether it's all in one file or in multiple files, or even in the
same file loaded multiple times.

If you want to remove a method, you have to use remove_method or
under_method (which are slightly different from each other; see ri or
other docs).

If I am not clear enough, please ask.

Same here :slight_smile:

David

···

On Fri, 12 Aug 2005, henrikbrink wrote:

--
David A. Black
dblack@wobblini.net

(Ara.T.Howard) #4

because:

   harp:~ > irb
   irb(main):001:0> class Foo;def foo;end;end

   irb(main):002:0> p Foo::instance_methods - Object::instance_methods
   ["foo"]

   irb(main):003:0> class Foo;def bar;end;end

   irb(main):004:0> p Foo::instance_methods - Object::instance_methods
   ["bar", "foo"]

opening up a class, even in a file that's loaded, can only add or modify
methods using 'def'. there is a mechanism to delete methods but it must be
explicit.

for dynamically loading classes try this:

     jib:~ > cat b.rb

       require 'dynaload'
       loaded = Dynaload::dynaload 'a.rb'
       loaded.classes.each do |klass, attributes|
         p [klass, attributes]
         p klass.instance_methods - Object.instance_methods
       end

     jib:~ > cat a.rb

       require 'dynaload'
       class Foo
         def foo
         end
       end
       Dynaload::export Foo, 'some attribute' => 42

     jib:~ > ruby b.rb

       [#<Module:0xb75cded8>::Foo, {"some attribute"=>42}]
       ["foo"]

     jib:~ > cat a.rb

       require 'dynaload'
       class Foo
         def bar
         end
       end
       Dynaload::export Foo, 'some attribute' => 42

     jib:~ > ruby b.rb

       [#<Module:0xb75cbed8>::Foo, {"some attribute"=>42}]
       ["bar"]

http://raa.ruby-lang.org/project/dynaload/
http://www.codeforpeople.com/lib/ruby/dynaload/

hth.

-a

···

On Fri, 12 Aug 2005, henrikbrink wrote:

Hello!

Im making an application that loads and uses the methods of a class
dynamically. The class can then be altered while the application is
running, and the application loads the file containing the class every
time it is needed.

The strange thing is: It works fine when i add a method to the class.
The new method shows up. But if i remove a method, it acts as if it was
still there. How can that be?

Here's the code used to get the methods:

   load "#{file}.rb"
   myclass = Object.const_get "MyClass"
   myclass_inst = myclass.new
   methods = myclass_inst.methods

If I am not clear enough, please ask.

Regards, Henrik

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

(Joel VanderWerf) #5

Aside from the suggestions so far, you might want to take a look at
http://raa.ruby-lang.org/project/script/. Just another approach to
encapsulating the definitions in a loaded script file...

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

(henrikbrink) #6

I can see now why my code didn't work, and i must say... doh!

But I'm glad I asked anyway as Dynaload does the job!

Thank you everyone!