Hi, I’ve been sifting through module_eval, instance_eval, define_method,
and the like and I can’t seem to accomplish what I am trying to do,
which is something like this:
class Foo
def initialize
list_of_method_names =
get_list_of_method_names_from_some_external_function
for method_name in list_of_method_names_do
create_method(method_name)
end
end
def create_method(method_name)
# some magic here as yet unknown
end
end
The list retrieval is in initialize() because the list is constantly
changing so I always want the most recent one when I initialize my
class.
What I want create_method() to do (simplified here) is, given the
argument “baz”, add a method to the current instance of Foo that would
look like this if it were a traditional method (that is, not dynamically
created):
def baz(*args)
args[0]
end
That seems pretty simple but I have run into all sorts of problems with
various ways of doing it. Rather than recount all those ways and why
they didn’t work, I instead present the minimal example of the problem I
am trying to solve and hope that someone can solve it.
Thanks in advance.
Dan
Dan T. wrote:
That seems pretty simple but I have run into all sorts of problems with
various ways of doing it. Rather than recount all those ways and why
they didn’t work, I instead present the minimal example of the problem I
am trying to solve and hope that someone can solve it.
Rather than try to sort out a way to create methods on the fly, perhaps
it
would be better if you were to explain what you are trying to do …
what
problem does this approach solve?
There are any number of ways to produce results for given input data,
and
creating new methods for a class at runtime is not necessarily the most
efficient way to accomplish your goal.
What I am saying is you are now struggling to solve, not the original
problem your program is meant to solve, but the problems created by your
solution.
One possible alternative is a hash with keys consisting of identifying
labels, and values consisting of lambdas that can produce various kinds
of
results. The lambdas could easily stand in for your custom methods, and
this approach might end up being easier to implement.
Example:
#!/usr/bin/ruby -w
hash = {
“+” => lambda { |x,y| x + y },
“-” => lambda { |x,y| x - y },
“*” => lambda { |x,y| x * y },
“/” => lambda { |x,y| x / y },
}
puts hash["/"].call(1.0,3.0)
Output:
0.333333333333333
Depending on what you are trying to do, this might be easier to use and
might be faster as well, especially if you take your development time
into
account.
On Dec 11, 2006, at 2:28 PM, Dan T. wrote:
What I want create_method() to do (simplified here) is, given the
argument “baz”, add a method to the current instance of Foo that would
look like this if it were a traditional method (that is, not
dynamically
created):
def baz(*args)
args[0]
end
class Dynamic
def initialize(name)
create_method(name)
end
private
def create_method(name)
class << self; self end.send(:define_method, name) { |*args|
args.first }
end
end
=> nil
foo = Dynamic.new(:foo)=> #Dynamic:0x71dbd4
bar = Dynamic.new(:bar)
=> #Dynamic:0x71b3fc
foo.foo(“Hi”)
=> “Hi”
foo.bar(“Hi”)
NoMethodError: undefined method `bar’ for #Dynamic:0x71dbd4
from (irb):33
bar.bar(“Hi”)
=> “Hi”
Hope that helps.
James Edward G. II