Dash (Docs & Snippets)

Dash (Docs & Snippets)

ตอนที่เขียนโปรแกรมทุกครั้งผมจะเปิด document ของภาษานั้นทิ้งไว้ 1 เพจ เพื่อคอยดูวิธีการใช้งานในกรณีที่ไม่แน่ใจ ซึ่งถ้าจำเป็นต้องไปไปทำงานในสถานที่ ที่ไม่มีอินเทอร์เน็ตก็ต้องอาศัยความรู้ที่มีในหัวหรือเอกสารที่ดาวน์โหลดทิ้งไว้ในเครื่องเพื่อคอยเปิดอ่านวิธีใช้งาน ซึ่งวิธีนี้ก็ยังมีปัญหาที่ในกรณีที่เราไม่อัพเดตเอกสารที่ใช้บ่อยๆ มันก็จะล้าสมัยไป ซึ่งถ้าโชคดีหน่อยถ้าเครื่องมือที่ใช้พัฒนา (IDE) นั้นเป็นคนรับหน้าที่จัดการอัพเดตเอกสารให้ แต่ก็ใช่ว่าเครื่องมือทุกรายจะทำหน้าที่แบบนี้เสมอไป

โชคดีที่ไปเจอ Dash (Docs & Snippets) เข้า Dash เป็นแอพพลิเคชั่นที่รวบรวมเอาเอกสารอ้างอิงของภาษาต่างๆ เข้าไว้ด้วยกัน ขณะที่เขียนอยู่นี้มีมากถึง 70 ภาษา ซึ่งเลือกได้ว่าต้องการที่จะดาวน์โหลดเอกสารใดมาไว้ในเครื่องบ้าง เช่น PHP, WordPress, Vim, HTML5, CSS3, iOS (สำหรับ iOS ไม่มีให้ดาวน์โหลดโดยตรง แต่จะใช้วิธีการไปอ่านจากเอกสารให้หลังติดตั้ง Xcode) เมื่อมีเอกสารอัพเดต Dash จะเตือนและอัพเดตเอกสารนั้นมาไว้ในเครื่องให้ทันที

ข้อดีของ Dash ที่เห็นได้ชัดคือค้นหาเร็วมาก แทบจะเรียกได้ว่าในทันทีทันใดเลยก็ว่าได้ ถึงแม้จะพิมพ์ผิดหรือพิมพ์ตกหล่นไปก็ไม่มีปัญหาเลย ซึ่ง Dash จะรองรับเอกสารที่สร้างจาก Appledoc หรือ Docxygen ซึ่งเป็นเครื่องมือสำหรับสร้างเอกสารที่เป็นที่นิยมมากสำหรับการสร้างเอกสารประกอบการพัฒนา ซึ่งแนวโน้มของจำนวนเอกสารที่ Dash รองรับก็ย่อมมีมากขึ้นเรื่อยๆ อย่างแน่นอน นอกจากนั้นที่เจ๋งอีกอย่างหนึ่งคือ Snippet ในกรณีมีชุดของคำสั่งที่ใช้บ่อยๆ เข้าไว้ด้วยกันและจำชื่อเรียกสั้นๆ ที่เราตั้งขึ้นมา เช่น @date ก็จะคือวันที่ปัจจุบันออกมา หรือหากมีโค้ดของ HTML Boilerplate Code ได้ใช้งานบ่อยๆ ก็เพียงแค่สร้าง Snippet ใหม่ กำหนดชื่อที่ต้องการให้ อย่างเช่น html-boiler-plate# จากนั้นเมื่อต้องการใช้งานก็เพียงแค่พิมพ์ชื่อที่เรากำหนดให้ ชื่อที่กำหนดให้ควรจำเพาะเจาะจงเพื่อไม่ให้ซ้ำกับข้อความที่เราจะพิมพ์ เนื่องจาก Dash จะทำงานเป็น deamon อยู่เบื้องหลัง เมื่อเจอคำที่ตรงกันกับที่กำหนดไว้ก็จะแทนที่ข้อความในทันที

