2007년 7월 31일 화요일

남대문 가츠라~

명동의 가쓰라하고는 다른 곳(?)입니다. 체인점이라고 합니다. (베이즐 님의 블로그)
사용자 삽입 이미지

가츠라~


사용자 삽입 이미지

히레까스랑 닭 튀김(이름이 생각이 안나네요 ^^;;)이랑 장어구이(^^;;; 어찌하다 시켰답니다.)를 시켜서 먹었는데....
사용자 삽입 이미지

사용자 삽입 이미지

장어구이는 튀김하고 같이 먹기에는 좀.. 별로인 듯하군요. 튀김 굳~


튀김이 최고네요. 튀김옷이 고기에 쫘~ㄱ 달라 붙어서 입안에 들어갈 때는 살살 녹는듯한 그맛~
사용자 삽입 이미지

오늘의 주인공 히레까스~


사용자 삽입 이미지

닭을 튀긴건데.. 이름은 기억이 안나네요 ^^;;


아~ 오랜만에 먹어본 황홀한 튀김의 재맛을 느꼈다고 할까나요~
사용자 삽입 이미지
사용자 삽입 이미지

야근한다고 저녁 때 먹으러가서 폰으로 찍은 사진밖에 없습니다.
※ 모듬튀김이 메뉴에서보면 작아보이는데 의외로 양이 많습니다..  -_-b

사용자 삽입 이미지

위치는 숭례문쪽의 파란 화살표 부근에 있습니다. ^^

※※ 보다보니... 명동의 가츠라도 체인점인 것 같네요.
※※※  남대문 가츠라 링크입니다. 메뉴도 포함되어 있네요.

2007년 7월 29일 일요일

SimpleTest(Unit Testing for PHP)

SimpleTest는 PHP에서 사용할 수 있는 Unit Testing 툴로서 이클립스 플러그인으로 사용할 수 있습니다.

설치하는 방법
  1. SimpleTest에서 이클립스 플러그인을 다운로드 받습니다.
  2. 적당한 장소에 다운로드 받은 소스의 압축을 풉니다.
  3. 이클립스를 실행시킨 다음에 Help > Software Updates > Find and install을 실행합니다.
  4. Search for new features to install > New Local Site을 클릭해서 설치할 프로그램의 위치를 설정합니다.

    사용자 삽입 이미지

  5. Finish를 눌러서 설치를 합니다. (설치가 완료된 후에 이클립스가 재시작됩니다.)
  6. 재시작한 이클립스에서 Window > Preferences를 클릭해서 Preferences 다이얼로그를 띄웁니다.
  7. SimpleTest항목을 찾은 다음에 PHP.exe file의 위치와 php.ini 파일의 위치, 그리고 Test File Suffix를 설정해줍니다. (Suffix를 설정하면 플러그인이 테스트 파일을 찾는데 도움을 줍니다. - 저의 경우에는 .test.php로 설정하였습니다.)
    사용자 삽입 이미지

  8. OK를 눌러서 창을 닫습니다.
사용하는 방법
PHP파일을 생성한 후 UnitTestCase를 상속받은 테스트 클래스를 작성해주면 됩니다. 테스트할 메소드는 test로 시작하여야만 됩니다.
<?php
    class test1 extends UnitTestCase {
        function test_pass(){
            $x = 1;
            $y = 2;
            $total = $x + $y;
            // 기대하는 결과값인 3과 메소드의 수행결과인 $total을 비교하여 비교치가
             // 다른 경우 세 번째 argument를 test fail과 함께 출력하게 됩니다.
            $this->assertEqual(3,$total, "This should pass");
        }
    }
?>
작성한 파일을 실행하기는 간단합니다. Run > Open Run Dialog를 띄운 다음에 SimpleTest를 실행시켜주거나 실행할 파일을 설정한 후 실행시켜주면됩니다.
사용자 삽입 이미지

※ 테스트를 추가하는 방법도 간단합니다. UnitTestCase를 상속받은 클래스에서 test...()를 추가하거나 UnitTestCase를 상속받는 테스트 클래스를 추가한 후 GroupTest를 생성하여 테스트가 가능합니다.
<?php
    class myGroupTest extends GroupTest {
        function myGroupTest() {
            parent::GroupTest('');
            $this->addTestFile(dirname(__FILE__).'/test1.php');
            $this->addTestFile(dirname(__FILE__).'/test2.php');
        }
    }
?>
※※ setUp() 메소드와 tearDown() 메소드를 사용하여 테스트 클래스가 로딩하기 전에 실행되는 작업을 수행하고, 테스트 종료한 다음에 마무리 작업을 수행할 수 있습니다. (다른 단위 테스트와 동일합니다.)

※※※ Mockup 생성도 가능합니다. Mockup을 생성하는 목적은 내부와 외부를 연결해주는 게이트웨이에 해당하는 부분을 만들 때 사용합니다.
// mock_objects를 포함시킵니다.
require_once('simpletest/mock_objects.php');

