November 2006 Archives

FindBugs 이클립스 플러그인은 정적 코드 분석 (static code analysis)를 통해 버그나 권장되지 않는 프랙티스들을 찾아주는 플러그인입니다. PMD, CheckStyle 등 몇가지 유사한 플러그인을 사용해보았는데, 어느 정도 설정을 조정해주어야 쓸만한 결과가 나와서, 이런 저런 튜닝을 하고 있는 중인데, FindBugs는 기본 설정으로도 결과가 좋아서, 고민없이 설치해서 써도 될 것 같습니다. PMD, CheckStyle 등을 잘 쓰는 것에 대해서는 다음에 써보겠습니다.

설치는 FindBugs update site ( http://findbugs.cs.umd.edu/eclipse )를 사용하시면 되구요. 이클립스의 프로젝트별 설정(Preference)에서 FindBugs를 활성화시켜주면 됩니다.

관련 레퍼런스는 The Last Mind 위키의 이클립스 플러그인 페이지를 참고하세요.

바보를 속이는 일은 쉽다. 지혜롭지 못한 사람을 속이는 일도 어렵지 않다. 설령 어떤 사람의 주장이, 얼마간은 진리에 의존하고 상당히 합리적인 논증 과정을 가지고 있다고 하더라도, 참인 것은 아니다. 지혜로운 사람은 그러한 주장에서 잘못된 전제들과 가정, 비합리적인 논증을 발견해낼 수 있지만, 그렇지 못한 사람들은 자신의 무지함과 무능력은 보지못하고, 궤변론자의 합리성을 시종처럼 뒤따를 뿐이다.

내게 객체 기반 프로그래밍 (Object-Oriented Programming)를 한마디로 축약하라면, 행동(Behavior)을 기준으로 도메인을 나누는(decomposition)하는 프로그래밍 방식이라고 정의할 것이다. 다시 말해, 객체(Object)는 잘 정의된 행동(Behavior)을 대표해야한다는 것이다. 행동(Behavior)이 아니라 자료(Data)를 기준으로 디자인하면, 구조화 프로그래밍(Structured programming)의 수동적인 자료구조와 그것을 조작하는 함수들의 집합이 탄생할 뿐이다. 설령 그것이 클래스라는 프로그래밍 언어 상의 장치를 사용한다고 하더라도 객체 기반 프로그래밍이라고 부를 수는 없다. (이러한 밈(meme)에 대해서는 Object Thinking이라는 책을 참고하라.)

Behavior-Driven Development라는 말을 강문식 군에게 처음 들었을 때는 이러한 객체 기반 프로그래밍의 생각을 대변하는 일반적인 개념을 가진 말이라고 추측했는데, 알고보니 정체는 그 개념을 TDD에 적용한 좁은 의미의 것이었다. Dave Astels 자신이 정의한대로 Behavior-Driven Specification 같은 용어를 썼으면 좋았을텐데 하는 생각이 든다.

설령 그렇다고 하더라도, 행동을 기준으로 하는 디자인이 맨 먼저 테스트에 적용되는 것은 상당히 훌륭한 개념이라고 생각한다. TDD를 통해서 얻을 수 있는 이점인 재사용과 테스트가 쉬운 (Reusable and Testable) 프로그램을 만드는데 있어서 객체 기반 프로그래밍의 기본 개념인 행동(Behavior)을 기준으로 한 디자인까지 할 수 있다면, 더할 나위 없이 좋을 것이다. 다만, 그것이 테스트 또는 스펙에만 머무르지 않고 실제 행동(Behavior)을 나타내는 디자인에까지 적용되어야 하겠지만 말이다.

아래는 Dave AstelsBDD에 대한 Google TechTalks 강연 내용 요약.

Unit vs. Behavior

unit: isolated focus like class, method
behavior: little fine-grained focused picses of behavior

unit should replaced by behavior
test should replaced by specification
assertion should replaced by expectation

rSpec

xunit should replaced by rSpec
assert_equal(expected, actual)->actual.should.equal expected

The Expectation API

  • equality
    • e.g. should.equal/sould.not.equal
  • counts
    • should.have(5).items
    • should.have.at.least(5).items
    • should.have.at.most(5).items
  • arbitrary block
    • should.satisfy { |obj| ... }
    • should.not.satisfy { |obj| ... }
  • pattern matching
    • should.match
  • arbitrary predicate
    • should.predicate (predicate? is defined on the target)
  • forced failure
    • violated(message)
  • exception
    • should.raise <exception>
  • direct class
    • should.be.an.instance.of C
  • ancestor class
    • should.be.a.kind.of C
  • interface
    • should.response.to :message

The Mocking API

just like jMock

  • creating a mock
    • m = mock("mock name")
  • expecting a method
    • should_receive(:name)
  • counts
    • never/once/twice/at_least_once/any_number_of_times
  • Arguments
    • with_no_args
    • with_any_args
    • with(arg1, arg2, ...)
  • Return values
    • and_returns(value)
    • and_returns_consecutively([...])
  • Provide a Block
    • should_receive(:name) {
    • |arg1, args2, ...|

Why Ruby?

  • Dynamic
  • Productive
  • Fun

Firefox의 유명한 extension인 Tab Mix Plus의 0.3.5 버전이 릴리즈 되었습니다. 아시는 분들은 아시다시피, Firefox 2.0 버전을 지원하는 버전입니다.

저의 Firefox 2.0 업그레이드 계획은 다음과 같습니다.

  • 회사의 Linux 데스크탑: Firefox 2.0 릴리즈 일에 Tab Mix Plus 개발 버전과 함께 설치.
  • 집의 Windows 데스크탑: Tab Mix Plus 0.3.5 정식 버전 릴리즈와 함께 설치.
  • Windows 노트북: '집의 윈도우즈 데스크탑'이 성공하면 이에 따라 설치.

현재 상황은,

  • 회사의 Linux 데스크탑: 성공했으나 기존에 저장해둔 세션이 알 수 없는 이유로 복구 되지 않음.
  • 집의 Windows 데스크탑: 성공.
  • Windows 노트북: 설치 예정.

Firefox 1.5 시절에 이미지로 캡쳐해둔 Tab Mix Plus 설정 방법이 무용지물이 되어서 괴롭습니다. 이래서 게으르면 여러가지로 손해입니다.

어쨌거나, 글 쓸 게 없으니, 별 쓸데없는 글을 다 적는군요.

회사에서 하고 있는 프로젝트에서 정책 데이터들을 MySQL 데이터베이스로 관리하고 있는데요. 보편적인 MySQL 관리툴인 phpMyAdmin 조차 사용하지 않고 그냥 손으로 관리하고 있길래 RubyOnRails로 간단한 관리 도구를 만들어보았습니다. 정확히 30분 걸렸습니다. 많은 관리 도구들이 CRUD 정도만을 필요로 하다는 것을 고려하면 RubyOnRails의 scaffolding만으로도 거의 충분하다고 볼 수 있죠. 다음에 시간이 나면 authentication/authorization 정도를 붙여볼 생각입니다.

Setting up database configuration

$ vi config/database.yml
development:
  adapter: mysql
  database: scheduler_policy_manager_development
  username: ***
  password: ***
  host: ***

Creating a model

$ ruby script/generate model address_schedule_policy

Creating a table for the model

$ vi db/migrate/001_create_address_schedule_policies.rb
class CreateAddressSchedulePolicies < ActiveRecord::Migration
  def self.up
    create_table :address_schedule_policies do |t|
        t.column :name,     :string
        t.column :ip,       :int
        t.column :period,   :int
    end
  end

  def self.down
    drop_table :address_schedule_policies
  end
end
$ rake db:migrate

Creating a scaffolding controller

$ ruby script/generate controller admin
$ vi app/controllers/admin_controller.rb
class AdminController < ApplicationController
    scaffold :address_schedule_policy
end

Running the web server

$ ruby script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2006-10-09 20:58:38] INFO  WEBrick 1.3.1
[2006-10-09 20:58:38] INFO  ruby 1.8.4 (2005-12-24) [i486-linux]
[2006-10-09 20:58:38] INFO  WEBrick::HTTPServer#start: pid=26079 port=3000

Adding some validation

$ vi app/models/address_schedule_policy.rb
class AddressSchedulePolicy < ActiveRecord::Base
    validates_presence_of :name, :ip, :period

    protected
    def validate
        errors.add(:period, "should be at least 5000 (ms)") if period.nil? || period < 5000    end
end

Generating scaffold

$ ruby script/generate scaffold address_schedule_policy admin

Making a small change to the table

$ script/generate migration ChangeTypeOfIpField
$ vi db/migrate/002_change_type_of_ip_field.rb
class ChangeTypeOfIpField < ActiveRecord::Migration
    def self.up
        change_column :address_schedule_policies, :ip, :string
    end

    def self.down
        change_column :address_schedule_policies, :ip, :int
    end
end
$ rake db:migrate

Installing streamlined generator

$ cd ~/tmp
$ wget http://streamlined.relevancellc.com/streamlined_generator-0.0.5.gem
$ sudo gem install streamlined_generator-0.0.5.gem

Generating streamlined scaffold for the model

$ ruby script/generate streamlined address_schedule_policy
# should restart WebRick to show streamlined correctly
$ script/server

Installing mongrel (the alternate web server)

$ sudo gem install mongrel

Running the new web server

$ mongrel_rails start

Author

Linko Apple Booth in the Coex Seoul Email address

Recent Comments

  • 홍민희: dPuTTY도 참고하세요~ read more
  • lastmind.net: 아직 많이 부족해요~ ^^ read more
  • nowol: 내가 세라비 존경하는거 알지? 잘 배우고 가요~ read more
  • lastmind.net: 네. ㅎㅎ 커널 님도 구입하셔야죠? read more
  • kernel0.myid.net: 어이쿠 뻘 답글을 남겼네요 -_-; 워헤드가 아니라 오리지널인줄 알았습니다. =_=;;; read more
  • kernel0.myid.net: http://en.wikipedia.org/wiki/Crysis_Warhead 라고 좀있음 또 나오지말입니다. ㅎㅎㅎ read more
  • lastmind.net: 와 그 정도인가요? 요즘 가격이 너무 안내려가서 ATI가 좀 더 read more
  • miriya: 4870때문에 요즘 nVidia가 쭈욱 밀리고있지요 ㅎㅎ 예전에 지포스6600 시절만 해도 read more
  • lastmind.net: 네, 저도 나중에 알고 충격. ㅎㅎ read more
  • lastmind.net: C++의 BAR == foo와 Java의 BAR.equals(foo)에요. 양쪽 모두 identity가 아니라 read more

About this Archive

This page is an archive of entries from November 2006 listed from newest to oldest.

October 2006 is the previous archive.

December 2006 is the next archive.

Find recent content on the main index or look in the archives to find all content.