เรื่องสำคัญที่สุดคือ Dash (Docs & Snippets) เป็นแอพฟรี แต่ก็มี In-App purchase ซื้อตัวเต็มอีก $9.99 เหรียญ เท่าที่ใช้งานดูแล้วก็ไม่เห็นข้อแตกต่างที่ชัดเจนว่าหลังจากซื้อแล้วมีอะไรบ้างที่แตกต่างจากเวอร์ชั่นฟรี แต่ก็ไม่เสียใจที่ซื้อไปเพาะส่วนหนึ่งแล้วต้องบอกกว่าเป็นแอพที่ใช้งานคุ้มค่ามาก ตอนนั้นอยากสนับสนุนคนทำมากกว่าที่จะคิดเรื่องคุ้มหรือไม่คุ้ม

สนใจอยากลองดาวน์โหลดมาทดลองใช้ได้ที่ App Store (สำหรับผู้ใช้งาน OS X เท่านั้น)

Dash page: http://kapeli.com/dash/
App Store: https://itunes.apple.com/th/app/dash-docs-snippets/id458034879?l=th&mt=12

custom-maintenance-mode

กำหนดให้ WordPress เข้าสู่โหมดบำรุงรักษา

โหมดบำรุงรักษาเป็นโหมดการทำงานหนึ่งของเว็บไซต์เพื่อลดผลกระทบการใช้งานเว็บไซต์ระหว่างที่มีการปรับปรุงระบบ สำหรับ WordPress นั้นจะเปิดใช้โดยอัตโนมัติระหว่างที่มีการอัพเกรดเวอร์ชั่นของ WordPress, Plug-in หรือ Theme หากแต่จะเป็นช่วงสั้นๆ เท่านั้น ซึ่งรูปด้านล่างจะเป็นหน้าจอโดยปริยายของ WordPress (ภาษาอังกฤษ) ซึ่งจะมีเพียงตัวหนังสือเท่านั้น
Continue reading

MySQL:: mysql_fetch_object

*บันทึกไว้อ่านกันลืม

พอดีวันนี้ได้กลับมาเขียน PHP แบบที่ต้องเชื่อมต่อกับฐานข้อมูลเองผ่าน mysql_* ที่ติดมากับ PHP หลังจากไม่ได้ใช้มานานแล้วตั้งแต่สมัยมหาวิทยาลัย แต่หลังจากใช้ไปได้สักพักก็เกิดความรู้สึกที่ว่าการใช้ mysql_fetch_array เหมือนที่เคยใช้มันไม่ค่อยสวยเท่าไหร่ พอดีเหลือบไปเห็น mysql_fetch_object เมื่อก่อนก็เคยใช้ แต่พี่งสังเกตว่าเราสามารถระบุคลาสมารับข้อมูลที่อ่านมาได้ เหมือนกับ Object Model ในพวก ORM วันนี้ก็เลยลองของสักหน่อย

ได้โค้ดทั้งหมดดังนี้

<?php
$connection = null;

function __db_connection() {
  global $connection; 

  $connection = mysql_pconnect( '127.0.0.1', 'foo', 'bar' );
  if ( ! $connection )
    $connection = mysql_pconnect( '127.0.0.1', 'foo', 'bar' );

  mysql_select_db( 'my_db_name' );
  mysql_query( 'set names utf8' );
};

class SL_Foo {
  protected $_foo = array(
    'ID'          => '',
    'message'     => '',
    'timestamp'   => ''
  );

  function __get( $name ) {
    global $datetime_format;
    if ( in_array( $name, array( 'timestamp' ) ) )
      return date( $datetime_format, strtotime( $this->_foo[ $name ] ) ) ;

    return @$this->_foo[ $name ];
  }

  function __set( $name, $value ) {
    $this->_foo[ $name ] = $value ;
  }

}

if ( ! $connection ) __db_connection();

$sql = sprintf( "select * from foo where ID = '%s'", addslashes( $_REQUEST['id'] ) );

