Hallo,

Mal die Frage, was du damit machen willst beiseite gelassen: Das ganze
geht auch recht elegant ohne eval(String).

Ich versuche mal das gleiche Ergebnis zu erzielen, nur eben so, wie
ich es geschrieben hätte.

  class Foobar
  end
  my_mod = Object.const_set(:Foo, Module.new)

  if defined?(Foo) # returns 'constant'
    my_mod.module_eval do
      define_method :bar do
        puts "static function 'bar' called"
      end
    end

    Foobar.extend(my_mod)
  end

> wie aber parametrisiere ich die zu definierende funktion?
> also im sinne von :define_method, 'bar(*args)' ...

Die Antwort ist verhältnismäßig einfach: Gibt dem Block, den du an
define_method übergibst einfach Parameter, also z.B.

    my_mod.module_eval do
      define_method :bar do |*args|
        puts "static function 'bar' called with '#{args.join(', ')}'"
      end
    end

> comments?

Das eval von Strings hat immer einen faden Beigeschmack, das sich zu
leicht Userinput in diesen Strings wiederfindet. Das kann leicht
eskalieren. Außerdem funktionieren Code-Analyse und
Syntax-Highlighting in solchen Blöcken nicht.

Es gibt aber auch Fälle in denen man nicht drumherum kommt. In 1.8
z.B. können Blöcke keine anderen Blöcke als Parameter annehmen. Damit
könnte man also keine dynamischen Methoden definieren, die Blöcke
erwarten. Hier kommt man um eval(String) oder module_eval(String)
nicht herum.

Auch die Ausführungszeit von den String-eval-definierten Methoden kann
kürzer sein, als die der dynamisch definierten, da sie keinen Scope
mehr mit sich rumschleppen müssen.

Aber das ist ein weites Feld.

Viele Grüße

Gregor
_______________________________________________
rubyonrails-ug mailing list
[email protected]
http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug

Antwort per Email an