웹 얼굴 분석 ~~

2007.07.05 23:23


웹얼굴분석 사이트

이런저런 사진 올려보고 테스트해본 결과 나름 정확한걸 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ
사용자 삽입 이미지

사용자 삽입 이미지

신고
오픈마루에서 진행된 첫번째 데브데이에 대한 내용입니다. 다른 후기들은 여기에서 보실 수 있습니다.
같이 루비 튜토리얼 세션을 진행하신 deepblue 님의 후기는 여기에서 보실 수 있습니다.

아래는 루비 튜토리얼 세션에서 진행된 내용 입니다.
튜토리얼1 - [멘토:강문식, 유지만] Ruby반 - 세미나룸#4

- 최종참가자: 10명 - 날개, 김성안, 브루펜시럽, 우주, 트위니, Celeste, Dano, iron, Raven, 이두원


참고자료

링크

문서

소스


셈플 어플리케이션 만들기 (with ActiveResource)

목표 :

ActiveRecord 를 사용하지 않고 ActiveRecord 의 REST 버젼이라고 할 수 있는 ActiveResource 만을 사용해서 스프링노트의 페이지를 다룰 수 있는 게시판을 만들어 본다.


step1 어플리케이션 생성

  1. > rails snote
  2. > cd snote
  3.  

step2 EdgeRails

  1. > svn co http://svn.rubyonrails.org/rails/trunk vendor/rails

Edge Rails 란 레일스 최신 개발소스를 의미함.

(참고) vendor/rails 디렉토리에 최신의 레일스 소스를 내려받으면 Edge 로 개발하는 환경이 갖추어 진다.

  1. vendor/rails/railties/lib/initializer.rb 에 아래와 같은 메소드가 존재.

  2. def framework_root_path

  3.   defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails"

  4. end

step3 오픈마루 인증센타를 통해서 인증하기

인증키 받기 : 도움말 참조


step3.1 레일스 환경설정 수정

config/springnote.yml 파일 생성후 아래와 같은 정보 추가.

  1. springnote:

  2.   open_id: 자신의오픈아이디

  3.   user_key: 인증센타를통해받은유저키

  4.   app_key: 인증센타를통해받은어플리케이션키

step4 Scaffold 를 이용해서 모델, 컨트롤러, 뷰 생성

  1. > script/generate scaffold page title:string source:text

step5 ActiveRecord 를 사용하지 않도록 설정 / 패치

step5.1 config/environment.rb 파일 수정

ActiveRecord 를 사용하지 않도록 설정

  1. config.frameworks -= [ :active_record ]

필수 세션 정의 필요

  1. config.action_controller.session = {
           :session_key => "_board_session",
           :secret => "some secret phrase"
    }

스프링노트 API 인증에 필요한 설정 파일 내용 로딩 (springnote.yml)

  1. CONFIG = YAML::load_file("#{RAILS_ROOT}/config/springnote.yml")

(참고 : 개발환경에서 상세하게 에러메시지를 남기도록 설정) : config/environmants/development.rb 파일내용중 아래와 같이 수정

  1. config.whiny_nils = false # 원래는 true

step6 Monkey Patch

lib/initializer.rb 작성

  1. module Rails
      class Initializer
       # Thanks to http://dev.rubyonrails.org/ticket/6795
       def load_observers
         return unless configuration.frameworks.include?(:active_record)
         ActiveRecord::Base.instantiate_observers
       end
      end
    end

config/environment.rb 파일에 monkey_patch 한 라이브러리 파일 로딩하도록 수정

  1. require 'lib/initializer.rb'

step7 컨트롤러 수정 (app/controller/pages_controller.rb)

  1. class PagesController < ApplicationController
      before_filter :update_site

  2. ......

  3.   private
  4.   def update_site
  5.     user_id = CGI.escape(CONFIG['springnote']['open_id'])
  6.     password = [ CONFIG['springnote']['user_key'], CONFIG['springnote']['app_key'] ].join(".")
  7.     Page.site = "http://#{user_id}:#{password}@api.springnote.com/"
  8.   end