// Mockup으로 만들 클래스 파일이 따로 있다면 require_once를 호출하여 포함시킵니다.
// 또는 클래스를 동일 테스트 파일에 선언해줍니다. (인터페이스만 선언해주면 됩니다.)
...
// Mock 클래스를 생성합니다.
Mock::generate('Sample');

// 이렇게 생성된 Mock 클래스는 Mock~으로 시작되는 이름의 클래스로 생성할 수 있습니다.
sample = new MockSample();

// 생성된 클래스의 메소드가 호출될 때의 동작을 정의하기 위해서 expect
// 또는 setReturnReference() 를 사용하여서 어떤 메소드가 호출될 때 어떤
// 리턴결과가 돌아올지에 대해서 정의가 가능합니다.
sample->expect(...);
출처 :  SimpleTest  via Manning, PHP in Action(Objects, Design, Agility)- 9,10장

※ SimpleTest의 API는 여기로 -> http://simpletest.org/api/

6. Object-oriented pinciples

1. The open-closed principle(OCP)
확장에는 열려있고, 수정에는 닫쳐있어야 한다.(open to extension, closed to modification)
// 수정전
function hello() {
   echo "Hello, Dolly!\n";
}

// 수정 후, 변경 가능한 요소인 이름을 인자로 받아 출력, 코드 수정없이 출력 범위를 확장함
function hello($name) {
   echo "Hello, ".$name."!";
}
2. The single-responsibility principle(SRP)
하나의 클래스에는 하나의 책임만을 져야한다. (변화 가능한 요소가 하나만 있어야 한다. -A class should have only one reason to change)

템플릿 엔진(Template engine)의 기본적인 특징은 다음과 같습니다.
  • 변수들의 집합을 저장할 수 있어야 합니다. (Storing a set of variables)
  • 템플릿 파일을 읽을 수 있어야 합니다. (Reading a template file)
  • 템플릿 파일과 변수 집합을 통하여 출력물을 생성할 수 있어야 합니다. (Combining the first two to generate output)
이러한 특징을 바탕으로 Template을 생성하면 다음과 같은 클래스를 만들 수 있을 것입니다.
class Template {
   private $vars;
   private $file;

   // 생성자에서 파일을 인자로 받아서 템플릿 파일에 사용될 파일을 저장합니다.
   public function __construct($file) {
     $this->$file = $file;
   }

   // 이름과 값 쌍으로 받아서 변수를 저장합니다.
   public function set($var, $value) {
     $this->vars[$var] = $value;
   }
  
   /* HTML로 출력합니다.
    * 1. 설정된 변수들의 집합을 현재의 심볼로 임포트합니다.
    * 2. 출력 버퍼에 템플릿 파일을 출력합니다.
    * 3. 출력 버퍼의 내용을 $string으로 리턴한 다음에 버퍼를 끕니다.
    * 4. 출력 버퍼를 클리어한다음 $string을 리턴합니다.
    */
   public function asHtml() {
     extract($this->vars);
     ob_start();
     include $this->file;
     $string = ob_get_contents();
     ob_end_clean();
     return $string;
   }
}
(관점에 따라 다를 수 있습니다만,) SRP의 원칙에서 봤을 때는 변수를 저장하는 부분과 템플릿 파일을 읽어들이는 부분과 템플릿으로 생성하는 부분 세 개의 책임을 가지는 클래스로 볼 수 있습니다. 따라서 이들을 분리할 수도 있겠죠.
// File을 읽어들이고 처리하는 클래스입니다.
class File {
   public function __construct($name) {
     $this->name = $name;
   }
   // File의 내용을 스트링으로 리턴합니다.
   function getContents() {
     return file_get_contents($this->name);
   }
}

// Template에서 사용하기 위한 변수들을 설정합니다.
// 디폴트 값을 설정하는 기능을 여기에서 할 수 있겠죠.
class TemplateData {
   private $vars;
   public function set($var, $value) {
     $this->vars[$var] = $value;
   }
   public function getArray() {
     return $this->vars;
   }
}

// TemplateData와 File에 템플릿 변수/파일을 처리하는 기능을 위임한 클래스입니다.
class Template {
   private $data;
   private $file;

   public function __construct($file) {
     $this->file = new File($file);
     $this->data = new TemplateData;
   }

   public function set($var, $value) {
     $this->data->set($var, $value);
   }

   private function processTemplate() {
     extract($this->data->getArray());
     $string = $this->file->getContents();
    // 파일처리와 템플릿 생성을 분리하여 include를 사용할  수 없어서 eval을 사용
     eval('?>'.$string);
   }

   public function asHtml() {
     ob_start();
     $this->processTemplate();
     $string = ob_get_contents();
     ob_end_clean();
     return $string;
   }
}
※ 그 외에도 The Dependency-inversion principle(DIP)와 Layered designs가 소개되어있는데 생략합니다~
※※ 4,5 장도 읽어봤는데.. 아는 내용이라 생략합니다~ ^^;;;

