티스토리 툴바


블로그 이미지
sunho@

공지사항

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

calendar

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

ActiveRecord self or @ or local ?

2012/01/16 15:58 | Posted by sunho@
Ruby에서의 변수를 그동안 익숙했던 Java나 C#등의 변수와 비교해서 이해하니 정말 헷갈린다.
변수나 키워드가 1:1로 대체되는 관계가 아니라, self는 Java의 static과 비슷하다 같은 설명을 보고나서 프로그램을 보니 이건 뭐 어떻게 이렇게 사용할 수 있는지 아리송하기만 하다.

오늘 이해한 내용을 예제를 통해 되짚어 보자.


이런 코드가 있다.

아이템은 여러장의 사진을 갖고 있고, DB에 저장되기 이전에 처음 사진의 아이디를 대표(represent_image) 로 저장해야 한다.


말로 설명하면 이해하기 힘들지만 코드는 간단하다.
처음에는 이런 코드를 생각했었다.

class Item < ActiveRecord::Base

   has_many :photos

   before_save :set_represent_image


   def set_represent_image

     unless @photos.nil? || @photos.count <1

       @represent_image = @photos.first.id

     end

   end

 end



photos 와 represent_image는 Item의 어트리뷰트니까 @을 붙여 인스턴스 변수를 호출했다.
그런데 제대로 작동되지 않는다. @photo가 계속 nil 로 나온다.
이런 문제가 나오는 이유는 다음과 같다.

실제로 rails에서 사용하는 어트리뷰트들은 변수라고 보면 이해하기가 힘들어진다.
이 어트리뷰트들은 변수라기 보다는 getter, setter를 호출하는 것이기 때문이다.
즉 photos 는 
def photo
  ...
end
를, photos = 는
def photo=(variable)
  ...
end
를 호출하는것과 같다.

내부적으로는 저 메서드 안에서 @photos라는 인스턴스 변수를 쓸지, @_photos라는 인스턴스 변수를 쓸지, 
@foobar라는 인스턴스 변수를 쓸지는 알수도, 알 필요도 없다. (메서드를 통해서만 접근하기 때문)

오호라...
처음 객체를 만드는 예제에 나오는 attr_accessor란 개념을 c#에 서 써봤고 (이건 루비를 흉내낸것)
Java에서 getter/setter와 크게 다르지 않다고 생각해 오 편하겠는데 정도로만 생각해왔다.
하지만 메서드를 꼭 변수 대입하듯이 사용하는것에 익숙치 않아 코드에 나오는 모든 attr_accessor들을
기전의 변수에 개념에서만 바라봤던 것 같다.

그래서 찾아보고, 실험하며 개선한 코드가 다음과 같다.

class Item < ActiveRecord::Base

   has_many :photos

   before_save :set_represent_image


   def set_represent_image

     unless photos.nil? || photos.count <1

       self.represent_image = photos.first.id

     end

   end

 end



이건 잘 동작하는 올바로 된 코드다.
 근데 뭐가 문제냐?
문제는 저기 self 키워드에 있다.
코드에서 보이듯이 photos에는 self키워드가 없다. 하지만 represent_image 앞에는 self키워드를 적어 줬는데, 이 키워드가 없으면 프로그램이 제대로 동작하지 않는다.
왜? 같은 attribute인데? 기본적으로 self 키워드는 생략해도 된다던데?
사실 위의 코드도 좀 석연치 않았던게 photos는 지역변수처럼 사용하지만 실제로는 메서드가 불린다.
여기에 힌트가 있다.

위의 코드를 보면 photos는 값을 호출할때 쓰이고, represent_image는 값을 대입할때 쓰인다.
따라서 photos는 먼저 지역변수로 인식되고, 이 지역변수가 없으므로  photos 메서드를 호출하고,
represent_image의 경우에는 값을 대입하므로 지역변수 선언이라고 여겨지는 것이다.

Java에서는 변수면 변수, 메서드면 메서드로 명확하게 표기하기 때문에 이렇게 변수처럼 쓰는 메서드의 경우가 없어 계속 Java 같은 엄격한 언어만 접해본 나로써는 이해하기가 힘든 부분이었다. 
1. find webdefault.xml (SOLR_INSTALLED_PATH/example/etc)
2. change <locale-encoding-mapping-list> attribute.

  <locale-encoding-mapping><locale>ko</locale><encoding>UTF-8</encoding></locale-encoding-mapping>



3. restart server with locale options.

java -Dfile.encoding=UTF-8 -Duser.language=ko -Duser.country=KR -jar start.jar

Apache Solr Service for Zend Framework

2011/08/14 12:07 | Posted by sunho@
solr-php-client wrapper for Zend Framework.

http://www.supercerebral.com/2011/06/apache-solr-service-for-zend-framework/ 
이전 1 2 3 4 5 ... 7 다음