step8 모델 수정 (app/model/page.rb)

  1. class Page < ActiveResource::Base
      set_primary_key 'identifier'

      def to_param
       identifier.to_s
      end
    end

step9 뷰 수정 (app/views/pages/show.html.erb)

  1. <p>
  2.   <b>Title:</b>
  3.   <%=h @page.title %>
  4. </p>
  5. <p>
  6.   <b>Source:</b>
  7.   <%=h @page.source %>
  8. </p>
  9. <p>
  10. <%=@page.source %>
  11. </p>
  12. <%= link_to 'Edit', edit_page_path(@page) %> |
  13. <%= link_to 'Back', pages_path %>

step10 업데이트 오류 해결

app/conteollers/page_controller.rb 에서 update 부분을 수정하면 됨.
     # ActiveResource 에는 update_attributes 가 구현이 안되어있다. 때문에 아래와 같이 수정하고 명시적으로 save 를 호출해주면 됨.

  1.   def update

  2.     @page = Page.find(params[:id])

  3.     respond_to do |format|

  4.       params[:page][:identifier] = params[:id]

  5.       if @page.attributes = params[:page]

  6.         @page.save

  7.         flash[:notice] = 'Page was successfully updated.'

  8.         format.html { redirect_to(@page) }

  9.         format.xml  { head :ok }

  10.       else

  11.         format.html { render :action => "edit" }

  12.         format.xml  { render :xml => @page.errors, :status => :unprocessable_entity }

  13.       end

  14.     end

  15.   end


기타 : 레일스 콘솔 사용 관련

개발환경 레일스 콘솔 실행 : script/console


콘솔상에서 아래와 같이 한줄씩 입력해보고 나오는 결과를 참고해보자.


  1. >> app.class
    >> app.get "/pages/페이지번호"
    >> app.get "/pages"
    >> app.response.body
    >> app.cookies
    >> helper.text_field_tag :foo
  2. >> app.methods.grep(/_path$/).sort
  3. >> _    (마지막 아웃풋을 보여줌)
  4. >> y _

기타2 : 엑티브리소스 참고

오류코드

200 - 399:: Valid response, no exception
404:: ActiveResource::ResourceNotFound
409:: ActiveResource::ResourceConflict
422:: ActiveResource::ResourceInvalid (rescued by save as validation errors)
401 - 499:: ActiveResource::ClientError
500 - 599:: ActiveResource::ServerError

Table 1.1: HTTP Verbs and REST-URLs
HTTP Verb REST-URL Action URL without REST
GET /projects/1 show GET /projects/show/1
DELETE /projects/1 destroy GET /projects/destroy/1
PUT /projects/1 update POST /projects/update/1
POST /projects create POST /projects/create

Table 1.2: Standard Path methods
Path Method HTTP Verb Path Requested Action
projects_path GET /projects index
projects_path(1) GET /projects/1 show
new_project_path GET /projects/new new
edit_project_path GET /projects/1;edit edit
projects_path POST /projects create
projects_path(1) PUT /projects/1 update
projects_path(1) DELETE /projects/1 destroy
REST Routing

config/routes.rb :

  1. map.resources :projects

map.resources :projects

Route Generated Helper
projects projects_url, projects_path
project project_url(id), project_path(id)
new_project new_project_url, new_project_path
edit_project edit_project_url(id), edit_

이 글은 스프링노트에서 작성되었습니다.


신고

루비세미나3회후기

2007.06.19 23:35

6월 16일날 세번째 루비 커뮤니티 세미나가 있었다. (잘정리된 deepblue 님의 블로그) 어랏? 그러고 보니 동생 생일날이네.

