Ruby instance methods from string and block

Is it possible to define an instance method in ruby โ€‹โ€‹from a string (method name) and a block (method contents)?

I suppose this will need to use instance_eval (), but I haven't figured out how to mix the two data types yet. Both the string and the block are dynamically determined, so it will work to create a block with "def # {string}" at the beginning - I do not know how to do this.

My use case is a class representing the Bacula configuration file. A configuration file can have many different types of resources. They are all stored in a relatively complex data structure behind the scenes (for other reasons, simplifying this structure will not lead to what I'm looking for). I would like resources to be quickly accessible using named methods.

For example, A represents one configuration file, B represents another. A has resources Director, Client, Work and B have Messages and Director.

In this case, A must have director (), client (), and job () methods, while B has messages () and director (). Each of them will return the corresponding resource from the corresponding configuration file.

I know that there are simpler ways to do this (for example, implement the [] method), but at the moment I am pursuing a more difficult solution for the sake of curiosity.

+3
source share
1 answer

I think you are looking for a method define_methodfor a module; however, it is closed, so you need to use class_evalor something else to start it.

body = proc { self * 3 }
name = "triple"
c = Numeric

c.class_eval { define_method(name.to_sym, &body) }

3.triple # 9

And a method with arguments:

body = proc { |second| [self * 3, second * 3] }
name = "triple_both"
c = Numeric

c.class_eval { define_method(name.to_sym, &body) }

puts 3.triple_both(5) # [9, 15]

( Eigenclass ):

body = proc { puts @meme + @meme + @meme }
name = "meme"
class SwedishChef; def initialize; @meme = "bork"; end; end    
sc = SwedishChef.new
(class << sc; self; end).class_eval { 
  define_method(name.to_sym, &body)
}
sc.meme # borkborkbork

[EDIT (Jรถrg W Mittag): .]

+4

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


All Articles