나는 호기심 질문이 있습니다. Ruby 클래스가 있고 클래스 메소드, 클래스 변수 등을 동적으로 추가하면 실행되는 동안 변경된 클래스 정의를 저장할 수 있으므로 다음에 응용 프로그램을 시작할 때 다시 사용할 수 있습니다.동적 루비 클래스 저장
답변
개체를 마샬링하기 만하면됩니다 (다른 사람들이 말한 것처럼). 예제를 보자.
class Extras
attr_accessor :contents
def test
puts "This instance of Extras is OK. Contents is: " + @contents.to_s
end
def add_method(name)
self.class.send :define_method, name.to_sym do
puts "Called " + name.to_s
end
end
end
지금 인스턴스를 생성하는 프로그램을 작성할 수 있습니다
그것에 방법을 추가하고 디스크에 저장 :require 'extras'
fresh = Extras.new
fresh.contents = 314
fresh.test # outputs "This instance of Extras is OK. Contents is: 314"
fresh.add_method(:foo)
fresh.foo # outputs "Called foo"
serial = Marshal.dump(fresh)
file = File.new "dumpedExample", 'w'
file.write serial
그래서 우리는 정상적인 방법을 호출 할 수있는 '시험'이 클래스를 고려 동적 메서드 'foo'. 우리가 디스크에 저장 한 예의 예를로드하는 프로그램 작성하는 경우 어떻게되는지 살펴 봅시다 :
require 'extras'
file = File.new 'dumpedExample', 'r'
serial = file.read
reheated = Marshal.load(serial)
reheated.test # outputs "This instance of Extras is OK. Contents is 314"
reheated.foo # throws a NoMethodError exception
그래서 우리가 볼 수있는 그런 (멤버 변수의 값을 포함) 인스턴스는 동적 방법을 저장하는 동안 아니였다.
디자인 관점에서 보면, 추가 된 모든 코드를 모듈에 넣고 다음에 프로그램을 실행할 때 클래스에 다시로드하는 것이 좋습니다. 우리는 이것을 실제로 알고 싶어하지만 어떻게 사용하고 싶은지에 대한 좋은 예가 필요합니다.
메서드를 다시 만들려면 추가 정보가 필요하면 모듈에서이를 멤버 변수로 저장하게하십시오. 모듈에 included
을 구현하고 클래스에 포함될 때 이러한 멤버 변수를 찾습니다.
즉석에서 수업을 수정하고 싶으시겠습니까? 마샬 모듈을 사용하면 파일에 객체를 저장하고 메모리에서 동적으로 다시 읽을 수 있습니다.
이 작업을 수행 할 내장 방법은 없습니다. 마샬은 방법을 저장할 수 없습니다. 이러한 방법과 변수가 체계적으로 생성되면 클래스에 필요한 데이터를 저장하여 다시 만들 수 있습니다. 예를 들어 이러한 메서드를 정의하는 make_special_method(purpose, value)
메서드가있는 경우 이러한 메서드에 전달해야하는 인수 배열을 만들어 클래스 상태를 다시 구성해야합니다.
정확히 무슨 뜻인지에 따라이 문제를 해결할 수있는 몇 가지 방법이 있습니다.
가장 간단한 경우는이 예에서와 같이 이미 존재하는 클래스에 변수 나 메소드를 추가 한 하나입니다 : 여기
class String
def rot13
return self.tr('a-z', 'n-za-m')
end
end
우리는 String 클래스에 ROT13 방법을 추가했습니다. 이 코드를 실행하자마자 프로그램의 모든 문자열은 # rot13 수 있습니다. 따라서 rot13을 사용할 수있는 문자열이 필요한 코드가 있으면 위 코드가 문제의 코드 앞에 실행되는지 확인해야합니다. rot13 코드를 파일에 넣고 require()하면됩니다. 아주 쉽게!
그러나 어쩌면 당신은 클래스에 클래스 변수를 추가 한, 당신은 같이 그 존재하지만 그 값 단지를 유지하려면 : 이제 당신의 값을 저장하려면
class String
@@number_of_tr_calls_made = 0
# Fix up #tr so that it increments @@number_of_tr_calls_made
end
@ @number_of_tr_calls_made를 사용하면 마샬 라이브러리를 통해 다른 직렬화 가능 루비 값과 동일한 방식으로 변환 할 수 있습니다. 또한 쉽게!
그러나 당신이 당신의 질문을 표현한 방식에 뭔가가 날 수는이 같은 일을하고 있다는 의심 :
greeting = "Hello"
class <<greeting
def rot13
return self.tr('a-z', 'n-za-m')
end
end
encrypted_greeting = greeting.rot13
이것은 우리가 첫 번째 예제에서했던 것과 매우 다르다. 이 코드는 프로그램의 모든 String에 rot13 자체의 힘을 부여했습니다. 이 코드는 '인사'라는 이름으로 참조 된 객체에만 권한을 부여합니다. 내부적으로 Ruby는 String의 익명 Singleton 서브 클래스를 생성하고 rot13 메소드를 추가 한 다음 익명 서브 클래스로 인사 장의 클래스를 변경함으로써이를 수행합니다.
여기서 문제는 Singletons가 Marshal'd 일 수 없다는 것입니다. Marshal.load를 호출하면 기존 Singleton 개체의 복사본을 생성 할 수있는 이유를 알 수 있습니다. 이제 인사말에는 상속 계층 구조에 Singleton이 있으므로 저장 및로드하려면 hose가 필요합니다. 대신 하위 클래스를 만드십시오.
class HighlySecurableString < String
def rot13
return self.tr('a-z', 'n-za-m')
end
end
greeting = HighlySecurableString.new("hello")
나는 asker가 실행 중에 클래스에 추가 된 메소드를 참조한다고 생각한다. 나는. 메타 프로그래밍 된 방법. 나는 오해했을지도 모른다. – toholio
- 1. 동적 루비 데몬 관리
- 2. 루비 블록의 동적 중첩
- 3. 루비 해시 저장
- 4. 이해 루비 클래스
- 5. 루비 클래스 질문
- 6. 루비 클래스 상수
- 7. 루비 추상 클래스 디자인
- 8. 루비 초급 클래스 질문
- 9. 루비 :이 클래스
- 10. 루비 클래스 키
- 11. 루비 클래스 문제
- 12. 루비 클래스 확장
- 13. 루비 클래스 모음
- 14. 루비 클래스 객체를 폐기하시오
- 15. 출력 루비 클래스
- 16. 루비 클래스의 평가는, 동적 데이터
- 17. 루비 동적 메서드 값 전달
- 18. 동적 JPA 쿼리 저장
- 19. json 문서에서 루비 클래스 생성하기
- 20. 루비 클래스 개체 가비지 수집
- 21. 루비 - 클래스/객체/메소드의 관계
- 22. 루비 사용자 정의 클래스 모델
- 23. 루비 클래스 메소드 호출에 대해
- 24. PHP는 동적 클래스 상속
- 25. 동적 클래스 변수
- 26. 셀레늄 : 동적 버튼과 클래스?
- 27. .NET에서의 동적 클래스 초기화
- 28. CoffeeScript의 동적 클래스 생성
- 29. 동적 클래스 이름 (jQuery)
- 30. 동적 클래스 인스턴스화
동적으로 추가되는 메소드에는 효과가 없습니다. – toholio