출처: Manning, PHP in Action(Objects, Design, Agility) 보면서 요약한 내용입니다.

여행 유의·자제·제한·금지 지역 보기

'여행 유의·자제·제한·금지 지역'에 대한 정보는 외교통상부 해외안전여행사이트가 원 출처더군요.

사용자 삽입 이미지
최소한 기사가 정보의 전달이 목적이라면 원래 출처와 링크를 명확하게 표기를 해줬으면 좋겠네요.
인터넷 상에서의 글쓰기의 기본 아닐런지...

출처: 외교통상부 해외안전여행사이트 via 중앙일보 이지은 기자의 '의외로 많은 여행 유의·자제·제한·금지 지역'

※ 태국이 여행유의,제한지역으로 되어있던데... 쓰레기 만두에 불량식품천국인 중국도 여행유의 지역에 들어가야 하지 않을까 생각이 되네요. ^^

2007년 7월 24일 화요일

3. Using PHP classes effectively

1. visibility: 메소드나 프로퍼티에 대해서 접근 권한 설정이 가능합니다.
  • public
  • private
  • protected - 디폴트로 설정됩니다. 부모나 자식 클래스에서만 접근이 가능합니다.
2. getter/setter 메소드 __get()__set()를 사용하여 접근 메소드를 만들면 getProperty()나 setProperty() 메소드 같은 메소드를 만들 필요없이 다음과 같은 형태로 사용할 수 있습니다.
$ClassInstance->property;
※ getter/setter의 경우 실험적으로 도입된 성격이 강하다고 합니다.

3. final - 자식 클래스에서 클래스 또는 메소드의 오버라이딩을 막습니다. (deprecated를 나타내기 위해서 사용할 수 있습니다.)

4. ::(double colon)은 클래스의 변수, 메소드 또는 상수를 접근하기 위해서 사용됩니다.
$product = Product::find($productCode);
5. 클래스 메소드는 static을 사용하여 정의합니다.
static public function encryptPassword(...){}
클래스 밖에서는 ::를 사용하여 접근하나 클래스안에서는 self를 사용하여 접근이 가능합니다.
self::encryptPassword();
※ 클래스 메소드, 변수에 대한 접근은 $this를 사용할 수가 없습니다.
※※ 언제 클래스 메소드를 사용하는가?
  • Creation methods and factory methods
  • Finder methods
  • Procedural code
  • Replacement for constants
6. 상수(constant)는 const로 정의합니다. 상수를 정의할 때는 $를 사용하지 않습니다.

7. abatract 선언을 사용할 수 있습니다.
  • abstract로 정의된 클래스 또는 메소드를 바로 사용할 때 에러가 발생합니다.
  • abstract로 정의된 메소드가 포함되어 있는 클래스는 abstract 클래스가 되어야 합니다.
abstract class HtmlDocument{
    public function getHtml() {...}
    abstract public function getContent();
}
8. CLASS Type Hints, 인자로 넘어오는 파라미터의 타입을 체크할 수 있습니다.
public function addDocument(Document $document) {}
  • Documnet의 인스턴스 또는 이를 상속받은 클래스의 인스턴스의 경우 정상통과가 되나 문자열(string)이나 다른 객체(Object)를 통과시킬 때 경고(Warning)을 발생시킵니다.
  • 그러나, 통과된 후에Document에 정의되어 있지 않은 메소드를 호출해도 에러메시지가 발생하지는 않습니다.
  • 객체들과 배열들만 체크가 가능하며 일반적인 데이타 타입(plain data type)을 체크하지는 않습니다.(예를 들면 문자열)
  • Type Hint의 단점으로는 체크를 위해 사용된 클래스가 변경되는 경우 관련된 Type Hint를 모두 변경해줘야 하는 의존(dependency)이 생긴다는 점입니다.
  • Type Hint가 실패한 경우 nonExistentmethod()가 호출됩니다.
9. instanceof를 사용해서 타입 체크가 가능합니다.
public function addDocument($document) {
    if(!($document instanceof Document)) {
        ...
    }
}
10. 인터페이스(interface)
interface Template {
   public function __constuct();
   public function execute();
   ...
}
자바의 인터페이스와 비슷합니다.
  • 클래스는 여러 인터페이스를 동시에 구현하는 것이 가능합니다 .
  • 동적언어에서는 인터페이스가 없는 것과 반대로 php에서는 이를 지원합니다.
    • 생성비용으로는 인터페이스 파일을 여는 비용을 제외하고는 거의 없습니다.
    • 디자인을 좀 더 명확하게 나타내고 실수를 막을 수 있습니다.
  • abstract와 동일한 역할을 합니다.
  • 두 개의 인터페이스를 구현하는 경우, 각각의 인터페이스가 동일한 메소드를 갖지 못합니다.
  • 인터페이스는 다른 인터페이스를 상속할 수 있습니다.
  • 생성자(__construct())를 인터페이스에서 선언할 수 있습니다.)
