Wie konvertiere ich einen String in eine Konstante in Ruby?

68

Wie konvertiere ich den String "User"in User?

Marshluca
quelle
Versuchen Sie eine variable Funktion aufzurufen?
Wersimmon
1
Ich möchte auch eine Antwort auf diese Frage; Versuchen Sie jedoch, eine neue Konstante basierend auf einer Zeichenfolge zu erstellen, ODER suchen Sie eine bereits initialisierte Konstante? Suchen Sie auch Vanille Rubin oder auch Rails?
Onebree

Antworten:

100
Object.const_get("User")

ActiveSupport ist nicht erforderlich.

Damien
quelle
Anwendungsbeispiel: class User; def self.lookup; const_get('SomeClassName);end; end User.lookupGibt die Klasse selbst zurück.
Artur Beljajev
61

Sie können die Module#const_getMethode verwenden. Beispiel:

irb(main):001:0> ARGV
=> []
irb(main):002:0> Kernel.const_get "ARGV"
=> []
Chris Jester-Young
quelle
32

Wenn Sie ActiveSupport geladen haben (z. B. in Rails), können Sie verwenden

"User".constantize
Severin
quelle
28

Die empfohlene Methode ist die Verwendung der ActiveSupport-Konstante:

'User'.constantize

Sie können auch Kernel verwenden const_get, aber in Ruby <2.0 werden keine Konstanten mit Namespace unterstützt, also ungefähr so:

Kernel.const_get('Foobar::User')

wird in Ruby <2.0 fehlschlagen. Wenn Sie also eine generische Lösung wünschen, sollten Sie den ActiveSupport-Ansatz verwenden:

def my_constantize(class_name)
  unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ class_name
    raise NameError, "#{class_name.inspect} is not a valid constant name!"
  end

  Object.module_eval("::#{$1}", __FILE__, __LINE__)
end
Psyho
quelle
1
Seit Ruby 2.0 EOL erreicht hat, muss ActiveSupport nicht mehr als Abhängigkeit abgerufen werden, um auf eine Konstante mit einer Zeichenfolge zu verweisen. :-)
Drenmi
Siehe auch'User'.safe_constantize
Eric Walker
Von wem empfohlen?
Adam Grant
-5

Verwenden Rubin magische Methode: eval():

eval("User")  #=>  User
dddd1919
quelle
6
Dies ist wahrscheinlich ein völliger Overkill, da er evalnicht so verwendet werden soll, und spezifischere Alternativen sollten vollständig vermieden werden.
Yagooar