$results = mysql_query( $sql, $connection ) ;
if ( ! $results ) printf( 'MySQL Error: %s', mysql_error() ) ;

$foos = array();
if ( mysql_num_rows( $results ) )
  while( $foo = mysql_fetch_object( $results, 'SL_Foo' ) ) 
    $foos[] = $foo;

mysql_free_results( $results );

// Do something with $foos
echo var_dump( $foos );

อธิบายโค้ดได้ดังนี้ครับ

  • บรรทัดที่ 2: สร้างตัวแปรเพื่อเก็บการเชื่อมต่อกับฐานข้อมูล
  • บรรทัดที่ 4-13: ฟังก์ชั่นสำหรับการเชื่อมต่อกับฐานข้อมูล
  • บรรทัดที่ 15-34: คือคลาสที่สร้างขึ้นเพื่อรับข้อมูลที่อ่านได้จากฐานข้อมูล โดยมีชื่อฟิลด์คือ ID, message, timestamp ซึ่งชื่อนี้ต้องเหมือนกันกับชื่อฟิลด์ที่มีในฐานข้อมูลแบบ case sensitive
  • บรรทัดที่ 22-32: เป็น Magic methods ของ PHP โดยที่ __get คือเมธอดที่ใช้อ่านค่าต่างๆ ของคลาส โดยสามารถกำหนดเงื่อนไขการการแสดงผลของค่าที่คืนไปได้ เช่นในตัวอย่างคือถ้าค่าที่ผู้ใช้ต้องการคือ timestamp ให้เปลี่ยนรูปแบบจากรูปแบบมาตรฐานในฐานข้อมูลให้กลายเป็นรูปแบบตามที่กำหนดในตัวแปร $datetime_format
  • บรรทัดที่ 36: สร้างการเชื่อมต่อ
  • บรรทัดที่ 38-41: สร้าง Query String และส่งข้อมูล Query เข้าสู่ฐานข้อมูล
  • บรรทัดที่ 45: อ่านค่าที่ได้จาก $results ออกมาเป็น Object โดยนำคลาส SL_Foo ที่กำหนดไว้ข้างต้นมารับค่าที่อ่านได้

จะเห็นได้ว่า ข้อดีของการสร้างคลาสเข้ามารองรับการทำงานแบบนี้คือเราสามารถกำหนดรูปแบบการแสดงผลของข้อมูลที่เราต้องการได้ อย่างเช่นเปลี่ยนแปลงรูปแบบวันที่ตามที่เราต้องการในตัวอย่าง นอกจากนั้นยังทำให้ดูแลจัดการโครงสร้างข้อมูลได้ง่ายขึ้น

* แก้ไข
เนื่องจากดูโค้ดแล้วมันดูเยิ้นเย้อในส่วนของฐานข้อมูลซึ่งสามารถลดลงได้ดังนี้

<?php
$connection = null;

function __db_connection() {
  global $connection; 

  $connection = mysql_pconnect( '127.0.0.1', 'foo', 'bar' );
  if ( ! mysql_ping( $connection ) ) {
    $connection = mysql_pconnect( '127.0.0.1', 'foo', 'bar' );
  }
  
  mysql_select_db( 'my_db_name' );
  mysql_query( 'set names utf8' );
};

class SL_Foo {
  protected $_foo = array();

  function __get( $name ) {
    global $datetime_format;
    if ( in_array( $name, array( 'timestamp' ) ) )
      return date( $datetime_format, strtotime( $this->_foo[ $name ] ) ) ;

    return @$this->_foo[ $name ];
  }

  function __set( $name, $value ) {
    $this->_foo[ $name ] = $value ;
  }

}

if ( ! $connection ) __db_connection();

$sql = sprintf( "select * from foo where ID = '%s'", addslashes( $_REQUEST['id'] ) );

$results = mysql_query( $sql, $connection ) ;
if ( ! $results ) printf( 'MySQL Error: %s', mysql_error() ) ;

$foos = array();
if ( mysql_num_rows( $results ) )
  while( $foo = mysql_fetch_object( $results, 'SL_Foo' ) ) 
    $foos[] = $foo;