클래스에서 인터페이스를 구현하도록 선언하는 것도 비슷합니다.
class SmartyTemplate implements Template()
출처: Manning, PHP in Action(Objects, Design, Agility) 보면서 요약한 내용입니다.

2. Objects in PHP

1. PHP5에 들어오면서 객체 지향적 설계가 가능하게 되었습니다.

2. PHP 클래스 형태
// 상속은 extends를 사용합니다.
class HelloWorld extends ParentClass{
       
private $world;
       
public $hello;
       
       
// 생성자입니다.
       
function __construct($world) {
               
// 자신의 프로퍼티나 메소드를 호출하는 경우 $this를 사용합니다.  
                $this
->world = $world;

               
// 부모의 생성자를 호출할 때는 parent를 사용할 수 있습니다.
                parent
::__construct();
       
}
       
       
function getHtml() {
               
return "Hello, ".$this->world."!";
       
}
}
3. PHP4와 달리 객체를 나타낼 때 레퍼런스를 사용합니다. PHP4에서 &를 사용하여 레퍼런스를 지정할 수 있어나 내부에서 symbol table alias를 가지고 있습니다.

4. 메소드의 Override를 지원합니다.

5. 기존에 exception이 발생하는 경우 die()를 사용하여 처리했습니다. PHP5에서는 throw를 사용하여 Exception을 발생시킬 수 있고,
throw new Exception('...');
try/catch를 사용하여 Exception을 잡을 수 있습니다.
try {
   ...
}catch(Exception $e) {
   print($e->getMessage());
}
6. 디버깅하는 경우 스택을 따라가고 싶을 때 debug_trace()와 debug_print_backtrace()를 사용할 수 있습니다.

7. 예외를 사용하는 것보다는 예외 상황에서 이를 처리하는 코드를 사용하는것이 더 좋습니다.

8. 사용자 정의 예외도 만들 수 있습니다. 그러나, 사용자 정의 예외는 최대 5~7개정도가 좋으며 내부에서 예외를 구분하는 코드를 사용하는 편이 더 낳습니다.
class UserException extends Exception{}
9. PHP에서 제공하는 예외를 사용자 정의로 바꾸는 것도 가능합니다.
class ErrorFromPHPException extends Exception{}
function PHPErrorHandler($errno, $errstr, $errfile, $errline) {
   throw new ErrorFromPHPException($errstr, $errno);
}
...
$oldhandler = set_error_handler('PHPErrorHandler');
fopen('/tmp/non-existent', 'r');
...
원상 복귀할 때도 set_error_handler를 사용하면 됩니다.
set_error_handler($oldhandler)
10. PHP에서 클래스를 생성하고 메소드를 호출할 때, 메소드가 없는 경우 __call()가 호출됩니다. (책에서는 오버로딩 시 사용합니다. 메소드 매개변수가 다른 경우 내부에서 __call()에서 적절한 메소드를 체크하여 호출시킵니다.)

11. __autoload() 정의되어 있지않은 클래스를 초기화하려는 경우 호출됩니다. (include되지 않은 클래스를 자동으로 호출하려고 하는 경우)


출처: Manning, PHP in Action(Objects, Design, Agility) 보면서 요약한 내용입니다.

2007년 7월 22일 일요일

document.write없이 html삽입하기

document.write을 사용해서 javascript코드를 삽입하는 방법은 다음의 문제를 가지고 있습니다.
  1. XHTML 모드에서 동작하지 않습니다.
  2. document.write를 써서 추가된 코드는 API를 사용하여 접근할 수 있는 방법이 없습니다.
  3. document.write는 HTML을 노드로 보지 않고 Serialized text로 보는 전혀 다른 관점을 지니고 있습니다.(DOM하고 비교했을 때)
document.write가 아닌 DOM을 이용해서 코드를 삽입하려면 다음의 방법을 선택할 수 있습니다.

  1. 호출할 javascript코드를 페이지에 삽입합니다.
    <scrip type="text/javascript" id="syndication" src="syndication.js"></script>

  2. syndication.js에 다음의 코드를 추가합니다.
    // 삽입할 태그를 DOM을 이용해서 생성합니다.
    var newContent = document.createElement('p');
    newContent.id = 'syndicated-content';
    newContent.appendChild(document.createTextNode('Here is some syndicated content.'));

    var source = document.getElementById('syndication');
    // script태그의 바로 앞쪽에 newContent를 삽입하게 합니다.
    source.parentNode.insertBefore(newContent, source);
2의 코드는 document.write('<p id="syndicated-content">Here is some syndicated content</p>');와 동일한 역할을 합니다.

출처: Insert in place without document.write via Simon Willison’s Weblog

J4P5(JavaScript For PHP 5)

  • J4P5(JavaScript For PHP 5)PHP5로 쓰여진 자바스크립트 인터프리터입니다.
  • 신뢰할 수 없는 JavaScript코드를 서버에서 실행시켜볼 수 있습니다.
  • ECMA-262 3rd edition을 구현했습니다.
  • GPL입니다.
