calling dynamic method from symbol or string

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

def do_something(options = {}) if options.has_key?(:event)    send(options[:event]) end end

See ri Object#send


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.

Okay, didn't realize that. Try this :slight_smile:

class Symbol   def +(a)     (self.to_s + a.to_s).to_sym   end end

and then,

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


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

nm, figured it out

def do_something(options => { :to => nil, :by => nil, :event => nil, :audit => true })   ...   event_params = ...   prc = options[:audit] ? { |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