Как получить объект класса из строки "A :: B :: C" в Ruby? - PullRequest
9 голосов
/ 23 июля 2010

Сбой следующего примера

class A
  class B
  end
end
p Object.const_get 'A' # => A
p Object.const_get 'A::B' # => NameError: wrong constant name A::B

UPDATE

Вопросы по теме задавались ранее:

  1. Приведение между строкой и именем класса
  2. Ruby String # to_class
  3. Получить класс по имени в Ruby?

Последний дает хорошее решение , которое можно развить в

class String
  def to_class
    self.split('::').inject(Object) do |mod, class_name|
      mod.const_get(class_name)
    end
  end
end

class A
  class B
  end
end
p "A::B".to_class # => A::B

Ответы [ 4 ]

7 голосов
/ 23 июля 2010

Вам придется вручную "проанализировать" двоеточия самостоятельно и вызвать const_get в родительском модуле / классе:

ruby-1.9.1-p378 > class A
ruby-1.9.1-p378 ?>  class B
ruby-1.9.1-p378 ?>    end
ruby-1.9.1-p378 ?>  end
 => nil 
ruby-1.9.1-p378 > A.const_get 'B'
 => A::B 

Кто-то написал qualified_const_get, чтоможет представлять интерес.

6 голосов
/ 23 июля 2010

Вот метод Rails 'constantize:

def constantize(camel_cased_word)
  names = camel_cased_word.split('::')
  names.shift if names.empty? || names.first.empty?

  constant = Object
  names.each do |name|
    constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
  end
  constant
end

Видите, он начинается с Object поверх всего этого, а затем использует каждое имя между двойными точками с запятой в качестве ступеньки кдоберитесь до нужной вам константы.

0 голосов
/ 01 июня 2012

Вы можете сделать это и с eval, который работает в некоторых случаях, когда const_get не работает. Здесь есть хорошая статья: http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc

0 голосов
/ 23 июля 2010

Extlib предоставляет метод full_const_get, который делает именно это.

http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67

Вы можете включить extlib или скопировать эту реализацию и использовать ее самостоятельно (при условии, что лицензирование совместимо с тем, для чего вы его используете)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...