Calling dynamic method from symbol or string


#1

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


#2

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

See ri Object#send

Vish


#3

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.


#4

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] + :"!")

Vish


#5

Vishnu G. wrote:

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] + :"!")

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”


#6

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


#7

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