2013-11-05 2 views
2

새로운 클래스를 동적으로 정의 할 수 있도록 Ruby 코드를 설정하려고합니다. 내 코드는 지금 아래에 나와있는 것처럼 작동하지만 작동하지 않는다고 생각합니다. 왜 그런지 혼란 스럽습니다.루비 메타 프로그래밍 - 프로세스를 통해 동적으로 새로운 클래스 정의하기

def define_new_class(&block) 
    new_class = Class.new(MyClass) do 
    yield 
    end 
end 

define_new_class do 
    attr_accessor :my_accessor_1 

    def initialize 
    puts "Hello" 
    end 
end 

어떤 통찰력이라도 대단히 감사하겠습니다!

답변

3

당신은 가까웠지만 몇 가지 일들이있었습니다. 먼저 Class.new의 인수는 새 클래스의 수퍼 클래스를 정의하지만 MyClass은 정의되지 않았습니다. 그러므로 instance_eval

def define_new_class(&block) 
    new_class = Class.new do 
    self.instance_eval &block 
    end 
end 

a = define_new_class do 
    attr_accessor :my_accessor_1 

    def initialize 
    puts "Hello" 
    end 
end 

내 생각 엔 당신이 처음에 MyClass 있었다 이유가 있다는 것입니다 것을 - 두 번째로 당신은 실제로 당신이 정의하는 대신 그냥 블록에 항복하는 클래스의 컨텍스트 내에서 블록을 평가할

def define_new_class(name, &block) 
    new_class = Class.new do 
    self.instance_eval &block 
    end 
    Object.const_set(name, new_class) 
end 

define_new_class('MyClass') do 
    attr_accessor :my_accessor_1 

    def initialize 
    puts "Hello" 
    end 
end 

a = MyClass.new #=> #<MyClass:0x007f8baaaf72c8> 
a.my_accessor_1 = 1 #=> 1 
a.my_accessor_1 # => 1 
: 당신은 그것이 사실 인 경우에, 당신이 그렇게 하나의 큰 행복 방법에

Object.const_set('MyClass', a) 

같은 일을 할 수있는 결과 클래스 MyClass로하는 참조가되고 싶어요

+0

방금 ​​MyClass를 자리 표시 자로 사용하고있었습니다. 다른 곳에서는 정의되어 있습니다. 코드의 다른 부분에 상수를 설정합니다. 나는 당신의'instance_eval' 솔루션을 시도 할 것입니다! – Bryce

+0

Alex, 나는'Module # const_set'이 사용될 수있는 곳에서 궁금해했습니다. 이것은 그 점에서 도움이되었습니다. 하나의 작은 점 : 나는'instance_eval'을'self '로 시작해야한다고 생각하지 않는다. 나는 그것이 필요하지 않은 곳에서는 종종 '자아'라는 말을 추가했습니다. 그것은 어느 정도는 문체의 취향입니까? –

+0

내 부분에서 확실히 문체 선택. 블록이 어떤 컨텍스트에서 평가되고 있는지를 명확히 밝히고 싶었습니다. 나는 당신이 주로 'self'를 속성 정의 자로 제한해야한다는 의견을 들었지만, 나는 그것을 자주 던지는 경향이있다. –

관련 문제