Monthly Archives: November 2012

ขี้เกียจเขียน For loop

ไม่นานมานี้เพิ่งรู้สึกตัวว่า “เฮ้ย เราไม่ได้เขียนโปรแกรมโดยใช้ For loop มาเป็นปีแล้วมั้ง”

สาเหตุเกิดมาจากว่าภาษาเขียนโปรแกรมที่ยุ่งๆ ด้วยอยู่ในรอบปีที่ผ่านมานี้ มีไลบราลีสำหรับการจัดการ collection ที่ค่อนข้างอำนวยความสะดวกให้อย่างมาก อย่างเช่น

  • Enumerable ของ Ruby
  • Sequences ของ Clojure
  • Iteration methods ของ Javascript (ที่ก่อนหน้านี้ไม่รู้ว่ามีพวกนี้ build-in ใน Javascript แล้วก็ใช้ underscore.js มาโดยตลอด)
  • List Comprehensions ของ CoffeeScript (มี reduce ให้ใช้ด้วยนะเออ ตอนแรกหาใน หน้า document หลักแล้วไม่เห็น)

ตอนนี้ตัวผม ถ้าต้องภาษาเขียนโปรแกรมด้วยภาษาใดๆ ที่มีไลบราลีเหล่านี้บริการไว้ให้ ก็จะเลือกใช้ไลบราลีเหล่านี้ก่อน For loop เสมอด้วยเหตุผล คือ

  • โค้ดสั้นลง
  • โค้ดอ่านได้เข้าใจง่ายขึ้น
  • ลดความผิดพลาดในการเขียนโปรแกรม เช่น การนับจุดสิ้นสุดของ i++
  • ทำงานกับ immutable data structure ได้ง่าย

เราอาจจะเคยพบปัญหาที่บางครั้งการพยายามเขียนโค้ดให้สั้นจนเกิดไป ทำให้โปรแกรมของเราอ่านยากขึ้น แต่ในกรณีนี้กลับตรงกันข้ามครับ การใช้ไลบราลีจัดการ collection นี้ทำให้เราเขียน code สั้นลงแต่อ่านง่ายขึ้นด้วย เพราะเราเพียงแค่บอกว่าเรา อยากได้อะไร บนเงื่อนไขอะไร (declarative programming) แทนที่จะต้องบอกขั้นตอนการทำงาน (imperative programming) เหมือนกับการเขียนโปรแกรมด้วย For loop ดังตัวอย่างการเลือกแต่เลขคู่ ในภาษา​ Javascript แบบนี้ครับ

var x = [1,2,3,4];
var y = [];
for (i=0; i < x.length; i++) { if (x[i] % 2 === 0) y.push(x[i]); }
console.log(y); //=> [2, 4]
var y = [1,2,3,4].filter(function(e) { return e % 2 === 0; });
console.log(y); //=> [2, 4]

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

ฟีเจอร์ใหม่ของ Ruby 2.0 ตอนที่ 1 – Refinements

วันที่ 24 กุมภาพันธ์ 2555 จะเป็นวันครบรอบ 20 ปีของภาษา Ruby และเป็นวันกำหนดการปล่อยเวอร์ชั่น 2.0 ตัวเต็มอีกด้วย ฟีเจอร์ใหม่ใน 2.0 มีอะไรบ้าง เอามาเล่าให้ฟังกันครับ

Refinements

[ต้องบอกไว้ก่อนว่า Refinements นี้ หากเจอ bug มากๆ ก็ยังอาจจะถูกถอดออกจากเวอร์ชั่น 2.0 ได้อยู่นะครับ]

Refinements เป็นฟีเจอร์ที่ถูกเพิ่มเข้ามาเพื่อทำให้เราทำ Monkey patching กันได้อย่างปลอดภัยมากขึ้นครับ

สำหรับคนที่ไม่รู้จัก Monkey patching เป็นฟีเจอร์หนึ่งของ Ruby ที่อนุญาตให้เราเข้าไปแก้ไขหรือเพิ่มเติมเนื้อหาของ class ใดๆ ก็ได้ที่ได้ถูกประกาศไว้แล้ว เช่นที่ Rails ได้ทำการ monkey patch Fixnum ซึ่งเป็น class ของตัวเลข 1,2,3,… ใน Ruby เพื่อให้เราสามารถเรียกใช้คำสั่งแบบ 2.days.ago ที่จะคืนค่าเป็นเวลาเมื่อ 2 วันที่แล้วได้

ปัญหาของเจ้า Monkey patching นี่คือ เมื่อเราได้มีการ load ไฟล์ที่มีการประกาศเจ้า Monkey patch แล้ว ทุกๆ ที่ใน code เราจะได้รับผลกระทบหมด ทำให้อาจเกิดปัญหาอย่างเช่น การตั้งชื่อ method ซ้ำซ้อนกันแล้วถูกทับกัน เกิดเป็น bug ที่สืบเสาะหายากมากๆ ได้ Refinements จึงเข้ามามีบทบาทในการจำกัดขอบเขตของการ monkey patch ดังตัวอย่างนี้ครับ

Module Insane
  refine Fixnum
    def +(other)
      self
    end
  end
  p 1 + 2  #=> 1
end
p 1 + 2  #=> 3

