검색결과 리스트
언어로그/Ruby/Rails에 해당되는 글 3건
- 2011.03.04 자바 개발자를 위한 루비적 관점
- 2010.12.12 [Ruby]WEBrick 서블릿 사용하기
- 2010.12.12 [Ruby]WEBrick 서버구동
글
자바 개발자를 위한 루비적 관점
핵심클래스 확장(Core Class)
Java에서는 SDK와 같은 Language Runtime의 핵심클래스에 메서드를 추가할 수 없기 때문에 확장메서드들을
다른 클래스의 정적메서드로 모아두는 방식을 선택함 (공백문자열인지 검사하는 StringUtils의 isBlank 메소드)
루비의 클래스들은 개방되어 있어서, 언제든지 수정 가능함
class String
def blank?
empty? || strip.empty?
end
end
루비의 nil은 자바의 null 에 해당하지만, 객체이며, 메소드 호출 및 추가가 가능
class NilClass
def blank?
true
end
end
불변객체의 장점
스레드 안정성 - 객체를 변경할 수 없기 때문에 스레드 충돌이 없음
캡슐화 용이
효율적인 해시키 생성 - 해시코드가 변경되지 않기 때문
가변(Mutable) 객체와 불변(Immutable) 객체
자바는 가변과 불변 2가지 버전의 클래스들이 존재하며, final 키워드를 사용해 불변성을 지원함
루비는 클래스가 아닌 인스턴스 수준에서 가변성이 이루어지는데, freeze 메서드를 호출하면 불변이됨
자바의 불변클래스에 변경메소드 호출은 변경된 새로운 객체를 리턴함
루비문자열은 자동 불변속성은 아니지만, 변경메소드에 대해 새로운 객체를 리턴함
루비 메소드기호 관례
Boolean 값을 반환하는 메소드는 ?로 끝남
객체의 값을 바꾸는 메소드는 !로 끝남
대입문에 사용되는 메소드는 =로 끝남
패키지와 네임스페이스
자바는 package 키워드를 사용해 네임스페이스를 생성
루비는 module을 사용하여 네임스페이스 생성. 참조하는 모듈다음에 범위연산자 :: 사용
module Relevance
class User
def initialize(name)
@name = name
end
attr_accessor : name
end
end
module Codecite
class User
def initialize(name)
@name = name;
attr_accessor : name
end
end
end
u1 = Relevance::User.new("Justin")
u2 = Codecite::User.new("Stu")
include Relevance
u3 = User.new("Jared")
puts "u3 is a #{u3.class}"
코드배포
- 로드패스(Load Path)
자바는 클래스패스 및 클래스 풀네임을 통해 클래스 단위로 로딩함
루비는 :$ 라는 이름을 가진 로드패스를 가지고 있으며, 소스파일 단위로 코드를 로딩함
(한 소스에 여러개의 클래스가 있을 수 있고, 아에 클래스 정의가 없을 수도 있기 때문 )
require 'super_widget'
w = new SuperWidget('phlange")
- 루비젬(RubyGems)
루비젬은 소스파일의 덩어리를 가리키는 말로, 자바에서의 jar 라고 생각할 수 있다.
gem 커맨드를 사용하여, 젬으로 그룹핑하고, 문서파일 생성, 웹을 통해 다운받고, 버전을 관리할 수 있다
require 'rubygems'// 젬을 로딩하기 위한 사전정의어 정도... require_gem 'pdf-writer'
애플리케이션을 특정 버전의 레일스에 바인딩하는 것을 동결(freezing)이라고 함!
레일스는 동결 지정/해제를 위한 freeze란 레이크 태스크를 포함하고 있음
위임
레일스에서 확장한 delegate라는 메소드를 사용하여 위임을 쉽게 사용할 수 있다.
require 'rails'
class Manager
attr_accessor : programmer, :tester
delegate :code, :debug, :to=> :programmer
delegate :write_test_plans, :run_tests, :to=>:tester
end
다형성과 인터페이스
루비에는 컴파일 타임이 없기 때문에, 자바의 다형성과는 다르게 작동함
루비의 타입 안전성은 인터페이스 차원이 아닌 메서드 차원에서 보장됨. 런타임에 실제 구현되지 않은 메소드를
호출하면 NoMethodError 예외를 던짐
자바에서는 컴파일 타임에 객체가 특정 인터페이스 타입이 아니면 에러를 발생시켜 주지만, 루비는 실행시에 실제로
해당 메소드가 구현되외 있는지 확인하고 예외를 발생시켜준다는 의미이다.
루비 메타프로그래밍
- 리플렉션
루비의 Object클래스도 자바처럼 객체의 상태와 내용을 볼수 있는 기능을 제공함
리플렉션 메서드로 Object#respond_to?, Object#instance_of?, Object#instance_variables, Object#kind_of 가 있음
- 메시지 전달
Object클래스의 send메서드를 통해 동적으로 객체의 메소드를 호출 할 수 있으며, 매개변수로 블록전달도 가능
실행할 메서드의 이름을 동적으로 조합해서 지정할 수 있기 때문에 다양한 형태의 메소드 호출, 전달이 가능
- 없는 메서드 처리(method missing)
존재하지 않는 메서들을 처리해주는 Object#method_missing 메서드를 재정의해서 사용할 수 있음
오리 타이핑(Duck Typing)
객체의 타입이 클래스(Object#class)가 아닌, 실제 그일을 수행하는 메서드를 가지고 있는지를 기준으로 판단
(오리처럼 걷고, 오리처럼 말하면, 인터프리터 입장에서 오리로 취급해줄게~)
- 오리타이핑의 장점
단위테스트 스텁객체 작성이 용이 - 필요한 메서드만 구현해주면 됨
반복적으로 사용하는 코드에 대해 인위적인 경계를 허물어뜨림 - 유연성?
객체 간의 관계 리팩터링이 쉬움
- 오리타이핑의 단점
자동화 도구들이 변수와 메서드 추측을 어렵게 만들어, 좋은 품질의 코드완성과 리팩터링 제공이 힘듬
믹스인
한번 작성한 코드를 믹스인으로 몇 개의 클래스나 모듈과 혼합할 수 있는 방식
위임을 믹스인으로 쉽게 구현할 수 있음
module Employer
def employees
@employees ||= []
end
def add_employee(employee)
...
end
def remove_employee(employee)
...
end
end
class BusinessPerson < Person
include Employer, Employee
end
특정 객체의 인스턴스를 생성하고 extend를 사용하여 특정 인스턴스에만 적용되게 할수도 있다
p = Persion.new("Stu", "Halloway")
p.extend Employer
함수(Functions)
함수형 언어에서의 함수를 의미한다. c, c++, 자바같은 절자지향 또는 객체지향 언어들은 명령형 프로그래밍의
개념들을 따르고 있다. 이들 프로그래밍에서 함수는 객체의 상태를 변경시키는 작업을 한다.
함수형 언어에서의 함수는 특정 입력값에 대해 항상 동일한 결과값을 반환하는 동작만을 한다.
루비에는 이런 함수와 유사한 블럭(block)이 존재한다. 자바에서도 인터페이스와 익명클래스를 사용하여 블럭 또는
클로저를 구현할 수 있다.
자바
public interface Comparator {
int compare(Object o, Object o1);
}
Collectons.sort(al, new Comparator() {
public int compare(Object o, Object o1) {
return ((String)o).length() - ((String)o1).length();
}
});
루비
sorted = readlines.sort { |x, y| x.length - y.length }
puts "sorted:\n #{sorted.join}
블록은 특정 작업에 대한 래퍼(Wrapper)를 구현할 때 유용함
def expect_exception(type)
begin
yield// 전달받은 블록을 호출함, 없으면 무시
rescue type=>e // 해당하는 타입의 예외이면 정상종료
return
end
raise "Excpected exception: #{type}"// 다른타입의 예외이면 예외를 발생시킴
end
expect_exception(ZeroDivisionError) {10/0}
&를 사용하여, 명시적으로 블록을 인자로 전달 받을 수 있다. block_given?를 호출해서 블록전달 유무도 알수 있다.
def expect_exception(type, &blk)
begin
blk.call if block_given? // 전달받은 블록을 호출함, 없으면 무시
rescue type=>e // 해당하는 타입의 예외이면 정상종료
return
end
raise "Excpected exception: #{type}"// 다른타입의 예외이면 예외를 발생시킴
end
expect_exception(ZeroDivisionError) {10/0}
'언어로그 > Ruby/Rails' 카테고리의 다른 글
| 자바 개발자를 위한 루비적 관점 (0) | 2011.03.04 |
|---|---|
| [Ruby]WEBrick 서블릿 사용하기 (0) | 2010.12.12 |
| [Ruby]WEBrick 서버구동 (0) | 2010.12.12 |
설정
트랙백
댓글
글
[Ruby]WEBrick 서블릿 사용하기
#!/usr/bin/ruby
require 'webrick'
include WEBrick
s = HTTPServer.new(:Port => 4000)
class HelloServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res['Content-Type'] = "text/html";
res.body = %{
Hello. You're calling form a #{req['UserAgent']}
I see parameters: #{req.query.keys.join(', ')}
}
end
end
s.mount("/hello", HelloServlet)
trap("INT"){ s.shutdown }
s.start
'언어로그 > Ruby/Rails' 카테고리의 다른 글
| 자바 개발자를 위한 루비적 관점 (0) | 2011.03.04 |
|---|---|
| [Ruby]WEBrick 서블릿 사용하기 (0) | 2010.12.12 |
| [Ruby]WEBrick 서버구동 (0) | 2010.12.12 |
설정
트랙백
댓글
글
[Ruby]WEBrick 서버구동
#!/usr/bin/ruby
require 'webrick'
include WEBrick
s = HTTPServer.new(
:Port => 3000,
:DocumentRoot => File.join(Dir.pwd, "/html")
)
trap("INT") { s.shutdown }
s.start
'언어로그 > Ruby/Rails' 카테고리의 다른 글
| 자바 개발자를 위한 루비적 관점 (0) | 2011.03.04 |
|---|---|
| [Ruby]WEBrick 서블릿 사용하기 (0) | 2010.12.12 |
| [Ruby]WEBrick 서버구동 (0) | 2010.12.12 |