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.

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

···

On Wed, Mar 23, 2011 at 9:32 AM, Vicente Bosch Campos <vbosch@gmail.com> wrote:

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?\(&quot;Mutation&quot;\)\}\.shuffle\!\[0\]\)     \#I&#39;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 ?

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

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

Many thanks Robert!!

···

On Mar 23, 2011, at 10:26 AM, Robert Klemme wrote:

On Wed, Mar 23, 2011 at 9:32 AM, Vicente Bosch Campos <vbosch@gmail.com> wrote:

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 ?

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

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

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)

:slight_smile:

Kind regards

robert

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

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.

···

On Mar 24, 2011, at 8:20 PM, Simon Kaczor wrote:

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)

:slight_smile:

Kind regards

robert

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

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.

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On Mar 25, 2011, at 10:13 AM, Albert Schlef wrote:

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.

--
Posted via http://www.ruby-forum.com/\.