2012-04-05 2 views
0

주어진 몇 가지 방법에 응답하는 객체가 있습니다. 나는 그들 중 일부를 해시에서 수집하고 싶다. 나는 항상 이런 식으로 쓴다.해시 값을 채우기위한 더 좋은 방법

class Person 
    # ... 

    def some_selected_attributes 
    attrs = {} 
    [:first_name, :last_name, :zip].each do |attr| 
     attrs[attr] = self.__send__(attr) 
    end 
    attrs 
    end 
end 

나는 이것을 수행하는보다 우아한 방법이있다.

: wq! Hash[]를 사용하여, 또 다른 옵션을

def some_selected_attributes 
    [:first_name, :last_name, :zip].inject({}) do |hash, attr| 
    hash[attr] = __send__ attr 
    hash 
    end 
end 

:

def some_selected_attributes 
    { 
    first_name: first_name, 
    last_name: last_name, 
    zip: zip 
    } 
end 

또한 inject으로 작업을 수행 할 수 있습니다 세 개의 속성이있을 때, 내가 직접 작성하지 않는 이유가 없습니다 참조

답변

1

해시가 실제로 필요한 경우 LBg는 너에게 좋은 패턴이있어. 그러나 기본 해시 대신 작은 구조체 객체를 만드는 것이 좋습니다. 구조체는 인덱싱 및 열거를위한 해시처럼 작동하지만 액세스 메소드가있어 보내기 및 점 표기법과 함께 사용할 수 있습니다.

class Person 
    # ... 
    SomeSelectedPersonAttrs = Struct.new :first_name, :last_name, :zip 

    def some_selected_attributes 
    SomeSelectedPersonAttrs[ * SomeSelectedPersonAttrs.members.map{|a| send a } ] 
    end 

end 

pa = person.some_selected_attributes 
pa.first_name # => "Joe" 
pa[:first_name] # => "Joe" 
pa['first_name'] # => "Joe" 
p.zip = 12345 # sets zip to 12345 
p[:zip] = 12345 
p['zip'] = 12345 

pa.values  # => ["Joe","Blow",12345] 
pa.each_pair {|k,v| ... } 
2

:

def some_selected_attributes 
    Hash[[:first_name, :last_name, :zip].map {|attr| [attr, __send__ attr] }] 
end 
+0

나는 주사를 언급하고 싶었다. 그러나 그것이 무엇을하는지 알았을지라도, 나는 항상 그것을 읽는 것이 까다로울 것입니다. 그래서 저는 종종'h = {};를 사용합니다. ...; 가독성을 위해 h를 반환합니다. – Deradon

+0

감사합니다! 첫 번째 [DRY] (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)는 충분하지 않습니다. '주사하다 '는 올바른 방향으로 가고 있지만 읽기가 어렵다. 다른 아이디어? – iblue

+0

마지막 편집을 참조하십시오. –

-1

나는 당신이하려는 것을 달성하는 더 좋은 방법이 있다고 생각합니다. 이미 클래스에있는 인수의 해시를 반환하는 메서드를 작성하는 것은별로 의미가 없습니다.

class Person 
    attr_accessor :first_name, :last_name, :zip 

end 

은 그럼 당신은() 메소드 some_selected_attributes 필요하지 않습니다 : 당신은 인스턴스 변수 또는 메소드를 사용하여 접근 attr_accessor를 만들 수 있습니다. 당신은 단지 직접 변수 또는 메소드에 액세스 할 수 있습니다 :

p = Person.new 
p.first_name # => value of first_name 

당신이 해시를 원한다면, 당신은 단지 그것을 만들 수 있습니다

p = Person.new 
hash = {:first_name => p.first_name, :last_name => p.last_name, :zip => p.zip } 

이 해시를 구축 싶어 이유를 잘 모르겠어요 어느 한 쪽. 그것은 전체적인 객체를 인수로 전달하여 수행하려는 작업을 수행하는 "객체 지향적 인"방법 인 것 같습니다.

선택한 필드의 해시 작업 대신 전체 개체로 작업하는 것이 좋습니다.

관련 문제