이번 세미나의 여파로 미투에 친구도 여럿 생겼다 ^^;;  언제나 커뮤니티를 위해 열심히 하는 deepblue 님이 아니었으면, 이번 5개월 만의 모임이 열리기도 힘들었을 것 같고, 오프라인 모임이 자취를 감추었을 수도 있었는데 어쨌든 다행이다.

워낙 급 제안이 되어서 사람들이 많이 올까 했었는데, 다행이도 많은 분들이 오셨다. 그날 가장 먼저 코디안님이 오셨는데, 역시나 바쁘신 분 답게 앉자마자 노트북을 꺼내놓으시고 마구 뭔가를 작성하신다... (이것이 그날 발표자료 였나? ^^). 부산에서 올라오신 분도 있었는데, 이 대목에서는 약간 미안한 마음마져 들었다. 너무나도 가볍게 마음가짐을 갖고 참석을 한터라서, 시간을 빼앗는건 아닌가? 라고잠시 반성..

갑자기 모이긴 했어도 역시나 많은 준비가 필요 없을 정도로 평소에 갖고 있는 내공들을 유감없이 뿜어내는 모습을 보니, 좀 더 자주 만나지 않으면 3시간은 턱없이 부족한 시간이라는 느낌을 받았다. 얘기하고 싶은 분들이 많았는데, 공지기간이 워날 짧아서, 발표주제를 수집할 수가 없어서, 참석하신 분들에게 기회가 다 돌아가지 못한 것 같았다.

언제나 즐거움과 도움과 지식과 노하우를 전달해주는 분들이 모인 자리라 그런지 유쾌한 느낌이었다. 개인적으로는 지난달에 있었던 루비온레일스실전워크샵 에서 발표했던 자료를 간단하게 소개하는 시간을 가졌는데, 짧게 줄여서 내용은 간략하게 하고 루비 커뮤니티에 참여하신 분들의 고마움을 느끼고 있다는 것을 전달하려고 노력은 했는데, 좀 횡설수설 했던 것 같다. (목도 너무 않좋구. 선생님들은 정말 대단하셔 ㅡㅡ;;)

커뮤니티 사람들이 좀더 원활하게 온라인에서 의사소통을 할 수 있는 공간이 어서 정착되면 좋겠다는 생각이 들었다. (그동안 nohmad님이 계속 개인적으로 운영을 해주시고 계셨는데, 이제는 사람도 점점 많아지고 있으니, 좀더 여러 사람이 운영을 도와줄 수 있는 형태로 되었으면 좋겠다 - 좋은 소식이 조만간 있지 않을까 ^^)

어쨌든 사진도 없고 무료한 후기인데, 루비 커뮤니티가 점점 더 활기찬 공간이 되었으면 좋겠다. 다음 세미나가 또 기다려진다.

P.S. 내용중에 이름이 매치가 안돼서 상세히 언급이 안되었으니 ^^;; 양해바랍니다.

이 글은 스프링노트에서 작성되었습니다.

신고

Railscasts (no1 ~ no5) : 레일즈 스크린캐스트

2007.03.28 18:11
아래내용은 railscasts.com 사이트에 올라온 동영상의 내용입니다. 레일즈 관련 팁들을 screencast 형태로 제공하고 있습니다. 직접 동영상을 보시면 더욱 좋습니다.

No1. Caching with instance variable

컨트롤러에서 모델의 find 메소드를 사용하는 경우 매번 DB 에 쿼리를 날리게 됩니다.

class ApplicationController < ActionController::Base

def current_user

User.find(session[:user_id]) # 이렇게 하면 매번 쿼리를 날리게 됨.

@current_user ||= User.find(session[:user_id])

end

end


볼드체로된 부분 처럼 항상 DB 쿼리를 하지 않도록, 인스턴스 변수를 활용해서 캐싱하는 형태로 사용하면 항상 DB자원을 사용하는 것을 줄여줄 수 있습니다.


No2. Dynamic find by methods

