Varun
Varun

Reputation: 4284

Ruby: Defining methods dynamically based on variable values

I want to achieve something like below. Defining method names based on array arguments and Call them.

arr = ['alpha', 'beta', 'gamma']

arr.each { |role|
  # If the method already exists don't define new
  if ! method_exist? "init_#{role}"
    define "init_#{role}"
      p "I am method init_#{role}"
    end
}

init_beta
init_gamma

Edit: If such a method already exists, don't define a new method.

Upvotes: 1

Views: 647

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118271

Do as below :

arr = ['alpha', 'beta', 'gamma']

arr.each do |role|
  # this code is defining all the methods at the top level. Thus call to 
  # `method_defined?` will check if any method named as the string argument 
  # is already defined in the top level already. If not, then define the method.
  unless self.class.private_method_defined?( "init_#{role}" )
    # this will define methods, if not exist as an instance methods on 
    # the top level.
    self.class.send(:define_method, "init_#{role}" ) do
      p "I am method init_#{role}"
    end
  end
end

init_beta # => "I am method init_beta"
init_gamma # => "I am method init_gamma"

Look at the documentation of private_method_defined and define_method.

Note : I have used private_method_defined?, as on top level, all instance method you will be defining ( using def or define_method in the default accessibility level ), become as private instance methods of Object. Now as per your need you can also check protected_method_defined? and public_method_defined? accordingly.

Upvotes: 1

Related Questions