클래스가 정의되었는지 어떻게 확인합니까?
문자열을 클래스 이름으로 바꾸는 방법은 해당 클래스가 이미있는 경우에만 가능합니까?
Amber가 이미 클래스 인 경우 다음을 통해 문자열에서 클래스로 이동할 수 있습니다.
Object.const_get("Amber")
또는 (Rails에서)
"Amber".constantize
그러나 NameError: uninitialized constant Amber
Amber가 아직 클래스가 아닌 경우 이들 중 하나가 실패 합니다.
내 첫 번째 생각은 defined?
방법 을 사용하는 것이지만 이미 존재하는 클래스와 그렇지 않은 클래스를 구별하지 않습니다.
>> defined?("Object".constantize)
=> "method"
>> defined?("AClassNameThatCouldNotPossiblyExist".constantize)
=> "method"
그렇다면 변환을 시도하기 전에 문자열이 클래스 이름을 지정하는지 어떻게 테스트합니까? (좋아요, NameError 오류를 잡는 begin
/ rescue
블록은 어떻습니까? 너무 못 생겼나요? 동의합니다 ...)
어때요 const_defined?
?
Rails에서는 개발 모드에서 자동 로딩이 있으므로 테스트 할 때 까다로울 수 있습니다.
>> Object.const_defined?('Account')
=> false
>> Account
=> Account(id: integer, username: string, google_api_key: string, created_at: datetime, updated_at: datetime, is_active: boolean, randomize_search_results: boolean, contact_url: string, hide_featured_results: boolean, paginate_search_results: boolean)
>> Object.const_defined?('Account')
=> true
레일에서는 정말 쉽습니다.
amber = "Amber".constantize rescue nil
if amber # nil result in false
# your code here
end
위의 @ctcherry의 응답에서 영감을 얻은 여기 class_name
에 문자열이있는 '안전한 클래스 메서드 전송' 이 있습니다. 경우 class_name
클래스의 이름이없는, 그것은 nil을 반환합니다.
def class_send(class_name, method, *args)
Object.const_defined?(class_name) ? Object.const_get(class_name).send(method, *args) : nil
end
응답하는 method
경우에만 호출하는 더 안전한 버전 class_name
:
def class_send(class_name, method, *args)
return nil unless Object.const_defined?(class_name)
c = Object.const_get(class_name)
c.respond_to?(method) ? c.send(method, *args) : nil
end
이 Object.const_defined?
방법을 사용한 모든 답변 에는 결함이있는 것으로 보입니다 . 지연로드로 인해 해당 클래스가 아직로드되지 않은 경우 어설 션이 실패합니다. 이것을 확실하게 달성하는 유일한 방법은 다음과 같습니다.
validate :adapter_exists
def adapter_exists
# cannot use const_defined because of lazy loading it seems
Object.const_get("Irs::#{adapter_name}")
rescue NameError => e
errors.add(:adapter_name, 'does not have an IrsAdapter')
end
문자열이 유효한 클래스 이름 (또는 쉼표로 구분 된 유효한 클래스 이름 목록)인지 테스트하기 위해 유효성 검사기를 만들었습니다.
class ClassValidator < ActiveModel::EachValidator
def validate_each(record,attribute,value)
unless value.split(',').map { |s| s.strip.constantize.is_a?(Class) rescue false }.all?
record.errors.add attribute, 'must be a valid Ruby class name (comma-separated list allowed)'
end
end
end
수업을 받고 싶은 경우를 대비 한 또 다른 접근 방식입니다. 클래스가 정의되지 않은 경우 nil을 반환하므로 예외를 포착 할 필요가 없습니다.
class String
def to_class(class_name)
begin
class_name = class_name.classify (optional bonus feature if using Rails)
Object.const_get(class_name)
rescue
# swallow as we want to return nil
end
end
end
> 'Article'.to_class
class Article
> 'NoSuchThing'.to_class
nil
# use it to check if defined
> puts 'Hello yes this is class' if 'Article'.to_class
Hello yes this is class
참고URL : https://stackoverflow.com/questions/5758464/how-do-i-check-if-a-class-is-defined
'Programing' 카테고리의 다른 글
jQuery로 JSON 트리를 검색하는 방법 (0) | 2020.11.04 |
---|---|
자바 : org.w3c.dom.Document의 모든 요소를 반복하는 가장 효율적인 방법? (0) | 2020.11.04 |
Sublime Text 2가 시작될 때 마지막으로 열린 파일 / 프로젝트를 열지 못하게하는 방법 (0) | 2020.11.04 |
특정 속성 만있는 태그를 찾는 방법-BeautifulSoup (0) | 2020.11.04 |
Linux에 pyodbc를 설치할 수 없습니다. (0) | 2020.11.03 |