find 메소드의 형태를 좀더 간소하게 사용할 수 있는 find_by_methods 의 사용에 대해서 알아보도록 합니다. 간단하므로 아래 예제를 보도록 하죠.

find 메소드의 컨디션에 해당하는 컬럼을 메소드 명으로 줄 수 있습니다. 레일즈가 다이내믹하게 처리한다는 얘기죠.

class TasksController < ApplicationController

def incomplete

@tasks = Task.find(:all, :conditions => ['complete =?', false])

@tasks = Task.find_all_by_complete(false)

end

def last_incomplete

@task = Task.find(:first, :conditions => ['complete = ?', false], :order => 'created_at DESC')

@task = Task.find_by_complete(false, :order => 'created_at DESC')

end

end


No3. Find through association

모델간의 관계를 이용해서 데이타를 찾아도록 하는 방법에 대해서 알아보도록 합시다.

모델의 관계는 다음과 같습니다.

class Project < ActiveRecord::Base

has_many :tasks

end

class Task < ActiveRecord::Base

belongs_to :project

end

이경우 Association 을 이용해서 데이타를 가져오면서  No2 에서 제공하는 find_by_methods 까지 활용해서 수정을 하면 아래와 같습니다.

class ProjectsController < ApplicationController

def show

@project = Project.find(params[:id])

@tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false])

@tasks = @project.tasks.find_all_by_complete(false)

end

end

깔끔한 코드 ~~


No4. Move find into model

custom find 메소드를 생성해서 find 메소드를 모델로 이동시킬 경우 얻을 수 있는 장점은?

class TaskController < ApplicationController

def index

@tasks = Task.find_all_by_complete(false, :order => 'created_at DESC')

@tasks = Task.find_incomplete

end

end

위와 같은 형태에서 find_all_by_complete 를 find_incomplete 라는 클래스 메소드로 활용하게 되면 Task 모델에 다음과 같은 클래스 메소드를 추가하면 됩니다.

def self.find_incomplete

find_all_by_complete(false, :order => 'created_at DESC')

end

이런식으로 모델의 클래스 메소드로 생성해 두는 경우 아래와 같이 컨트롤러에서도 활용 가능죠.

class ProjectController < ApplicationController

def show

@project = Project.find(params[:id])

@tasks = @project.tasks.find_all_by_complete(false, :order => 'created_at DESC')

@tasks = @project.taskts.find_incomplete

end

end


No5. Using with scope

find 메소드를 커스텀하게 작성해서 모델로 이동시켜서 사용하는 경우, 커스텀 find 메소드로는 파라미터를 어떻게 전달할 수 있을 까요?

class Task < ActiveRecord::Base

belongs_to :project

def self.find_incomplete

find_all_by_complete(false, :order => 'created_at DESC')

end

end

이렇게 커스텀 find 메소드인 find_incomplete 를 생성해서 쓰고 있었는데, 이 메소드를 사용하는 컨트롤러에서는 호출시에 현재로서는 파라미터를 전달할 방법이 없습니다.

예를 들어서 아래와 같이 호출하고 싶은 경우 find_incomplete 메소드를 어떻게 수정하면 될까요?

class TaskController < AppliationController

def index

@tasks = Task.find_incomplete :limit => 20  #이렇게 파라미터를 추가해서 호출하고 싶다.

end

end

방법은 Rails 에서 제공하는 함수인 with_scope 를 사용하면 좀더 우아하게 처리할 수 있습니다.

find_incomplete 클래스 메소드를 수정해보도록 합시다.

def self.find_incomplete(options = {})

with_scope :find => options do

find_all_by_complete(false, :order => 'created_at DESC')

end

end

이렇게 수정하면 어떠한 형태의 파라미터도 다이내믹하게 처리할 수 있겠네요.

우아해졌습니다 ~~