부족한 점은 다음과 같습니다.
  • 유니코드가 지원되지 않습니다.
  • 정규표현식이 지원되지 않습니다.
  • 기본적으로 제공되는 대부분의 객체와 메소드들에 대해서 테스트가 되어 있지 않습니다.
  • 속도가 느립니다.
웹상의 에디터에서 JavaScript를 포함한 글을 쓰게 하는 경우 보안등의 문제를 서버단에서 체크하는데 사용하면 유용할 것 같네요. (소스는 보지 못했습니다. (__))

출처: J4P5 in Simon Willison’s Weblog

HTTP overhead 줄이기

1. 문제점
  • 페이지에 많은 이미지나 비디오 파일이 포함되어 있습니다.
  • 해당하는 이미지나 비디오 파일은 동일한 파일이 아니기 때문에 HTTP연결을 생성하고 초기화하는데 비용이 들어갑니다.
  • 예) 아바타를 사용하는 Q&A 페이지에서 50개의 아바타를 로딩하는 경우
  • 이미지가 다 로딩되지 않은 경우 페이지가 아직 사용하지 못하는 것처럼 인식될 수 있습니다. (onload시간에 js동작을 하게 하였다면 로딩전까지 js가 실행되지 않겠죠)
2. 해결책
이미지의 src를 기본값이 되는 "디폴트 이미지#http://원주소"로 변경하여서 처음 페이지 로딩 시에 디폴트 이미지를 로딩하게 합니다.
<img src="default.gif#http://avatarurl" ... >
페이지 로딩이 끝난 다음(onload가 호출되는 시점)에 #뒤의 이미지 원주소를 로딩하게 합니다.

3. 소스코드

/*
        delayHTTPoverhead
        written by
                Christian Heilmann
        with help
                from Drew McLellan, David Dorward and Lawrence Carvalho
        http://www.wait-till-i.com/index.php?p=465
        License: http://creativecommons.org/licenses/by/3.0/
*/

delayHTTPoverhead
= function(){
       
var parentID = '';
       
var avtClass = '';
       
       
// 페이지의 default이미지를 원래 이미지로 교체해줍니다.
       
function replaceImage(){
               
var img = (parentID!=='')?
                        document
.getElementById(parentID).getElementsByTagName('img'):
                        document
.getElementsByTagName('img');
               
               
var rep=/.*#/;
               
for(var i=0;img[i];i++){
                       
var src=img[i].src;
                       
                       
if(src.indexOf('#')!=-1 && img[i].className.indexOf(avtClass)!==-1){
                                img
[i].src = src.replace(rep,'');
                       
};
               
};
       
}
       
       
// onload에 replaceImage를 추가시켜줍니다.
       
var _onload=wind_onloadw.onload;
       
if(typeof window.onload!='function'){
                window
.onload=replaceImage;
       
}else{
                window
.onload = function(){
                       
if(_onload){
                                _onload
();
                       
};
                        replaceImage
();
               
};
       
};
}();

4. 출처




2007년 7월 20일 금요일

맥북 팔기..(팔렸습니다.)

에서 휴가비가 안나오는 관계로..
맥북을 팔려고 내놓았습니다. -_-;; 가격은 72만원으로 내놓았습니다. 
  • 구매일: 작년 7월
  • 메모리: 2G로 업그레이드
  • 하드디스크: 120G로 업그레이드
  • 부속품: 설명서, OS X시디, 리모컨, 박스
  • DVI 컨버터, 원래 사용하였던 메모리 256M *2 모두 포함입니다.
사용자 삽입 이미지

관심있으신 분은 댓글로 달아주세요. ^^
서울에서 직거래 하고 싶습니다.

큰 사진을 보시길 원하시면 여기를 클릭하세요.


2007년 7월 19일 목요일

hr 태그 색바꾸려면?

사용자 삽입 이미지

이쁘게 바뀐 hr~


hr 태그의 색상을 바꿀 때 아무리해도 color, border, background-color를 설정해도 안되더군요. 그래서 찾아보니 noshade를 선언해야지만 색상이 변경이 가능하다고 하더군요.
<hr noshade="noshade" color...

출처 : HTML HR COLOR CHANGE

IE6, https에서 Security Warning이 발생하는 경우

사용자 삽입 이미지

https를 사용하는 경우 "This page contains both secure and nosecure items. Do you want to display the nosecure items? " 또는 "이 페이지는 보안된 항목과 보안되지 않은 항목을 모두 포함하고 있습니다. 보안되지 않은 항목을 표시하겠습니까?" 라는 메시지가 나오는 경우...

  1. HTTPS 안에 있는 파일들에서 다른 리소스를 접근할 때
    1. https를 사용해야하는데 http를 사용하거나
    2. https의 위치 외의 곳에 있는 파일에 접근하는 경우 등
  2. HTTPS 안의 소스에서 iframe을 가지고 있을 때(src에 절대 경로 사용시 https사용해야 함)
    1. iframe에 src가 없는 경우
    2. iframe에 src가 있으나 src의 파일이 없는 경우

