How to declare a method dynamically using method_missing?

I have a ruby ​​program, and I want to accept a method created by the user and make a new method from this name. I tried this:

def method_missing(meth,*args,&block) name = meth.to_s class << self define_method(name) do puts "hello " + name end end end 

And I get the following error:

 `define_method': interning empty string (ArgumentError) in 'method_missing' 

Any ideas? Thank you

Edit:

It works differently for me, but I'm still curious how to do it. Here is my code:

 def method_missing(meth,*args,&block) Adder.class_eval do define_method(meth) do puts "hello " + meth end end send("#{meth}") end 
+4
source share
2 answers

The variable name not available in the class definition area ( class << self ). This does not throw a NameError because you have overridden method_missing .

To do what you are trying to do, you need to save the area with name . To do this, you need to use only block-based methods (e.g. class_eval ) instead of directly opening the class, so something like this:

 def method_missing(meth,*args,&block) name = meth.to_s eigenclass = class << self; self; end eigenclass.class_eval do define_method(name) do puts "hello " + name end end end 

But in fact, the symbol in meth is quite sufficient - you don’t need a name at all. (Although you will still need the above method anyway.) Also, you want to execute this method immediately. The easiest way is to simply send a message:

 def method_missing(meth,*args,&block) eigenclass = class << self; self; end eigenclass.class_eval do define_method(meth) do puts "hello #{meth}" end end send(meth, *args, &block) end 
+11
source

The problem is that class << self does not act as a closure, which means that the variable name will not be available inside the definiton method.

On the other hand, when you use class_eval , you pass a block ( Proc ), which is a closure, which means that all local variables from the current binding will be accessible inside the body of the block.

+1
source

Source: https://habr.com/ru/post/1380513/


All Articles