mysql_free_results( $results );

// Do something with $foos
echo var_dump( $foos );
  • บรรทัดที่ 8-12 รวมเป็นบรรทัดเดียวกัน เพื่อลดการเชื่อมต่อกับฐานข้อมูลตอนสั่งเปิดการเชื่อมต่อ
  • คลาส SL_Foo ลบการใส่คีย์เป็นค่าเริ่มต้น เนื่องจากคลาสใช้ Magic Methods และด้วยวิธีการเขียนทำให้จะระบุหรือไม่ก็ไม่ส่งผลกระทบกับการทำงาน
Screen Shot 2012-04-25 at 19.00.40

Set Up GHUnit for iOS

อยากลองทำ TDD บน iOS ดูบ้าง เลยเห็นว่ามี Test Framework อยู่ 2 ตัวบน iOS ที่น่าสนใจ คือ SenTesting ที่เป็น Build-in Framework ของ Xcode และ GHUnit ที่เป็น 3rd-party แต่เท่าที่ลองดูแล้ว GHUnit จะมีส่วนแสดงผลดีกว่า SenTesting มาก

ซึ่งในตอนนี้จะพูดถึงการติดตั้งและใช้งานเบื้องต้นของ GHUnit เท่านั้นนะครับ ยังไม่ลงรายละเอียดการใช้งานมาก เนื่องจากการเขียน Test Case นั้นสามารถศึกษาได้ทั่วไปครับ

  • ก่อนอื่นต้องเริ่มสร้างโปรเจคหลักขึ้นมาก่อน โดยในที่นี้ตั้งชื่อว่า Gyro จะเป็นโปรเจคแบบไหนก็ได้ครับแล้วแต่ชอบ
  • หลังจากนั้นสร้าง Target เพื่อใช้ทดสอบโปรเจคก่อนหน้านี้ ซึ่งถ้าให้ดีที่สุดจะอยู่ในรูปแบบ <ชื่อโปรเจคที่ต้องการทดสอบ>Tests ตัวอย่างเช่นในกรณีนี้จะเป็น GyroTests เพราะนอกจากจะสื่อความหมายแล้ว Xcode จะนำไปกำหนดค่าต่างๆ ให้อัตโนมัติอีกด้วย โดยขั้นตอนการสร้าง Test Project นั้นเริ่มต้นด้วยการสร้าง Target ขึ้นใหม่ใน Project วิธีการคือให้เลือกที่ชื่อโปรเจคด้านบน จะเห็นปุ่ม “Add Target” ด้านล่าง จากนั้นจะมีหน้าต่างคล้ายกับหน้าสร้างโปรเจคใหม่ขึ้นมา ควรเลือก Empty Project เพราะจะแก้ไขน้อยมาก ในที่นี้ผมตั้งชื่อว่า GyroTests ครับ
  • เมื่อทำด้านบนเสร็จจะมี GyroTests เพิ่มเข้ามาใต้หัวข้อ TARGETS อีก 1 Target ถัดมาคือเพิ่มเฟรมเวิร์ค GHUnit เข้ามาโดยกดที่เครื่องหมาย “+” ในหัวข้อ Link Binary With Libraries (เลือกหัวข้อ Build Phases ด้านบน, จากนั้นเลือกลูกศรสามเหลี่ยมด้านหน้าหัวข้อ Link Binary With Libraries) จากนั้นจะมีหน้าต่างถามแสดงรายการ Framework ทั้งหมดที่ Xcode รู้จัก แต่เนื่องจาก GHUnit เป็น Framework ภายนอกจึงต้องเลือกปุ่ม “Add Other…” เพื่อระบุตำแหน่งที่เก็บ GHUnit ไว้ (หากโคลนมาจาก github จะอยู่ที่ gh-unit/Examples/MyTestable-iOS/GHUnitIOS.framework, หรือดาวน์โหลด zip ไฟล์ จาก github.com จะได้ โฟลเดอร์ GHUnitIOS.framework ที่สามารถเพิ่มเข้าไปยัง Xcode ได้ทันที) ซึ่งเมื่อทำเสร็จเรียบร้อยแล้วจะเห็นไฟล์ชื่อ GHUnitIOS.framework เพิ่มเข้ามาในโปรเจค ด้านบนสุด
  • Continue reading

