이름이 주어진 인스턴스 변수의 값을 가져옵니다.


99

일반적으로 문자열에 이름이있는 객체에 대한 참조를 얻으려면 어떻게해야합니까?

보다 구체적으로, 매개 변수 이름 목록이 있습니다 (멤버 변수-동적으로 빌드되어 직접 참조 할 수 없음).

각 매개 변수는 from_s메소드 도있는 객체입니다 .

다음과 같은 작업을하고 싶습니다 (물론 작동하지 않습니다 ...).

define_method(:from_s) do | arg |
    @ordered_parameter_names.each do | param |
        instance_eval "field_ref = @#{param}"
        field_ref.from_s(param)
    end
end

답변:


179

이를 달성하는 가장 관용적 인 방법은 다음과 같습니다.

some_object.instance_variable_get("@#{name}")

+또는 사용할 필요가 없습니다 intern. 루비는 이것을 잘 처리 할 것입니다. 그러나 다른 개체에 도달하여 해당 ivar를 빼 내면 캡슐화가 손상되었을 가능성이 상당히 높습니다.

ivar에 명시 적으로 액세스하려는 경우 올바른 방법은 액세스 자로 만드는 것입니다. 다음을 고려하세요:

class Computer
  def new(cpus)
    @cpus = cpus
  end
end

이 경우 Computer.new를 사용 instance_variable_get하면 을 사용 하여 @cpus. 하지만 만약 당신이 이것을하고 있다면, 당신은 아마도 @cpus공개를 의미 할 것입니다 . 당신이해야 할 일은 :

class Computer
  attr_reader :cpus
end

이제 할 수 있습니다 Computer.new(4).cpus.

참고 당신은 다시 할 수 있는 기존의 클래스를하고 판독기에 개인 바르합니다. 접근자는 방법 일 뿐이므로 다음을 수행 할 수 있습니다.Computer.new(4).send(var_that_evaluates_to_cpus)


instance_variable_get ( "@ # {name}")은 변수의 값을 반환하지 않습니까? 실제 개체에 대한 참조가 필요합니다. 나는 결국 다시 쓰기를 끝냈 기 때문에 많은 변수 + 내가 원하는 순서대로 이름을 가진 배열 대신 매개 변수 자체를 배열에 넣었습니다 (디자인 결정은 배열을 검색하여 매번 변수에 액세스할지 또는 필요할 때만 사용되는 이름이있는 추가 어레이)
LK__

아니요 : instance_variable_get ( "@ # {name}")은 실제 개체를 반환합니다.
Yehuda Katz

약간의 명확성을 위해 죽은 스레드를 밝혀냅니다. 완전한 예는 다음과 같습니다. class Computer attr_read : cpus def new (cpus) @cpus = cpus end end?
Nicolas de Fontenay 2013 년

"그러나 다른 개체에 접근하여 ivar를 빼 내면 캡슐화가 깨졌을 가능성이 상당히 높습니다." 다른 객체의 ivar에 어떻게 침입합니까?
RubyMiner

9

인스턴스 변수 이름에서 인스턴스 변수를 얻으려면 다음을 수행하십시오.

name = "paramName"
instance_variable_get(("@" + name).intern)

이것은 인스턴스 변수의 값을 반환합니다 @paramName


클래스를 동적으로 생성하는 동안 인스턴스 변수 이름 배열이 있습니다 (특정 순서로 처리해야하므로이 목록이 필요합니다). 이 이름을 사용하여 변수에 대한 참조를 얻고 싶습니다.
LK__

1
문자열 "paramName"이 있고 @paramName에 대한 참조가 필요합니다
LK__

1
확인. 이 두 가지 의견을 정확히 말하도록 질문을 편집하는 것이 좋습니다.
Daniel Lucraft

2
또한 이것은 역 직렬화와 관련이 없습니다. 더 나은 제목은 "이름이 주어진 인스턴스 변수의 값 가져 오기"또는 기타 일 수 있습니다.
Daniel Lucraft

항상 모듈을 수행하고 추가 :attr_reader varname할 수 있으므로 더 깔끔하고 덜 장황한 방식으로 변수에 액세스 할 수 있습니다.
ocodo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.