Bagaimana cara membuat instance kelas dari nama string di ruby?


121

Saya memiliki nama kelas dan saya ingin membuat turunan dari kelas itu sehingga saya dapat mengulang melalui setiap atribut rails yang ada dalam skema kelas itu.

Bagaimana saya akan melakukan itu?

  1. Saya memiliki nama sebagai string kelas yang ingin saya periksa
  2. Saya rasa saya perlu membuat instance kelas agar saya bisa
  3. Ulangi atributnya dan cetaklah.

1
Ini pertanyaan yang bagus. Terima kasih telah menanyakannya dan menyelamatkan saya dari penggunaaneval
David West

Jawaban:


219

Di rel, Anda bisa melakukan:

clazz = 'ExampleClass'.constantize

Dalam ruby ​​murni:

clazz = Object.const_get('ExampleClass')

dengan modul:

module Foo
  class Bar
  end
end

Anda akan menggunakan

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

4
Perhatikan bahwa Object.const_get('Foo::Bar')tidak akan berhasil, sementara constantizeakan.
Marc-André Lafortune

Terima kasih, bangun untuk bertanya tentang itu karena masalah Admin :: Pengguna :) Pukul saya untuk itu.
mhenrixon

Hai @Wes, ini sangat membantu, terima kasih! Pertanyaan singkat - apakah ini juga akan berfungsi untuk modul bersarang? Misalnya,clazz = 'Foo::Bar::Uber'
iaacp

@iaacp Ya, ini akan bekerja untuk sebanyak mungkin level yang Anda miliki.
Wes


6

Coba ini:

Kernel.const_get("MyClass").new

Kemudian untuk mengulang melalui variabel instance objek:

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

Terima kasih, karena saya benar-benar harus mengulang melalui kolom model rekaman aktif, ini tidak akan berfungsi untuk saya, tetapi akan berguna dalam aplikasi ruby ​​"murni" saya :)
mhenrixon

1
Lihat ActiveRecord # atribut () dan / atau ActiveRecord # attribute_names ().
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"

Di ruby ​​2.0 dan, mungkin rilis sebelumnya, Object.const_getakan secara rekursif melakukan pencarian di namespace seperti Foo::Bar. Contoh di atas adalah ketika namespace diketahui sebelumnya dan menyoroti fakta yang const_getdapat dipanggil pada modul secara langsung dan bukan secara eksklusif Object.


Anda harus menambahkan penjelasan untuk ini. Sampai sekarang, itu hanya satu blok kode.
Josh Crozier
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.