2015-01-25 2 views
2

초기화 된 Ruby 객체에 대해 메소드를 동적으로 정의하려고합니다. MyObject 해시를 기반으로합니다. initialize 메소드로 전달합니다.Ruby - obj의 고유 클래스와 로컬 변수를 공유합니다.

my_hash.each do |key| 
    class << self 
    define_method(key.underscore.to_sym) do 
     my_hash[key] 
    end 
    end 
end 

이것은 undefined local variable or method 'key' for #<Class:#<MyObject:0x007fc7abw0cra0>> 실패 다음 initialize 방법의 몸에서 나는 다음 있습니다. 어떤 아이디어?

my_hash은 camelized 키가 많은 json 응답으로 만들어 졌으므로 원하는 값을 얻기 위해 간단한 루비 메서드를 사용하는 것이 더 편리합니다.

+1

해시를 OpenStruct로 변환하면 각 키에 대한 메서드가 만들어집니다. – emaillenin

+0

하지만 MyObject 개체에서 사용할 수있는 메서드를 만들지 못합니까? 내가 어떻게 든 method_missing을 재정 의하여 OpenStruct 객체에 호출을 전달하지 않는다면 말입니다. –

답변

4

로컬 변수들이 정의되는 범위에 국부적. (가) (어휘) 루비 스코프되는 스크립트 범위 모듈/클래스 정의의 범위에있어서 정의 된 범위 및 범위를 차단. 블록 스코프는 외부 스코프 (주변 스코프를 가깝게 닫음)에 중첩됩니다.

my_hash.each_key do |key| 
    singleton_class.class_eval do 
    define_method(key.to_sym) do 
     my_hash[key] 
    end 
    end 
end 

또는 더 나은 아직 :

my_hash.each_key do |key| 
    define_singleton_method(key.underscore.to_sym) do 
    my_hash[key] 
    end 
end 

참고 : 나는 또한 (버그, 당신은 each_key와 키를 반복하지 each해야한다 고정입니다 그래서, 당신은 블록을 사용해야합니다 each_pair의 별칭).

+0

Brilliant. Jörg에게 감사드립니다. –

+0

멋진 답변, Jörg. –

2

class << self 대신 define_singleton_method을 사용할 수 있습니다. 또한 Hash#each은 키와 값이있는 두 요소 배열을 생성합니다.

my_hash.each do |key, val| 
    define_singleton_method(key.underscore.to_sym) do 
    val 
    end 
end 
+0

네, 정확히 내가 필요한 것. –

+0

첫 번째 문장을 설명하기 위해 편집하는 경우 나는 업 보턴을 사용합니다. –

관련 문제