2010-12-26 3 views
3

런타임시 클래스 인스턴스 변수, 데이터 및 attr_reader를 어떻게 추가합니까? 내가 호출 할 수있는이 클래스 지금 그래서클래스 인스턴스 변수와 attr_reader를 런타임에 Ruby 클래스에 추가 하시겠습니까?

class Test 
    additional_data :status, 55 
end 

그 주어진 예를 들어

class Module 
    def additional_data member, data 
    self.class.send(:define_method, member) { 
     p "Added method #{member} to #{name}" 
    } 
    end 
end 

:

p Test.status # => prints 55 

답변

4

방법 ?

class Object 
    def self.additional_data(name, value) 
    ivar_name = "@#{name}" 

    instance_variable_set(ivar_name, value) 

    self.class.send(:define_method, name) do 
     instance_variable_get(ivar_name) 
    end 

    self.class.send(:define_method, "#{name}=") do |new_value| 
     instance_variable_set(ivar_name, new_value) 
    end 
    end 
end 

class Foo 
    additional_data :bar, 'baz' 
end 

puts Foo.bar # => 'baz' 
Foo.bar = 'quux' 
puts Foo.bar # => 'quux' 

매우 자명하지만 궁금한 점이 있으면 알려주세요.

+0

'self.class.send (: define_method, name) ... 대신'왜'self.class.define_method (name) ...'가 아닌가? – user102008

4

Module#class_eval 당신이 원하는 무엇인가 :이 약

def add_status(cls) 
    cls.class_eval do 
    attr_reader :status 
    end 
end 

add_status(Test) 
+0

답변 해 주셔서 감사합니다. 그러나 Test뿐 아니라 모든 클래스에 메서드 상태를 추가 할 수 있기를 원합니다. 내가 뭘 하려는지 질문을 업데이트했다. .. – Zabba

+1

Ruby에서 모든 것이 객체 다.'Test.class_eval ... '할 수 있다면'variable.class_eval ...'할 수있다.'variable'는 클래스 객체. 나는 당신이 원하는 것과 더 잘 맞는 뭔가로 내 대답을 업데이트했습니다. – Theo

+1

... 그리고 원하는 경우 분명히 메소드의 속성 이름을 전달할 수 있습니다. – Theo