I have seen examples of catching unkown methods called on a class with
method_missing.
For example:
class Example
def initialize(…)
#…
end
def method_missing(item)
call = item.id2name
process(call)
end
end
But I’m not sure if that is an ‘acceptable’ way to do things. Also,
suppose that I wanted to add a method dynamically that takes arguments,
is this even possible?
My general thought is allowing functionality to be added to a program
dynamically based on a set of rules in a config file.
Any suggestions are welcome.
Thank you.
def method_missing(item, *args, &blk)
process(item, *args, &blk) # item is already a symbol
end
end
But I’m not sure if that is an ‘acceptable’ way to do things. Also,
suppose that I wanted to add a method dynamically that takes arguments,
is this even possible?
My general thought is allowing functionality to be added to a program
dynamically based on a set of rules in a config file.
Any suggestions are welcome.
Thank you.
Also, keep in mind Ruby classes are open. You can add real methods to
them on the fly.
You are right for sure here Marcin, however are you aware that the two
are not exactly the same? In case you get bitten by define_method
maybe Ara’s recent post about instance_eval{ def … } might be
helpful,
the following is a “String-eval-free” way to define a method on a
class without being exposed to the closure of the current
environment.
----------------------- 8< ----------------------
value = 222 ## evil closure variable shadowing A#value
class A
class << self
def value; 1120 end # just to show that Ara’s method works
end
def value; 101010 end # the value we really want
end
A.class_eval %{
def tom; value end
} ## works but we use the threaded String eval
A.class_eval do
define_method :marcin do value end # value is the closure of course
end ## nice, but does not work
class A
class << self
alias_method :old_new, :new
def new *args, &block
o = old_new( *args, &block )
o.instance_eval do
def ara; value end
end
o
end
end
end ## this does the trick, simple concise, trivial well we wish it
were.
and there are issues with the alias it is a potential redefeinition
disaster
a = A.new
p [:tom, a.tom]
p [:marcin, a.marcin]
p [:ara, a.ara]