P.S. 보다보니 벌써 동영상이 #11 까지 올라왔네요.. 나머지도 한번 가서 보세요... 짧으니 한꺼번에 보시면 저같은 초보 분들은 도움이 될만한 것들을 금방 얻을 수 있겠습니다.

[추가내용]
scope access method 관련해서 레일즈 플러그인이 하나 나왔네요.
AutoScope

Examples

Declare your scopes within your ActiveRecord::Base subclasses.

 class Contact < ActiveRecord::Base
auto_scope \
:old => {:find => {:conditions => ["born_on < ?", 30.years.ago]}},
:young => {:find => {:conditions => ["born_on > ?", 1.year.ago]}}
end

class Testimonial < ActiveRecord::Base
auto_scope \
:approved => {
:find => {:conditions => ["approved_at < ?", proc {Time.now}]},
:create => {:approved_at => proc {Time.now}}},
:unapproved => {
:find => {:conditions => "approved_at IS NULL"},
:create => {:approved_at => nil}}
end
이렇게 해주면 아래와 같이 사용하실 수 있습니다.
Testimonial.approved.count
Testimonial.unapproved.create!(params[:testimonial])
@young_contacts = Contact.young
@contacts = Contact.old.find(:all, :conditions => ["name LIKE ?", params[:name]])





신고

Web-based IDE and debugger for Rails

2007.02.14 11:34
Gyre 라는 오픈소스 툴이 나왔습니다. 웹기반의 레일즈 IDE 겸 디버깅 툴이라는 타이틀을 달고 있는데요, 개발자의 말에 의하면 아직은 pre-pre-pre alpha 상태이니 감안해서 봐달라고 합니다. 역시나 아직은 많이 불안정한 모습입니다.

이것또한 레일즈 어플리케이션으로 되어있습니다. 스크린캐스트도 올려져 있습니다.
사용자 삽입 이미지

screenshot


설치 방법은 아래와 같습니다.
sudo gem install -y ruby-debug -v 0.6.2
sudo gem install -y coderay
svn checkout http://gyre.bitscribe.net/svn/gyre/trunk gyre
cd gyre
mysqladmin create gyre
rake db:migrate
script/server -p 4000
기본적으로 Rails 1.2.1 로 되어있으니, Rails 1.2.2 를 쓰시는 분들은 config/environment.rb 에서 RAILS_GEM_VERSION 을 변경해 주시면 됩니다.

윈도우즈에 설치하시는 분들은 설치후 재시작시

TypeError in Project#index
Showing app/view/project/index.rhtml where line #32 raised:
can't convert nil into String ....

이런식의 오류가 날 수 있는데요, project_helper.rb 의 render_directory_dialog 에 보면 ENV["HOME"] 정보가 제대로 존재하지 않아서 그렇습니다. 대략 패쓰를 여러분들이 사용하시는 레일즈 어플리케이션이 있는 상위 디렉토리쯤으로 변경하시면 될 것 같습니다.

Gyre 를 설치한뒤 실행시키고 브라우저로 접속하면 처음 화면에서 프로젝트들을 등록하는 화면이 보이게 됩니다. 여기서 기존에 존재하는 레일즈 어플리케이션을 등록하게 되면 Gyre 는 기존의 레일즈 어플리케이션의 application.rb 파일에 내용을 추가하게 됩니다.

### The following was added by Gyre as a horrible, horrible hack.
### Remove if you wish to run the app standalone.
class ApplicationController < ActionController::Base
 before_filter :gyre_set_bp_retry
 def gyre_set_bp_retry
  params["BP-RETRY"] = true
 end
end
### EOH (end of horror)

확인해보니 위와 같은 내용이 추가되고 있었습니다. 이러한 것이 추가되는 이유는 익셥션을 핸들링 하기 위해서라는 군요. (브레이크 포인트를 걸기위한 용도로도 사용하는 것 같습니다). 디버거 상에서 어플리케이션이 실행되지 않는 경우에는 행걸릴수도 있으니 주의하라는 당부의 말도 있는 것 보면, 테스트용으로만 잠깐 써보는 것이 전부인 것 같습니다. 아직 많이많이많이 불안불안 합니다.