출처:

P.S. 관련 참고자료 나미님이 알려주신 skc101님의 "이 페이지는 보안된 항목과 보안되지 않은 항목을 모두 포함하고 있습니다."


아침 출근 길

밤새도록 모기와 사투를 벌이다..(두마리를 격추(?) 시키긴 하였습니다.) 잠을 설치고 출근하는 아침길...

비가오더군요. 피곤함에 우울함까지..급 우울모드~
지하철 타러 올라가는 에스컬레이터 안에서 한 아가씨가 좌측통로 길을 막고서 (우측 서서가는 라인에 설 수 있는 공간이 충분히 있는데도 불구하고) 우산이 고장난듯 계속 우산을 만지작거리더군요.
 '출근 시간은 어쩌라고 길을 막고 서있는거냐? -_-'

지하철을 탔는데 옆에 선 아저씨 한명이 장우산을 들고선 옆으로 기울여서 들고 계시더군요.
 '옆 사람 물떨어지는 건 생각안하냐? -_-'

복잡한 지하철에 습기 가득찬 통로에 서있는데 모기가 달려들더군요.
 '젝일슨~ -_-;;;; 으~으~'

하도 복잡한 통로에 서있다가 자리가 나길래 앉아버렸습니다. 조금 있다가 옆자리 사람이 내리고 한 아가씨가 앉았는데 다리를 꼬고 앉더군요. 그리고선 앞사람 피해줄까봐 옆으로 다리를 꼬더군요. 바지에 물이 다 묻었습니다.
 '이런 ㅅㅂㄹㅁ 장난하냐? -_-'

지하철에서 나오는데 길을 막고 서있는 인간들은 왜이리 많은지.. --;;;;

다른 사람의 입장에서보면.... 반대로 피해를 줬을지도 모른다는 생각도 들지만.. 급우울에 급짜증 모드로 들어가는 하루군요. !!

사용자 삽입 이미지

2007년 7월 18일 수요일

가수 싸이에 대한 궁금증...

오늘 뉴스를 보니 '병무청에서 싸이의 군 복무기간을 방산에서 근무한 4개월을 뺀 20개월을 복무해야한다(8월6일 입대)'는 뉴스가 나오더군요. 갑자기 궁금증이 들더군요...

그러면 들어가자마자 한달만에 일병다는건가요? 훈련소에서는 편하겠네요~

사용자 삽입 이미지

뉴스 출처: 스포츠조선, "가수 싸이, 8월6일 논산 육군훈련소에 현역 입대" via Naver

2007년 7월 17일 화요일

블로그를 이용한 대한항공의 B787 마케팅

대한항공에서 B787 도입과 관련하여 B787미션이라는 마케팅을 시작했는데 블로거들을 타겟으로한 마케팅이 포함되어 있습니다.


자신의 블로그에 대한항공, B787 도입과 관련한 포스팅을 하고 해당 페이지로 가서 응모를 하는 방식인데요. 몇가지 조건이 붙어있습니다. 글 제목과 태그(이글루스에 태그도입이 안되었으면 응모도 못했었겠네요.)와 포스트 본문에 B787, 대한항공 키워드가 들어가는 것을 조건으로 했습니다.

참가하기만해도 100마일을 준다고하니 기쁜마음으로 받아먹습니다만...
홍보라는 1회성 마케팅에 그친점과 우수작(블로그 댓글, 조회수 등으로 평가)을 위해서 스팸성 글을 뿌릴 수 있다는 점을 생각한다면.. 약간은 미흡한 마케팅이 되지 않을까 생각되네요.
 
대한항공 마일리지카드로 100마일 쌓을려면.. 1만3천원 정도 써야되나요?  ^^

출처: 대한항공 787미션

2007년 7월 16일 월요일

옷장수가 방문한 나라들


※ 방문맵을 만들어보세요~

2005년도가 진정 대박이었네요. -_-;;;; 그 이후로 나가본적이 없어서....
이제는 혼자가 아닌 그녀와 함께하는 여행이 되었으면.. ㅠㅠ

나미님의 홈피로부터~ (이 집은 오리지날 홈피라서 트랙백이 없답니다.)

2007년 7월 14일 토요일

Safari버그 - 화면에 보이지 않는 Textarea에 값을 설정하는 경우..

  • Safari 버전: 2.0.3
  • 플랫폼: OS X 10.4
팝업을 띄워서 Textarea에서 값을 받아 설정하는 프로그램(텍스트 + html)을 짜서 Safari에서 테스트를 하는데 안되더군요.
처음에는 코드를 잘못짰나 싶어서 다시 보았는데 Safari의 버그더군요.
Element.show(dialog);
form.dialog_form.textarea.value = "..."
와 같은 코드가 원래 사용한 코드였습니다. 실제로는 좀 더 많은 코드가 사용되기는 합니다만.. 다이얼로그가 화면에 출력되기 전에는 form.value의 값이 동작하지는 않더군요.

