Wie erstelle ich eine Klasseninstanz aus einem Stringnamen in Ruby?


121

Ich habe den Namen einer Klasse und möchte eine Instanz dieser Klasse erstellen, damit ich jedes Rails-Attribut durchlaufen kann, das im Schema dieser Klasse vorhanden ist.

Wie würde ich das machen?

  1. Ich habe den Namen als Zeichenfolge der Klasse, die ich überprüfen möchte
  2. Ich denke, ich muss eine Klasseninstanz instanziieren, damit ich kann
  3. Durchlaufen Sie die Attribute und drucken Sie sie aus.

1
Das ist eine gute Frage. Danke, dass du es gefragt und mich vor der Verwendung bewahrt hasteval
David West

Antworten:


219

In Schienen können Sie einfach tun:

clazz = 'ExampleClass'.constantize

In reinem Rubin:

clazz = Object.const_get('ExampleClass')

mit Modulen:

module Foo
  class Bar
  end
end

du würdest verwenden

> clazz = 'Foo::Bar'.split('::').inject(Object) {|o,c| o.const_get c}
  => Foo::Bar 
> clazz.new
  => #<Foo::Bar:0x0000010110a4f8> 

4
Beachten Sie, dass dies Object.const_get('Foo::Bar')nicht funktioniert constantize.
Marc-André Lafortune

Danke, bin aufgewacht, um wegen eines Admin :: User-Problems danach zu fragen :) Schlage mich dazu.
Mhenrixon

Hey @Wes, das war hilfreich, danke! Kurze Frage - würde dies auch für verschachtelte Module funktionieren? Zum Beispielclazz = 'Foo::Bar::Uber'
iaacp

@iaacp Ja, es funktioniert für so viele verschachtelte Ebenen wie Sie.
Wes


6

Versuche dies:

Kernel.const_get("MyClass").new

So durchlaufen Sie die Instanzvariablen eines Objekts:

obj.instance_variables.each do |v|
  # do something
end

Vielen Dank, da ich wirklich die Spalten des aktiven Datensatzmodells durchlaufen muss, funktioniert dies nicht für mich, aber es wird in meinen "reinen" Ruby-Apps nützlich sein :)
Mhenrixon

1
Überprüfen Sie die ActiveRecord # -Attribute () und / oder ActiveRecord # -Attributnamen ().
Mbreining


5
module One
  module Two
    class Three
      def say_hi
        puts "say hi"
      end
    end
  end
end

one = Object.const_get "One"

puts one.class # => Module

three = One::Two.const_get "Three"

puts three.class # => Class

three.new.say_hi # => "say hi"

In Ruby 2.0 und möglicherweise früheren Versionen Object.const_getwird rekursiv eine Suche in Namespaces wie durchgeführt Foo::Bar. Das obige Beispiel ist, wenn der Namespace im Voraus bekannt ist und die Tatsache hervorhebt, dass const_getModule direkt und nicht ausschließlich aufgerufen werden können Object.


Sie sollten eine Erklärung hinzufügen. Ab sofort ist es nur ein Codeblock.
Josh Crozier
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.