o_o_o--
o_o_o--

Reputation: 1025

How do I call a method, given its name, on an element of an array?

How do I call a method, given its name, on an element of an array?

For example, I could have:

thing = "each"

I want to be able to do something like:

def do_thing(thing)
  array = [object1,object2]
  array[0].thing
end

so that do_thing(to_s), for example, would run object1.to_s.

Upvotes: 0

Views: 72

Answers (3)

toro2k
toro2k

Reputation: 19230

You can use public_send or send. public_send only sends to public methods while send can see public and private methods.

def do_thing(thing)
  array = [1,2,3]
  array.public_send(thing)
end

do_thing('first')
# => 1

do_thing(:last)
# => 3

Update A more general version:

def do_thing(array, index, method, *args)
  array[index].public_send(method, *args)
end

do_thing([1, 2, 3], 0, :to_s)
# => "1"

do_thing([[1,2], [3, 4]], 0, :fetch, 0)
# => 1

require 'ostruct'
o = OpenStruct.new(attribute: 'foo')
do_thing([o], 0, :attribute=, 'bar')
o.attribute == 'bar'
# => true

Upvotes: 3

Arup Rakshit
Arup Rakshit

Reputation: 118261

Here is an example to help you out although I don't have any idea what objects are residing inside your array:

arr = [Array.new(2,10),"abc" ]
arr.each{|i| p i.send(:length)}
#>>2
#>>3

Upvotes: 0

Anand Shah
Anand Shah

Reputation: 14913

Object#send

thing = "each"
def do_thing(thing)
  array = [1,2,3]
  array.send(thing)
end

From the doc:

class Klass
  def hello(*args)
    "Hello " + args.join(' ')
  end
end
k = Klass.new
k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"

Upvotes: 0

Related Questions