그러나, 다이얼로그가 뜬 다음에 주소창에 javascript:form.dialog_form.textarea.value = "..."를 설정하는 경우는 정상적으로 값이 설정이 되었습니다. 구글에서 검색해보니 관련한 버그에 대한 내용이 좀 나오더군요.
Element.show(dialog);
form.dialog_form.textarea.innerHTML = "<span style="color:red;">메모</span>입니다."
저의 경우 이를 해결하기 위해서 innerHTML을 사용해봤습니다만, 동작을 하지 않더군요. 텍스트를 저장하는 것은 가능하였습니다만, html을 입력하는 경우에는 동작을 하지 않더군요. (<span>~</span>은 잘리고 입니다만 나오더군요.)
Element.show(dialog);
form.dialog_form.parentNode.innerHTML = "<textarea><span style="color:red;">메모</span>입니다.</textarea>"
해결책으로 삼은 것은 textarea의 parentNode의 html을 바꿔버리는 것으로 해결은 했습니다만...


이런 버그가 있더군요 =.= ;;

관련 자료: Brian Hartsock's Blog - Safari Textarea bug

2007년 7월 11일 수요일

fileSize

IE에만 해당하는 얘기지만 파일을 업로드하기 전에 document나 image의 파일 사이즈를 알려주는 속성이 있습니다. fileSize가 그 속성인데요.
document.fileSize   // 해당하는 html 페이지의 size를 리턴합니다.
document.images[i].fileSize   // document.images를 통해서 접근하는 image의 fileSize를 알 수 있습니다.
quirksmode에서는 document.fileSize + document.images[0..length].fileSize를 합한 값을 페이지의 총 크기로 계산하더군요. (혹시나 싶어서 덧붙이지만, images[0..length].fileSize가 값을 가지고 오는 것은 아니구요. -쉬운 표기를 위해서- images의 루프를 돌면서 각 image의 fileSize를 가지고 와야합니다.)

출처: quirksmode의 File size

National Genographic의 결과..

족보가 정확하다는 것을 새삼 깨닫게 되었다.. -_-;;;

사용자 삽입 이미지

클릭하시면 크게 볼 수 있습니다.


아프리카에서 서남아시아, 중동을 거쳐 동북아시아 중국으로 들어오게 됩니다. (같은 계통으로 미얀마, 중국, 타이완 사람들이 같은 계통이더군요.)

제가 성이 의령 옥씨인데 시조는 당나라에서 건너온 옥진서님 이십니다. (from 네이버 백과사전)
시조는 당()나라 사람 옥진서()인데 당나라에서 재사() 여덟 사람을 고구려에 파견할 때 그 중 한 사람으로 나와서 뒤에 신라에서 의춘군()에 봉해졌다고 한다...
족보가 맞군요 ^^b
오랜 시간과 비싼 비용이 들었지만 즐거웠던 탐험이었던 것 같습니다.

출처:
네이버 백과사전 옥(玉)

[메모] 루비로 특정사이트를 스크랩하기에 대한 생각?

친구인 H군(사이트 운영자입니다.)이 '스팸 때문에 골치아퍼~'라고 투덜투덜 되길래 루비로 스크래퍼(?)를 만들면 어떨까 하고 고민을 하다가 조사를 좀 해봤습니다. 

기본적인 아이디어는 다음과 같습니다.
  1. 사이트의 주소를 인자로 받습니다.
  2. 사이트의 html을 읽어옵니다.
  3. html에서 http://로 시작되는 주소를 추출합니다.
  4. 해당 주소가 스팸주소인지를 비교합니다.
    1. 스팸주소인 경우 해당주소를 삭제 대상으로 기억해 놓습니다.
    2. 해당 주소가 운영 사이트의 하위 사이트면 해당 주소로 이동 후 3,4의 과정을 반복합니다.
아주~ 단순한 프로그램이라서 금방되겠지 생각을 했답니다만.. 쉽지가 않더군요. (세상일이 만만하겠습니까?)

1생략하고 2의 부분은 Net::HTTP.start(url) {|http| response=http.get('index.html')} 을 사용하여 페이지를 요청한 다음의 response를 얻어냅니다. 그리고, response.body를 통해서 페이지의 각 라인을 얻어옵니다.

여기에서 정규표현식을 써서 http://로 된 주소를 얻어옵니다. 이 주소를 이용해서 다시 탐색에 들어가거나 스팸여부를 비교하기 위한 수단으로 사용합니다.

주소를 얻는 부분은 쉽긴한데 html을 파싱해서 어떤 데이타를 얻어야할지 필요한데이타를 어떻게 가져와야할 지가 애매하더군요. 공식적인 html 파서는 없는 듯 했습니다. (검색 결과 몇개 나오는 것은 있더군요. RAA-html-parser2, JavaScript파서도 있더군요.)

결론은... 여기까지.. 역시 같이 뭔가를 같이할 사람이 필요한 시점인 것 같군요 ^^

관련자료

2007년 7월 10일 화요일

