39 Stimmen

Ruby-Symbol für die Klasse

Gibt es in Ruby eine Möglichkeit, ein Symbol oder eine Zeichenkette in eine gleichnamige Klasse zu verwandeln?

Wenn ich zum Beispiel eine Klasse habe wie

class Bob
  def talk
     puts "Hi, I'm bob"
  end
end

Und eine Methode, die ich irgendwo anders im Code habe, wird ein Symbol :bob übergeben, kann ich das irgendwie in die Klasse Bob verwandeln? Vielleicht so etwas wie

b = :Bob.new
b.talk

Oder gibt es eine Möglichkeit, etwas Ähnliches zu tun?

58voto

August Lilleaas Punkte 52649

Es gibt viele Möglichkeiten, dies zu tun. Da Ihnen der Kontext fehlt, ist es unmöglich, eine "beste" Methode zu wählen. Hier sind ein paar Möglichkeiten.

Kernel.const_get(:Bob)

eval(:Bob.to_s)

Kernel.const_get(:bob.to_s.capitalize)

4 Stimmen

Nun, zum Glück habe ich nicht nach dem "besten" Weg gefragt, sondern nur nach einem Weg... ;)

9 Stimmen

Nur für den Fall, dass Bob ist definiert im Modul People und Sie wissen es, Sie können People.const_get(:Bob)

45voto

Dan Frade Punkte 1001

Schiene

Nur zur Verwendung mit Rails.

Mit einer Schnur:

"Module".constantize #=> Module
"Class".constantize #=> Class

Mit einem Symbol:

:module.to_s.classify.constantize #=> Module
:open_struct.to_s.classify.constantize #=> OpenStruct

Wenn Sie es mit einem Multi-Wort Symbol, dann müssen Sie Folgendes hinzufügen #classify in die Kette einfügen, um die Großschreibung aller Teile der Konstante korrekt zu handhaben.

http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize

8 Stimmen

Sorry, ich sollte wahrscheinlich hinzufügen, dass dies eine Rails nur Sache ist.

1 Stimmen

Wenn Sie Rails verwenden, ist dies wahrscheinlich die beste Lösung.

1 Stimmen

Die Frage bezieht sich speziell auf Symbole und die Konstante existiert nicht in der Klasse Symbol in Rails. Die Antwort sollte lauten :Module.to_s.constantize .

10voto

Lance Olsen Punkte 101

Keine der Lösungen, die ich gesehen habe, funktioniert, wenn Sie :foo_bar in FooBar verwandeln wollen. Wenn es das ist, wonach Sie suchen:

:foo_bar.to_s.split("_").collect(&:capitalize).join.constantize
\=> FooBar

Ich hoffe, das hilft jemandem.

1 Stimmen

Dafür ist 'camelize' da: :foo_bar.to_s.camelize

4 Stimmen

@DaveSims camelize ist eine ActiveRecord-Erweiterung: api.rubyonrails.org/classes/ActiveSupport/ obwohl dies auch für constantize .

0 Stimmen

Ja, wie Dan Frade, das hätte ich erwähnen sollen :)

5voto

sepp2k Punkte 352762

NameSpace.const_get(classname) gibt das Klassenobjekt zurück (vorausgesetzt, classname enthält den Namen einer Klasse - enthält er den Namen einer Konstante, die keine Klasse ist, wird der Wert dieser Konstante zurückgegeben). Der Toplevel-Namensraum ist Object, so dass Sie Folgendes tun können Object.const_get(:Bob).new

2voto

Tim Hoolihan Punkte 12248
class Bob
end

def create(name)
  return eval("#{name}.new")
end

b = create(:Bob)
puts b.class

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X