How to dynamically define a class method which will refer to a local variable outside?

16,624

Solution 1

Class methods don't really exist in Ruby, they are just singleton methods of the class object. Singleton methods don't really exist, either, they are just ordinary instance methods of the object's singleton class.

Since you already know how to define instance methods (using Module#define_method), you already know everything you need to know. You just need to call class_eval on C's singleton class instead of C itself:

(class << C; self end).class_eval do
  define_method(:a_class_method) do
    puts var 
  end
end

Current versions of Ruby have a singleton_class method to make that easier:

C.singleton_class.class_eval do
  define_method(:a_class_method) do
    puts var 
  end
end

But actually, current versions of Ruby also have Module#define_singleton_method, so, in this particular case, that is unnecessary:

C.define_singleton_method(:a_class_method) do
  puts var 
end

Solution 2

you can do it simply this way

class << C
  define_method(:a_class_method) do
     # do something
  end
end
Share:
16,624
Croplio
Author by

Croplio

Updated on July 18, 2022

Comments

  • Croplio
    Croplio almost 2 years
    class C
    end
    
    var = "I am a local var outside"
    
    C.class_eval do
       def self.a_class_method
         puts var 
       end
    end
    

    I know, this is not correct, because the def created a new scope. I also know that use define_method can create a instance method without creating a new scope, but my point is how to define a class method.