# Calling dynamic method from symbol or string

**URL:** <https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849>\
**Category:** Rails\
**Created:** [February 26, 2007, 2:42pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849 "2007-02-26T14:42:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 2:42pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/1 "2007-02-26T14:42:44Z")

</div>

i have several dynamic methods such as:

def assign!

def close!

being added to my models via a plugin. my question is how might i  
call these methods if the method name is passed as a symbol or string  
parameter to another method?

def do\_something(options = {})  
if options.has\_key?(:event)  
# call the dynamic! method specified by options[:event]  
# would it  
end  
end

so if i do

model.do\_something(:event =\> :assign)

i want assign! method called

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 3:14pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/2 "2007-02-26T15:14:49Z")

</div>

def do\_something(options = {})  
if options.has\_key?(:event)  
send(options[:event])  
end  
end

See ri Object#send

Vish

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 3:30pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/3 "2007-02-26T15:30:51Z")

</div>

i know i need to use object.send

it’s just that i am passing in, say { :event =\> :assign }

where my method is named assign!

i figured out, unless there is an easier way, to do

send “#{options[:event].to\_s + “!”}”.to\_sym

which is ugly in my opinion, so if someone has a prettier way, please  
let me know.

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 3:37pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/4 "2007-02-26T15:37:51Z")

</div>

Okay, didn’t realize that. Try this 🙂

class Symbol  
def +(a)  
(self.to\_s + a.to\_s).to\_sym  
end  
end

and then,

send(options[:event] + :"!")

Vish

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 4:49pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/5 "2007-02-26T16:49:20Z")

</div>

Vishnu G. wrote:

> Okay, didn’t realize that. Try this 🙂
> 
> class Symbol  
> def +(a)  
> (self.to\_s + a.to\_s).to\_sym  
> end  
> end
> 
> and then,
> 
> send(options[:event] + :"!")
> 
> Vish

This is way more complicated then it needs to be. You don’t need to  
hack the Symbol class at all. all you need is:

send “#{options[:event]}!”

If a string is entirely dynamic you don’t need quotes. So this:

“#{ foo.bar + ‘123’ }”

is the same as:

foo.bar + ‘123’

Use the dynamic string for what its good for, combining static parts  
with changing parts:

“#{foo.bar}123”

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 5:50pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/6 "2007-02-26T17:50:23Z")

</div>

yeah, much cleaner

send “#{options[:event]}!”

for some reason, i thought send had to take a symbol

now, my other problem is this…

the method i am sending to accepts a block. how can i pass the block  
off to send?

i currently using this way, method i am sending gets called, but the  
block isn’t so i figure i am missing something

def do\_something(options =\> { :event =\> nil, :by =\> nil })

# validate options

…  
send("#{options[:event}!") do  
# expecting this to get passed to the method in send  
audit(options[:by])  
end  
end

# dynamic method

def assign!  
…  
yield(self) if block\_given?  
end

def audit(user)  
…  
end

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 26, 2007, 8:21pm UTC](https://www.ruby-forum.com/t/calling-dynamic-method-from-symbol-or-string/86849/7 "2007-02-26T20:21:49Z")

</div>

nm, figured it out

def do\_something(options =\> { :to =\> nil, :by =\> nil, :event =\> nil,  
:audit =\> true })  
…  
event\_params = …  
prc = options[:audit] ? Proc.new { |o| o.audit(options[:by] } : nil  
send("#{options[:event]}!", event\_params, &prc)  
end

def audit(user)  
…  
end

def some\_event!(additional\_params)  
…  
yield(self) if block\_given?  
end
