문제

다음을하고 싶습니다.

사전에 반복되는 클래스의 인스턴스 변수를 선언하고 싶습니다.

내가이 해시가 있다고 가정 해 봅시다

hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}

그리고 각 키를 클래스의 인스턴스 변수로 갖고 싶습니다. 해시에 반복되는 변수를 선언 할 수 있는지 알고 싶습니다. 이 같은:

class MyClass
  def initialize()
    hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    hash.each do |k,v|
      @k = v
    end
  end
end

나는 이것이 효과가 없다는 것을 안다! 나는 당신이 내가 원하는 것을 더 명확하게 이해할 수 있는지 확인하기 위해이 코드를 넣었습니다.

감사!

도움이 되었습니까?

해결책

class MyClass
  def initialize()
    hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    hash.each do |k,v|
      instance_variable_set("@#{k}",v)
      # if you want accessors:
      eigenclass = class<<self; self; end
      eigenclass.class_eval do
        attr_accessor k
      end
    end
  end
end

Eigenclass는 단일 객체에 속하는 특수 클래스이므로 정의 된 메소드는 해당 객체의 인스턴스 메소드가 있지만 객체의 일반 클래스의 다른 인스턴스에는 속하지 않습니다.

다른 팁

class MyClass
  def initialize
    # define a hash and then
    hash.each do |k,v|
      # attr_accessor k # optional
      instance_variable_set(:"@#{k}", v)
    end
  end
end

척의 대답은 마지막 두 번의 시도보다 낫습니다. 고유 성분은 아닙니다 self.class 내가 생각했던 것처럼; 내가 이것을 깨닫기 위해 쓴 것보다 더 나은 시험이 필요했습니다.

이전 코드를 사용하여 다음과 같은 방식으로 테스트했으며 수업이 실제로 조작되었으며 인스턴스가 아니라는 것을 알았습니다.

a = MyClass.new :my_attr => 3
b = MyClass.new :my_other_attr => 4

puts "Common methods between a & b:"
c = (a.public_methods | b.public_methods).select { |v| a.respond_to?(v) && b.respond_to?(v) && !Object.respond_to?(v) }
c.each { |v| puts "    #{v}" }

출력은 다음과 같습니다.

Common methods between a & b:
    my_other_attr=
    my_attr
    my_attr=
    my_other_attr

이것은 내 전제를 분명히 반증합니다. 내 사과 척, 너 ~이었다 바로 모두.

구형 답변 :

attr_accessor 인스턴스의 초기화가 아니라 클래스 정의에서 평가 될 때만 작동합니다. 따라서 원하는 것을 직접 수행하는 유일한 방법은 사용하는 것입니다. instance_eval 문자열로 :

class MyClass
  def initialize(params)
    #hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    params.each do |k,v|
      instance_variable_set("@#{k}", v)
      instance_eval %{
        def #{k}
          instance_variable_get("@#{k}")
        end
        def #{k}= (new_val)
          instance_variable_set("@#{k}", new_val)
        end
      }
    end
  end
end

이 시도를 테스트하려면 :

c = MyClass.new :my_var => 1
puts c.my_var

http://facets.rubyforge.org/apidoc/api/more/classes/openstructable.html

OpenSStructable은 모든 클래스 또는 객체에 옵션 구조 동작을 제공 할 수있는 Mixin 모듈입니다. OpenStructable은 임의의 속성을 가진 데이터 객체를 확장 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top