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

3

37
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.

Mangum answered 15/8, 2010 at 12:47 Comment(0)
F
80

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
Fireproof answered 15/8, 2010 at 13:53 Comment(5)
Great answer. Could you share links to ruby's documentation on class methods meta-programming? thanksAndromeda
@mattgathu: There are no class methods in Ruby. There is only one kind of methods: instance methods.Grindle
I'm trying to implement a singleton method that takes parameters. How do I do it?Andromeda
@mattgathu: There is no such thing as a singleton method in Ruby. A singleton method is just a normal instance method defined in a singleton class. You define a singleton method with parameters in exactly the same way as you define an instance method with parameters, because there are only instance methods. Singleton methods and class methods are nothing special, because they don't exist.Grindle
Great explanation! I would upvote multiple times if I could XDSteffin
A
1

you can do it simply this way

class << C
  define_method(:a_class_method) do
     # do something
  end
end
Alimentation answered 12/12, 2016 at 21:50 Comment(0)
P
0
C.instance_eval do
  def class_method
    "This is class method"
  end
end

instance_eval: defines singleton methods on the object (which results in class methods when it's called on class object).

class_eval: defines regular instance methods

Pneumo answered 5/5, 2019 at 22:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.