스크립트 기반의 레일즈 어플리케이션을 이렇게 꼭 브라우저로 IDE를 제공하고 디버깅 할 필요가 있을까 생각이 들기도 했지만, 어쨌든 디버깅에 많은 불편함을 느끼고 있는 저로서는 이러한 디버깅을 할 수 있는 옵션들이 많이 나타나는 것 자체가 반가운 소식입니다. 아직 갈길이 멀게만 느껴지는 중입니다.


 

신고
제 2회 루비 세미나가 1회때와 마찬가지로 오픈마루에서 있었습니다.
아래 위키페이지에서 2회에 참여하신 분들의 발표내용 및 후기들을 보실 수 있습니다. (아직 올라오는 중인 것 같네요)

이번 세미나는 부제가 있었습니다. "루비코드를 말한다" - 1인당 5분 내외의 코드조각을 발표하고 공유하는 것이었습니다. 하지만 역시나 1회때 세미나때 받았던 인상처럼 어느 한분도 쉽사리 5분정도에 끝내시는 분이 없었습니다.
재미난 것들 뿐아니라 제게는 아직 어려운 것들도 많이 언급되었습니다. 자극을 또 많이 받게 되었네요.
국내에 출시된 루비서적의 번역자분들도 오셨고.  앞으로도 줄줄이 출간 대기중이신 분들 (황대산님, WooKay님) 도 오셨습니다. 1회때도 모두 오셨든 분들이죠 ^^;;

(유스풀 패러다임) 김석준님 강문식님
 