[메모]루비로 프로그램 짜면서 실수했던 것들

TinyMCE의 jstrim으로 js파일들을 통합하려고하니 다음의 문제가 있었습니다.
  • 합쳐야할 js파일들의 목록을 xml파일로 따로 관리해야한다.
  • 에러나는 경우 어디에서 에러가 발생하는 지 알수가 없다.
  • (그리고 개인적인 사정) C#을 봐야 소스를 볼 수 있다. (-_- 귀차니즘~)
이러한 이유로 루비로 뚝딱뚝딱 프로그램을 만들어 보았습니다. 프로그램의 동작은 단순합니다.
  1. php파일을 읽어들입니다.
  2. <? if($isDebug) { ?> 에서부터 <?} else {?>까지의 script태그를 가진 라인들에서 src의 주소를읽어 들입니다.
  3. <?} else {?> 에서부터 <?} ?>까지의 script태그를 읽어들입니다.
  4. 2의 파일목록들을 3의 파일에 합쳐서 배포합니다.
아주 단순한 프로그램입니다만 짜는 과정에서 다음과 같은 에러로 고생을 했습니다.
  • String 변수와 String 변수를 +연산자로 합치는 경우 (변수가 nil 이 될 때 에러가 나더군요.)
  • Ruby 프로그램은 Block없이 프로그램을 짤 수 없다.
  • File.open()으로 파일을 여는 경우 인자로 받는 경로가 절대 경로가 아니면 에러가 발생한다.(File.expand_path()로 절대 경로를 알 수 있다.
이런 노력(?)끝에 허접 프로그램이 나왔습니다. 돌기는 잘 도는 군요 - .-)//

허접이지만.. 오랜만에 포스팅을 위해서 올려봅니다.

more..

2007년 7월 4일 수요일

YAHOO의 Module Pattern

큰 골격은 다음과 같습니다.모듈인 myModule을 통해서만 (public속성에) 접근이 가능합니다.

YAHOO.myProject.myModule = function(){}();

이 function() 안에 return을 추가한다.

YAHOO.myProject.myModule = function(){

return {

myPublicProperty: ""   // public property가 된다.

myPublicMethod: function() {}   // public method가 된다.

}

}();

public property/method들은 return된 hash를 통해서 접근이 가능한 public 속성이 됩니다.

※ 마지막에 ()를 사용하여 anonymous를 실행시키고, 이를 myModule을 통해서 접근하게 합니다. 

 여기에 function()안에 property와 method를 정의한다.

YAHOO.myProject.myModule = function(){

  var privateProperty;   // private property가 된다.

  var privateMethod = function() {}   // private method가 된다.

return {

myPublicProperty: ""  // public property가 된다.

myPublicMethod: function() {} // public method가 된다.

}

}();

밖에서 봤을 때 private property/method는 접근할 수 없지만 public속성 (return되는 hash)에서는 closure를 통해서 접근이 가능하게 됩니다. private속성을 감추고 public 속성만을 접근하게 함으로서 Global variables are evil원칙을 훌륭하게 지키게 해줍니다.

Module Pattern은 privatge속성과 public 속성을 나누는것이 목적입니다.

출처 : Yahoo! User Interface Blogl의 Module Pattern

[css] overflow-x, -y

overflow:scroll을 사용하면 수직,수평방향으로 스크롤바가 모두 생기기 때문에 보기가 안좋은 경우가 있습니다. 이런 경우에는 overflow-x, overflow-y를 사용하세요. 수직 또는 수평 한쪽 방향만 스크롤 출력이 가능합니다.

w3 문서를 보니
'Overflow' is a shorthand for 'overflow-x' and 'overflow-y'. It sets both to the same value.
라고 되어 있네요 =. =;;

출처 : CSS3 module in w3.org


P.S. Safari에서는 overflow-x, overflow-y가 설정이 되지 않더군요. overflow:auto로 설정하는 경우 x 또는 y축 방향으로 자동적으로 설정됩니다. {overflow:auto; overflow-x:hidden; overflow-y:auto;}로 설정하면 Safari나 다른 브라우져에서도 y축방향으로만 설정되게 됩니다.

2007년 7월 1일 일요일

오픈마루 1st DevDay 참석 후기

사용자 삽입 이미지
오픈마루 1st DevDay에 참석하고 돌아왔습니다. 재미있었습니다. ^^b ;;;
이창신님Lightweight MVC Platform에 새 인증 방식Google Gears로 날개를 달자라는 세션을 들었는데요.

준비를 해야하는 부분이 있는걸 몰라서 따라가는데 힘들었습니다만.. 재미있더군요 ^^
(조만간 정리를 해서 올리겠습니다.)

세미나를 들으면서 부러운 것도 많더군요. 애플리케이션에 대한 고민이라던거 Mashup에 대한 고려 등등..
저는 언제쯤이면 저정도 될 수 있을까.. 갈길이 참 먼것 같습니다. -_-;;

(조만간.. 제대로 정리해서 올릴께요 (__))