Dynamic methods

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.

···

--
Posted via http://www.ruby-forum.com/.

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

  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.

  class Example
  end

  foo = "bar"

  Example.class_eval %{
    def #{foo}
      "#{foo}"
    end
  }

  Example.new.foo #=> "bar"

T.

···

On Aug 23, 6:46 pm, -j B- <jrb...@drexel.edu> wrote:

Trans wrote:

Also, keep in mind Ruby classes are open. You can add real methods to
them on the fly.

  class Example
  end

  foo = "bar"

  Example.class_eval %{
    def #{foo}
      "#{foo}"
    end
  }

It's better not to use string evals:

Example.class_eval do
     define_method foo do
         "#{foo}"
     end
end

lopex

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 :frowning:

A.class_eval do
  define_method :marcin do value end # value is the closure of course :frowning:
end ## nice, but does not work :frowning:

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 :frowning: 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]

Cheers
Robert

···

On 8/24/07, Marcin Mielżyński <lopx@gazeta.pl> wrote:

Trans wrote:

> Also, keep in mind Ruby classes are open. You can add real methods to
> them on the fly.
>
> class Example
> end
>
> foo = "bar"
>
> Example.class_eval %{
> def #{foo}
> "#{foo}"
> end
> }
>

It's better not to use string evals:

Example.class_eval do
     define_method foo do
         "#{foo}"
     end
end

lopex

--
I'm an atheist and that's it. I believe there's nothing we can know
except that we should be kind to each other and do what we can for
other people.
-- Katharine Hepburn

the above really su..., sorry

class A
  alias_method :old_init, :initialize
  def initialize *args, &blk
    old_init( *args, &blk )
    instance_eval do
        def ara; value end
    end
  end
end
# the issues remain though, we could apply the method redefintion
hammer Pit and Ara came up with and just redefine initialize like
that, but that would make it about 100 lines I guess :frowning:

Robert

···

On 8/24/07, Robert Dober <robert.dober@gmail.com> wrote:

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 :frowning: well we wish it were.
## and there are issues with the alias it is a potential redefeinition disaster

--
I'm an atheist and that's it. I believe there's nothing we can know
except that we should be kind to each other and do what we can for
other people.
-- Katharine Hepburn