Como crio uma instância de classe a partir de um nome de string em ruby?


121

Eu tenho o nome de uma classe e quero criar uma instância dessa classe para que eu possa percorrer cada atributo do rails que está presente no esquema dessa classe.

Como eu faria isso?

  1. Eu tenho o nome como uma sequência da classe que quero verificar
  2. Eu acho que preciso instanciar uma instância de classe para que eu possa
  3. Passe pelos atributos e imprima-os.

1
Esta é uma grande pergunta. Obrigado por perguntar isso e me salvar de usareval
David West

Respostas:


219

Nos trilhos, você pode apenas fazer:

clazz = 'ExampleClass'.constantize

Em rubi puro:

clazz = Object.const_get('ExampleClass')

com módulos:

module Foo
  class Bar
  end
end

você usaria

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

4
Note que Object.const_get('Foo::Bar')não vai funcionar, enquanto constantizevai.
Marc-André Lafortune

Obrigado, acordei para perguntar sobre isso por causa de um problema do Admin :: User :) Entre em contato comigo.
Mhenrixon

Hey @Wes, isso foi útil, obrigado! Pergunta rápida - isso funcionaria também para módulos aninhados? Por exemplo,clazz = 'Foo::Bar::Uber'
iaacp 16/03/2015

@iaacp Sim, funcionará para tantos níveis aninhados quanto você.
Wes


6

Tente o seguinte:

Kernel.const_get("MyClass").new

Em seguida, faça um loop pelas variáveis ​​de instância de um objeto:

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

Obrigado, desde que eu realmente tem que percorrer as colunas do modelo de registro ativo isto não vai funcionar para mim, mas será útil nas minhas "puros" apps rubi :)
mhenrixon

1
Confira ActiveRecord # attribute () e / ou 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"

Em Ruby 2.0 e, lançamentos possivelmente mais cedo, Object.const_getvai recursiva executar uma pesquisa em um namespaces como Foo::Bar. O exemplo acima é quando o espaço para nome é conhecido antecipadamente e destaca o fato de que const_getpode ser chamado diretamente nos módulos, e não exclusivamente Object.


Você deve adicionar uma explicação para isso. A partir de agora, é apenas um bloco de código.
precisa
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.