Как делают я получаю объект класса от строки “A:: B:: C” в Ruby?

Следующие сбои в качестве примера

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

ОБНОВЛЕНИЕ

Вопросы о теме, которую спрашивают ранее:

  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

9
задан Community 23 May 2017 в 10:31
поделиться

3 ответа

Вам придется вручную «проанализировать» двоеточия и вызвать 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 

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

7
ответ дан 4 December 2019 в 15:11
поделиться

Вот метод 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 поверх всего этого, затем использует каждое имя в между двумя точками с запятой в качестве ступеньки для перехода к нужной константе.

6
ответ дан 4 December 2019 в 15:11
поделиться

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

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

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

0
ответ дан 4 December 2019 в 15:11
поделиться