MBP

How to force eject a stuck cd/dvd in Macs

เนื่องจากซ่อมเครื่อง iMac แล้วแผ่นมัน Snow Leopard ที่ซื้อมามันติดอยู่ในเครื่องแล้วเครื่องเจ้ากรรมมันก็บูตไม่ได้แล้วด้วย สุดท้ายเลยนั่งหาข้อมูลเพื่อดึงแผ่นออก ซึ่งวิธีการก็ไม่ได้มีอะไรพิศดาร แค่ Interface มันเป็น Slot Load แค่นั้น

ก่อนอื่นเตรียมกระดาษ A4 1 แผ่น พับให้ขนาดเท่ากับปุ่ม delete บนเครื่อง รีดให้แบนพอประมาณ เนื่องจากต้องการความแข็งสักหน่อย ทำไมต้องใช้กระดาษก็เพราะถ้าใช้แผ่นพลาสติกหรือวัสดุอื่นอาจจะเข้าไปโดนชิ้นส่วนด้านในเสียหายครับ อีกอย่างกระดาษมีปัญหาเรื่องไฟฟ้าสถิตน้อยมาก

จากนั้นก็เอาแผ่นกระดาษที่พับแล้วแหย่เข้าไปในด้านขวาสุดฝั่งตรงข้ามกับช่องทำหรับล็อคเครื่อง (Kensington Security Slot) แหย่เข้าไปสัก 1.5 นิ้วครับจากนั้นจะได้ยินเสียงที่เครื่องกำลังจะดันแผ่นออกที่รอคอยครับ

ถ้าเครื่องปิดอยู่ก็เปิดซะก่อน เนื่องจากเป็น slot-load เลยต้องใช้กระแสไฟฟ้าสำหรับดันแผ่นออกมาด้วยครับ

eclipse configurations for OpenCV in Mac OS X 10.7

บันทึกไว้กันลืม เพราะพึ่งเคยใช้ CDT (C/C++ Development Tooling) บน eclipse แล้วยิ่ง C/C++ นี่มากสุดก็แค่คำนวณ Arithmetics ธรรมดา แต่ช่วงนี้ต้องเอา C/C++ มาใช้งานในเชิงคำนวณหนักๆ อย่างเช่น OpenCV ด้วยแล้วก็กระอัดเลือดเหมือนกัน ส่วนปัญหาที่เจอคือทุกครั้งที่คอมไฟล์จะเจอข้อความด้านล่าง ทั้งๆ ที่ก็กำหนดทุกอย่างไว้อย่างที่ฝรั่งส่วนใหญ่บอกแล้ว

ld: symbol(s) not found for architecture x86_64

ซึ่งเท่าที่หาดูเป็นเพราะสถาปัตยกรรมของ CPU ที่ใช้อยู่ ตอนแรกยังคิดว่าเป็นเพราะ OS ที่ทำงานแบบ 64-bit mode เลยหาทางทุกวิธีที่จะเปลี่ยนให้ 10.7 ทำงานในแบบ 32-bit mode สุดท้ายเลยพบว่า ต้องใช้ -arch เพื่อระบุ architecture ที่ต้องการ ซึ่งค่าที่เป็นไปได้คือ i386, x86_64, ppc, ppc64 ซึ่งค่าที่จะใช้เพื่อแก้ปัญหาด้านบนคือ x86_64 เนื่องจาก OS X 10.7 นั้นทำงานในแบบ 64-bit (x86_64) โดย default (ย่อหน้านี้อาจจะดูมืนๆ เมาๆ หน่อย เพราะยังเข้าใจแบบนี้อยู่) ดังนั้นจึงต้องระบุค่าเพิ่มเข้าในช่วงคอมไฟล์เป็น

-arch x86_64

Continue reading