ฉันจะสร้างอินสแตนซ์คลาสจากชื่อสตริงในทับทิมได้อย่างไร


121

ฉันมีชื่อของคลาสและฉันต้องการสร้างอินสแตนซ์ของคลาสนั้นเพื่อให้ฉันสามารถวนลูปผ่านแต่ละแอททริบิวต์รางที่มีอยู่ในสคีมาของคลาสนั้น

ฉันจะทำอย่างนั้นได้อย่างไร?

  1. ฉันมีชื่อเป็นสตริงของคลาสที่ฉันต้องการตรวจสอบ
  2. ฉันเดาว่าฉันต้องสร้างอินสแตนซ์ของคลาสเพื่อที่ฉันจะได้
  3. วนดูแอตทริบิวต์และพิมพ์

1
นี่เป็นคำถามที่ดี ขอบคุณที่ถามและช่วยฉันจากการใช้eval
David West

คำตอบ:


219

ในรางคุณสามารถทำได้:

clazz = 'ExampleClass'.constantize

ในทับทิมบริสุทธิ์:

clazz = Object.const_get('ExampleClass')

ด้วยโมดูล:

module Foo
  class Bar
  end
end

คุณจะใช้

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

4
โปรดทราบว่าObject.const_get('Foo::Bar')จะไม่ทำงานในขณะที่constantizeจะ
Marc-André Lafortune

ขอบคุณตื่นมาถามเรื่องนี้เพราะปัญหา Admin :: User :) เอาชนะฉันไปได้เลย
mhenrixon

เฮ้ @Wes นี่เป็นประโยชน์ขอบคุณ! คำถามด่วน - สิ่งนี้จะใช้ได้กับโมดูลที่ซ้อนกันด้วยหรือไม่ ตัวอย่างเช่นclazz = 'Foo::Bar::Uber'
iaacp

@iaacp ใช่มันจะทำงานในระดับที่ซ้อนกันมากที่สุดเท่าที่คุณมี
Wes


6

ลองสิ่งนี้:

Kernel.const_get("MyClass").new

จากนั้นวนซ้ำตัวแปรอินสแตนซ์ของออบเจ็กต์:

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

ขอบคุณเนื่องจากฉันต้องวนซ้ำคอลัมน์ของโมเดลเรก
คอร์ดที่

1
ตรวจสอบ ActiveRecord # attributes () และ / หรือ 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"

ใน Ruby 2.0 และอาจเป็นรุ่นก่อนหน้านี้Object.const_getจะทำการค้นหาเนมสเปซFoo::Barซ้ำ ๆเช่น. ตัวอย่างข้างต้นคือเมื่อ namespace เป็นที่รู้จักกันก่อนเวลาและไฮไลท์ความจริงที่ว่าสามารถเรียกว่าโมดูลโดยตรงเมื่อเทียบกับเฉพาะในconst_getObject


คุณควรเพิ่มคำอธิบายนี้ ณ ตอนนี้มันเป็นเพียงบล็อกของรหัสเท่านั้น
Josh Crozier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.