Dynamically calling a certain set of methods

Hi,

I am doing an implementation of a genetic algorithm to resolve a certain
type of equations. I need to randomly call a certain method from a set:

def mutation

  self.send(self.methods.select!{|element| 

element.to_s.end_with?(“Mutation”)}.shuffle![0]) #I’m using to_s as
the symbol object do not allow end_with?

end

def operatorSwitchMutation
end

def numberSwitchMutation
end

def unusedNumberMutation
end

Is self.send(self.methods.select!{|element|
element.to_s.end_with?(“Mutation”)}.shuffle![0]) the best way to do it ?
Is there a more ruby idiom to perform the safe thing ?

Best,
V.

On Wed, Mar 23, 2011 at 9:32 AM, Vicente B. Campos [email protected]
wrote:

def operatorSwitchMutation
end

def numberSwitchMutation
end

def unusedNumberMutation
end

Is self.send(self.methods.select!{|element|
element.to_s.end_with?(“Mutation”)}.shuffle![0]) the best way to do it ? Is there
a more ruby idiom to perform the safe thing ?

First of all you can save typing by removing “self.”. Then you should
replace #shuffle![0] with #sample:

send(methods.select!{|element|
element.to_s.end_with?(“Mutation”)}.sample)

If you like you can strip this down even further by using regular
expressions because those happen to work with Symbols as well:

send(methods.grep(/Mutation\z/).sample)

:slight_smile:

Kind regards

robert

Great,much better and concise… (I need to improve on my regexp)

Many thanks Robert!!

You can save yourself some CPU cycles by pre-compiling the list of
available methods as a class instance variable:

class Mutating

@mutations = instance_methods.grep(/Mutation$/)
class << self
attr_reader :mutations
end

def mutation
send(self.class.mutations.sample)
end
end

Simon

I am actually modifying the mutation methods and creating more on the
fly … loving metaprogramming capabilities in Ruby to code genetic
algorithms: hence I think its best to not precompile.

In any case a great idea if I do something a bit less random.

Thanks Simon.

Simon Kaczor wrote in post #989060:

class Mutating

@mutations = instance_methods.grep(/Mutation$/)
class << self
attr_reader :mutations
end

But if his actual class if derived from Mutating, your code won’t work
because the derived class won’t see the parent’s @mutations. Correct me
if I’m wrong.

If I add the method with instance_eval you are correct, but it works if
we add them to the class definition with class_eval (hence they get
inherited).

#! /usr/bin/env ruby

require ‘ap’

class Foo
def new_create
instance_eval do
def xMutation
puts “XELLO”
end
end
Foo.class_eval do
def yMutation
puts “YELLO”
end
end
end
end

class Bar < Foo
end

a = Foo.new
a.new_create
ap a.methods.grep(/Mutation\z/)
b = Bar.new
ap b.methods.grep(/Mutation\z/)
a.xMutation
a.yMutation
b.yMutation
#b.xMutation <- Fails
ap Foo.methods.grep(/Mutation\z/) #We have not added any class methods,
which is what we wanted

In any case I want to do something more dynamic than this and not force
the new definitions to the class definition. I am sort of like having a
“Library of Congress” singleton class where the new methods created on
the fly and the scores obtained with them are stored. Hence when the new
objects get created they go into the library and apply to themselves the
methods that worked well for past generations ( with a random factor
because we want innovation). Its a bit like genetics but with historical
memory ?

Kind regards,
Vicente