현재 레일즈로 개발된 동영상UCC 허브사이트 웰리(http://wellee.com) 를 운영중이신 이노크레이지 김동규님의 서비스 개발기~ 의 소개도 있었구요.

조정목님의 레일즈1.2 변경사항 소개도 있었습니다.

본격적인 코드 공유가 시작되고나서는 사실 정신이 없었습니다. 위의 내용 소개가 끝나니 벌써 2시간 가량이 지나갔더군요. 동생 결혼식을 앞두고 상견례가 5시부터 있었던터라 머릿속이 복잡해지면서 ㅎㅎ 조바심나는 통에 사실 집중해서 듣질 못했습니다.

집중해서 들었더라도 쉽지않은 내용들이더군요, 황대산님의 메타 프로그래밍2 정도에 해당하는 이번 내용은 쉽지 않은 내용이었지만, 열심히 설명을 해주신 덕분에 약간 이해가 되었습니다. 책이 출간되어서 나오면 좀더 자세히 알 수 있을 것 같습니다. ^^

WooKay님의 셈플 코드는 보는 순간 ㅡㅡ+ 도무지 뭘 의미하는지 모르겠더군요. 조바심 낼 정도는 아니었는데, 왠지 코드를 보는 순간부터 지금까지 다급한 맘이 좀 드네요. 매일매일 열심히 루비를 다뤄봐야겠다는 생각이 들게해주는 코드였습니다.

중간에 나오는 통에 많은 분들의 주옥같은 발표를 듣지 못하게 되어서 무지 아쉬움을 느끼면서 쓰게되는 후기입니다. - 송우일님 열심히 동영상 찍어주셨는데, 언능 공유해 주실꺼죠?

하여간 제가 짧게 언급한 내용은 루비의 GC에 대한 내용이었습니다.  참석하신 분들의 얘기를 통해서 좀더 상세히 GC메커니즘에 대해서 알게 되었구요. 관련 개념들중 일부만(mark-and-sweep) 간신히 소개하는 정도였고,  copy-on-write (COW) 라던지 GC의 종류비교? 등등 기타 다른 내용들은 언급하지 못했습니다. (워낙 쫏기는 기분이라 ㅠㅠ). 셈플 코드도 루비의 GC를 체험하기에는 턱없이 부족한 내용이라 지금 생각하니 많이 아쉬움이 남습니다. ^^;;

뭐 후기에 아쉬움이 남아야 담에 더 잘할 수 있지 않을까? 라고 자위해보면서 국내의 훌륭한 많은 루비스트들과 1회에 이어서 2회때에도 공감할 수 있는 시간을 가졌던 것이 무척 즐거운 시간이었던 것 같습니다.

많은 분들의 발표를 다 듣지 못하고 가서 더 언급할 수 있는 내용이 ㅡㅡ;;;;

동영상 올려주시면 열심히 다시 보고 후기를 보강하도록 하겠습니다.  :D
신고
저도 크리스마스를 맞이하야 주변 사람들에게 엘프 바이러스를 유포중입니다.
전 아들녀석 버젼까지 두명의 엘프를 동원해서 행복 바이러스 퍼뜨리는 중이죠.
즐겁네요. 제가 제껄 더 자주 보는 것 같습니다. 하하하
 
[아빠버젼]
 
[아들 - 재선이버젼]

크리스마스가 얼마 안남았군요. 많이 많이 주변사람들에게 따뜻한 정을 나누어 주세요.
(이런 것두 정인가 ㅡㅡ;;;;)

신고

Douglas Crockford Video: Advanced JavaScript

2006.12.06 11:07
JavaScript Architect in Yahoo.... 야후에는 이런 직책도 있는가보다.  멋진걸.
자바스크립트를 다루는 일이 많아지는 요즘에는 이런 주제는 어드밴스드가 아니라 오히려 기본에 가깝지 않나 생각된다.

자바스크립트를 다루는 사람들 특히나 Ajax 를 주로 쓰게되는 사람들은 꼭 볼만한 내용인 것 같다.
강의 영상 뿐만아니라. 슬라이드까지 제공되니 한번쯤 보는게 좋을 듯 ...


신고

제 1회 루비 세미나 다녀왔습니다.

2006.11.27 10:20
국내에서 최초로 실시된 루비 세미나에 다녀왔다.  물론 그전에도 altlang 이나 Framework2.1 에서도 루비에 대한 내용은 있었지만, 이번 세미나에서 받은 즐거운 지적인 자극과 루비에 좀더 올인하고 싶은 의욕을 고취시켜주는 느낌 때문에라도 사실상 최초의 루비 세미나가 맞는 것 같다.

제1회 루비 세미나 위키 페이지 : http://wiki.rubykr.org/show/RubySeminar

어쨌든 그동안 블로그상으로만 보던 많은 루비 개발자들을 한자리에서 만날 수 있어서 가기전부터 기대가 되었는데, 발표 준비나 내용 그리고 토론하는 분위기 등등 역시나 deepblue 님의 발표에서 처럼 루비를 하는 사람들은 모두 사람냄새 나는 코드들을 접해서 그런지 왠지 다른 개발자들에게서는 접하기가 힘든 그런 좋은 느낌을 주는 개발자들이 많았던 것 같다. 

실무에 적용하는데는 역시나 많은 난관이 있겠지만, 그러한 고민에 대한 해결방법으로 JRuby 쪽에서 뭔가 대안을 찾으려고 고민하시는 창신님의 발표를 보면서 많은 공감을 받았다. Ruby 로 설득하기 힘들어서 groovy 로 어느정도 대리만족을 느끼고 있는 현 상태로서는 당분간 앞으로의 JRuby 의 행보에 많은 관심이 있을 수 밖엔 없을 것 같다.

어쨌든 배포에 대한 문제를 가장 심각하게 생각하고 있었던 요즘이었는데, 정목님이 발표하신 Capistrano 는 어느정도 배포 환경에 대해서 고민한 흔적들이 포함되어있는 것 같아서 매우 흥미롭게 본 내용이었다.

그나저나 기억에 오래 남는 것은 ikspress 님의 발표였는데, 아마도 많은 분들이 한껏 웃을 수 있어서 그랬나보다. 역시나 루비는 재미를 주는 것임에는 분명하지만, 발표하시는 내공이 (유머를 유도하시는) 상당하신 분이라는 느낌을 받았다.

많은 기대를 하고 있었던 nohmad 님의 발표는 역시나 중요한 순간에 닥치는 사고(발표자료가 사라짐 ㅡㅡ;;) 에도 불구하고 세미나를 이끌어가시는 모습을 보니 인코딩 문제에 있어서는 상당한 고민과 내공을 가지고 계신분이라는 생각이 들었다. (좋은 모듈이 나올 것 같은 예감이~~~)

하여간 모든 분들을 다 언급해 드릴 수는 없지만, 조만간 나오게될 세미나 동영상을 기대하면서, 그전에는 여러 훌륭한 루비 개발자분들을 간접적으로 만날 수 있는 위키페이지에 가보면 많은 후기들과 세미나 발표자료들이 있으니 루비에 관심있는 분들 또는 인간냄새나는 개발자들을 만나고 싶은 분들은 꼭 가서 꼼꼼히 보시길 ~~~

어쨌거나 몸담고 있는 회사에서 맘껏 루비질을 할 수는 없지만, 언젠가 프로페셔널한 루비 개발자 (취미가아니고^^) 가 되는 걸 꿈꾸면서 ~~

신고

자바스크립트로된 라이브러리 혹은 프레임웍 들을 살펴보다보면 눈엣 가시처럼 거슬리는 코드들이 보인다. 평소에 보지못한방식이라서 그럴 수도 있고, 워낙 고수들이 만들어놓은 자바스크립트 고유의 장점들을 살려서 작성해놓았기 때문일 수도 있다.

어쨌든 그중에 자바스크립트를 생성할때 네임스페이스를 구현하는 방법 등을 둘째 치더라도 (보면 그냥 이해가 되는 부분이기도 하니까) 왜 이런 라이브러리들은 프로토타입 객체를 통해서 함수들을 선언해 놓을까?

가장 큰 이유는 개인적인 생각에서는 메모리의 문제가 아닐까 한다. 물론 다른 이유도 많겠지만...

메모리의 측면에서 보기위한 예를 들면:

[CODE]

function mySample() {

var field1 = "test";

var today = new Date();

this.todayis=function(){

alert("Today is " + this.today);

}

}

[/CODE]

위와 같은 함수가 있다고 생각해보자. 이때 todayis 라는 함수는 오늘 날짜를 alert 창으로 찍어서 보여줄 것이다.이런식으로 mySample 함수 생성 메소드 내부에 함수를 추가하는 방식을 사용하는 경우에는 mySample 객체의 인스턴스가생성될때 마다 매번 함수를 새로 만드는 형태가 된다. - 객체를 대량으로 만드는 경우에는 메모리 사용면에 있어서 취약할 수 있다.

이런 고려사항때문에 대부분 Prototype 객체를 사용해서 함수를 연결하는 형태를 취하고 있는 것으로 생각된다.
하지만 Prototype 을 사용하는 경우에 주의해야 하는 사항은 가비지 문제이다.

함수내부에 함수를 추가한 형태의 경우에는 내부적으로 클로저가 만들어진 경우인데 (클로저는 함수 내부에 또 다른 함수를 구현하는 경우에만 동작한다), 이때 생성 메소드에서 DOM 엘리먼트를 다루는 경우에는 함수의 지역 변수로 선언된 내용이 가비지 컬렉터에게 수집되지 않는 문제점이 발생할 수 있다.

쩝... 여러가지고 JavaScript 코드를 사용해서 뷰단에서 멋진 효과및 이벤트 처리를 위해서는 많은 고려해야할 사항이 있는 것 같다.

신고


티스토리 툴바