การ refine ไม่ได้ถูกจำกัดอยู่เพียงแค่ใน module ครับ เรายังสามารถนำไปใช้ที่อื่นได้ ด้วยคำสั่ง using แบบนี้ครับ

def use_refinements
  using Insane
  2 + 3  #=> 2
end

คำสั่ง using นี้สามารถใช้ได้ทุกที่เลยครับไม่ได้จำกัดแค่เฉพาะภายใน method อย่างในตัวอย่าง เราสามารถ using ใน class หรือ module อื่นๆ ได้หมด

สำหรับ Refinements มีเพียงเท่านี้ครับ ฟีเจอร์อื่นๆ จะตามมาในวันหลัง สำหรับใครที่สนใจ ลองเล่นเวอร์ชั่น preview กันได้แล้ววันนี้ โดยใครที่ใช้ rvm ก็ rvm install 2.0.0-preview1 กันได้เลยครับ สำหรับคนที่ใช้ OSX แล้วมีปัญหาการติดตั้งเวอร์ชั่น 2.0 ลองทำตา gist นี้ดูครับ Installing Ruby 2.0.0-preview1 with RVM on OS X

อ้างอิง

Node.js Knockout 2012

เสาร์อาทิตย์ที่ผ่านมาได้มีโอกาสร่วมกิจกรรม ​Node.js Knockout ซึ่งเป็นการแข่งขันเขียนโปรแกรมด้วย Node.js ในเวลา 48 ชั่วโมงพร้อมกันทั่วโลก

ทีมของผมมีด้วยกัน 3 คน คือ ผม พี่ @llun และ @ac_roca โดยใช้ชื่อทีมว่า Vikings เพราะตอนแรกสมาชิกในทีมจะเป็นคนจาก Viki ทั้งหมด แต่มี 2 คนถอนตัวออกไป ได้พี่ @llun เข้ามาเป็นกำลังสำคัญแทน

ผลงานของเราชื่อว่า Markeo (กว่าจะได้ชื่อนี้มาคิดกันเกือบครึ่งชั่วโมง) เป็นเกมส์จำลองการลงทุน โดยมีสิ่งที่ให้ลงทุนคือ Youtube video และมูลค่าของ video คือ จำนวน page view ครับ

เทคโนโลยีหลักๆ ที่เราใช้ ก็คือแน่นอน Node.js ที่ทางผู้จัดได้เตรียมเซอร์เวอร์ให้เราใช้แล้วบน Nodejitsu CoffeeScript Express.js Twitter Bootstrap jQuery Mongoose และ MongoDB ครับ ตัวผมเองมีประสบการณ์กับ Node.js น้อยมาก ก็ได้แต่ตามๆ ถามๆ 2 คนนั้นเป็นหลักแหละครับ

สำหรับ code ของโปรเจ็คนี้ผมทำการ fork มาจาก repo ที่ทางผู้จัดมีให้ มาไว้ที่ account Github ตัวเอง แล้วครับ ใครอยากดูอะไรก็เชิญตามอัธยาศัยครับ

เราใช้เวลากันประมาณ 19 ชั่วโมง วันแรก 10 ชั่วโมงใช้ในการวางแผน เตรียม development environment และทำ flow ทั้งหมดของเกมส์ ส่วนวันที่ 2 เราตกแต่ง UI และเก็บรายละเอียด และที่สำคัญ ทำวิดีโออธิบายโปรเจ็คครับ

ที่บอกว่ามันสำคัญ เพราะทางผู้จัดบอกว่าเป็นสิ่งที่ require สำหรับกรรมการหลักซึ่งมีสัดส่วนในการให้คะแนนถึง 40% และทางเราไม่มีใครเคยทำวิดีโอเลยและออกจะขี้อายกันทั้งนั้น เราใช้ Google Hangout OnAir ในการบันทึก โดยใช้เวลาทั้งหมด 1 ชั่วโมง ผลเลยออกมาเป็นสำเนียงกะเหรี่ยงและตะกุกตะกักแบบนี้ Markeo Introduction ผมขอสงวนสิทธิ์ไม่บอกนะครับว่าเป็นเสียงใคร 😀

ทางเราไม่ได้คาดหวังจะได้รางวัลอะไรจากงานนี้ตั้งแต่ต้น เพราะเชื่อว่ามีคนเก่งๆ และเตรียมตัวมาดีๆ อีกมาก และพอยิ่งได้เห็นผลงานของทีมอื่นๆ แล้วก็เป็นไปตามที่คิดครับ งานกราฟฟิกดีไซน์ห่างกันคนละชั้นเลย ใครสนใจลองไปดูผลงานของทีมอื่นๆ ได้ที่นี่ http://nodeknockout.com/entries ใครกำลังหาไอเดียทำโปรเจ็คอะไรอยู่ลองไปดูได้ครับ อาจจะได้ไอเดียเจ๋งๆ ไปทำอะไรเล่นกัน

งานนี้ต้อง gracias a @ac_roca และขอบคุณพี่ @llun มากครับที่ให้ผมได้เกาะทำอะไรสนุกๆ และเรียนรู้ Node.js และ environment รอบๆ อย่างรวดเร็วแบบนี้

ปล. เสร็จงานแล้วก็เหนื่อยไม่ใช่น้อยครับ วันหยุดนี่เป็นสิ่งที่จำเป็นสำหรับโปรแกรมเมอร์อย่างผมจริงๆ