Dynamically calling a certain set of methods

  • Thread starter Vicente Bosch Campos
  • Start date
V

Vicente Bosch Campos

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
=20
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?
=20
end
=20
def operatorSwitchMutation
end
=20
def numberSwitchMutation
end
=20
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.=20=
 
R

Robert Klemme

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:
=A0 =A0def mutation

=A0 =A0 =A0self.send(self.methods.select!{|element| element.to_s.end_with=
?("Mutation")}.shuffle![0]) =A0 =A0 #I'm using to_s as the symbol object do=
not allow end_with?
=A0 =A0end

=A0 =A0def operatorSwitchMutation
=A0 =A0end

=A0 =A0def numberSwitchMutation
=A0 =A0end

=A0 =A0def unusedNumberMutation
=A0 =A0end


Is self.send(self.methods.select!{|element| element.to_s.end_with?("Mutat=
ion")}.shuffle![0]) the best way to do it ? Is there a more ruby idiom to p=
erform 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)

:)

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
V

Vicente Bosch Campos

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

Many thanks Robert!!


certain type of equations. I need to randomly call a certain method from =
a set:element.to_s.end_with?("Mutation")}.shuffle![0]) #I'm using to_s as =
the symbol object do not allow end_with?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 ?
=20
First of all you can save typing by removing "self.". Then you should
replace #shuffle![0] with #sample:
=20
send(methods.select!{|element| = element.to_s.end_with?("Mutation")}.sample)
=20
If you like you can strip this down even further by using regular
expressions because those happen to work with Symbols as well:
=20
send(methods.grep(/Mutation\z/).sample)
=20
:)
=20
Kind regards
=20
robert
=20
--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
=20
 
S

Simon Kaczor

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
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)

:)

Kind regards

robert
 
V

Vicente Bosch Campos

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.=20

Thanks Simon.

You can save yourself some CPU cycles by pre-compiling the list of
available methods as a class instance variable:
=20
class Mutating
...
@mutations =3D instance_methods.grep(/Mutation$/)
class << self
attr_reader :mutations
end
=20
def mutation
send(self.class.mutations.sample)
end
end
=20
Simon
=20
First of all you can save typing by removing "self.". Then you = should
replace #shuffle![0] with #sample:
=20
send(methods.select!{|element| = element.to_s.end_with?("Mutation")}.sample)
=20
If you like you can strip this down even further by using regular
expressions because those happen to work with Symbols as well:
=20
send(methods.grep(/Mutation\z/).sample)
=20
:)
=20
Kind regards
=20
robert
=20
--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
=20
=20
=20
=20
=20
 
A

Albert Schlef

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

Vicente Bosch Campos

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=20
def xMutation=20
puts "XELLO"
end
end
Foo.class_eval do=20
def yMutation=20
puts "YELLO"
end
end =20
end
end

class Bar < Foo
end

a =3D Foo.new
a.new_create
ap a.methods.grep(/Mutation\z/)
b =3D 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 ?=20

Kind regards,
Vicente
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top