Opendream ได้ Notice จาก web site ชื่อดัง
> ผมคงไม่สามารถร่วมงานกับ OD ที่สนิทกับ Roofimon และ Pphetra
> ได้อีกแล้วน่ะครับ สองคนนี้เกรียนเกินไป
>
> ผมไม่มีปัญหาอะไรกับ OD นะครับ และเคารพในการตัดสินใจของ OD
> ที่จะร่วมงานกับสาวกจาวาทั้งสอง (ว่าจะมีประโยชน์กับ OD เอง)
> แต่ Blognone คงจะไม่สามารถเอื้อประโยชน์กับ OD
> ที่มีสองคนนี้อยู่ร่วมงานด้วยได้อีกต่อไปครับ
> ทั้งในแง่การโพสต์รับสมัครงาน และกิจกรรมอื่นๆ ในอนาคต
>
> นอกจากนี้ งานส่วนตัวในอนาคตของผมก็คงจะไม่ร่วมงานที่มี OD
> เป็นพาร์ทเนอร์อีกเช่นกัน ไม่ว่าจะเป็น CC หรืออื่นๆ นะครับ
กลุ่ม CC ก็ได้กับเขาด้วย
> เรียนทุกท่าน
> ผมขอถอนตัวจากทีม CC Thailand ครับ ด้วยเหตุผลว่า CC Thailand มี
> OpenDream เป็นพาร์ทเนอร์ และผมมีนโยบายส่วนตัวที่จะไม่ทำงานร่วมกับ OD
> ซึ่งผมมีปัญหากับพนักงาน-สมาชิกบางคนของ OD ครับ
> (ไม่ได้มีปัญหาอะไรกับคุณเก่งนะครับ แต่เนื่องจากตัวองค์กร OD
> มีความสัมพันธ์กับพนักงานเหล่านี้ ซึ่งเคยว่าร้ายผม
> ก็คงต้องขอถอนตัวครับ)
> สุดท้ายขอบคุณทุกท่านที่ช่วยผลักดัน CC Thai
> ให้ประสบความสำเร็จขึ้นมาได้ครับ และอวยพรให้ก้าวหน้าต่อไป
คาดการณ์ว่าในอนาคต ถ้าท่านฯยังไม่หายแค้น
Opendream คงมีโอกาสโดนข่าวปล่อยเล่นงานแน่ๆ #สื่อเท่านั้นที่ครองโลก
Saturday, May 14, 2011
Wednesday, February 02, 2011
git - อยาก commit รวมกับ commit ก่อนหน้านั้น
เรื่องมีอยู่ว่า หลังจากที่ผม commit code ไปเป็นชุด (แก้ feature A แต่พบว่า feature B มี bug ด้วย ก็เลยเกิด commit ไล่ๆกัน)
แล้วเกิดพบว่า ลืม commit file ไปหนึ่ง file
แต่อยากให้ commit นี้ไปรวมอยู่ใน commit ก่อนหน้านั้น
กรณีที่เป็น case พึ่ง commit ไปหยกๆ เราก็สามารถใช้ commit --amend เข้ามาช่วยได้
แต่ถ้าเป็นกรณีที่มี commit อื่นๆมาคั่นหล่ะ
Note: ใช้ได้กับกรณีที่ยังไม่ push ขึ้น repository เท่านั้น
พระเอกของเรื่องนี้ก็คือ
ขั้นตอนก็คือ
เนื่องจากเรามี code ที่ต้องการแก้ไข ค้างอยู่ ให้ทำการ stash เก็บไว้ก่อน
จากนั้นก็สั่ง rebase โดยกำหนด commit id ตัวก่อนหน้าตัวที่เราจะแก้
เลือกเปลี่ยน commit ที่เป็นเป้าหมายในการ amend ให้เป็น 'edit'
จากนั้นก็สั่ง
แล้วก็เลือก commit --amend เข้าไป
สุดท้ายก็สั่ง
แล้วเกิดพบว่า ลืม commit file ไปหนึ่ง file
แต่อยากให้ commit นี้ไปรวมอยู่ใน commit ก่อนหน้านั้น
กรณีที่เป็น case พึ่ง commit ไปหยกๆ เราก็สามารถใช้ commit --amend เข้ามาช่วยได้
แต่ถ้าเป็นกรณีที่มี commit อื่นๆมาคั่นหล่ะ
![]() |
| From pphetra |
Note: ใช้ได้กับกรณีที่ยังไม่ push ขึ้น repository เท่านั้น
พระเอกของเรื่องนี้ก็คือ
git rebase --interactionขั้นตอนก็คือ
เนื่องจากเรามี code ที่ต้องการแก้ไข ค้างอยู่ ให้ทำการ stash เก็บไว้ก่อน
$ git stash
Saved working directory and index state WIP on (no branch): b1b2bd6 fix bug: บางครั้งก็กด zoom ผลลัพท์จากการ serach ได้ บางครั้งก็ไม่ได้
HEAD is now at b1b2bd6 fix bug: บางครั้งก็กด zoom ผลลัพท์จากการ serach ได้ บางครั้งก็ไม่ได้
จากนั้นก็สั่ง rebase โดยกำหนด commit id ตัวก่อนหน้าตัวที่เราจะแก้
$ git rebase -i d1b9dc72a4a8f57b1dcb43c704494d8fcb639fd2
pick 516712b ERP-1807 implement login panel.
pick 38d8bda fix bug: duplicate primary key constraint 's name.
pick d316ecd fix bug: บางครั้งก็กด zoom ผลลัพท์จากการ serach ได้ บางครั้งก็ไม่ได้
# Rebase d1b9dc7..d316ecd onto d1b9dc7
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
เลือกเปลี่ยน commit ที่เป็นเป้าหมายในการ amend ให้เป็น 'edit'
จากนั้นก็สั่ง
git stash popแล้วก็เลือก commit --amend เข้าไป
สุดท้ายก็สั่ง
git rebase --continue
Related link from Roti
Labels:
git
Monday, November 22, 2010
Wednesday, November 10, 2010
ทบทวน drama เมื่อ 3 ปีก่อน
ขออนุญาติน้อง Deans4j นะ ที่ quote คำพูดบางอันมาออก
เพราะพี่ว่า "ความจริงมันเปิดเผยแล้ว ทุกคนเข้าใจแล้วว่าอะไรเป็นอะไร"
คุณ bow แกเขียน benchmark เทียบ Java, Python, Ruby
บังเอิญคุณ bow แก้มี domain ที่ใช้อยู่ในเรื่อง "scientific computation"
แล้วมีประสบการณ์ java ไม่พอที่จะ optimize
เจ้า deans4j ก็เลยเข้าไปจุดระเบิด
http://www.blognone.com/node/4385
มีเรื่องมีราว
เจ้าน้อง deans ก็ไปตั้งกระทู้ไว้ใน blog ตัวเอง
http://deans4j.wordpress.com/2007/04/12/against-idiot/
สมัยนั้นผมเป็นแฟน blognone และ markpeak
เห็นเจ้า deans4j aggressive ขนาดนั้น ทนไม่ได้ก็เลยไป comment ไว้แบบนี้
จากนั้น deans กับผม ก็เขียนจดหมายคุยกันหลังไมค์
นี่คือจดหมายที่ผมตอบเขา
อันนี้คือบางส่วนที่เขา ตอบกลับมา
เมื่อก่อนผมไม่เข้าใจที่ deans พูดหรอกนะ แต่ปัจจุบัน พฤติกรรมของ markpeak มันยืนยันตามคำพูดน้อง deans ทุกอย่าง
ตัดภาพกลับมาปัจจุบัน
หลังจากเรามี party "java เกรียน day"
ทุกอย่างที่ผ่านมา 3 ปี ก็ชัดเจนแล้วสำหรับผม
สุดท้ายผมก็ทำในสิ่งที่ผมแนะนำคนอื่นไม่ได้
อารมณ์ร้ายๆ ก็มามีผลต่อชิวิตผม
หวังว่าสุดท้าย ตีนผมคงจะไม่ปะทะปากใครนะ
เพราะพี่ว่า "ความจริงมันเปิดเผยแล้ว ทุกคนเข้าใจแล้วว่าอะไรเป็นอะไร"
คุณ bow แกเขียน benchmark เทียบ Java, Python, Ruby
บังเอิญคุณ bow แก้มี domain ที่ใช้อยู่ในเรื่อง "scientific computation"
แล้วมีประสบการณ์ java ไม่พอที่จะ optimize
เจ้า deans4j ก็เลยเข้าไปจุดระเบิด
http://www.blognone.com/node/4385
มีเรื่องมีราว
เจ้าน้อง deans ก็ไปตั้งกระทู้ไว้ใน blog ตัวเอง
http://deans4j.wordpress.com/2007/04/12/against-idiot/
สมัยนั้นผมเป็นแฟน blognone และ markpeak
เห็นเจ้า deans4j aggressive ขนาดนั้น ทนไม่ได้ก็เลยไป comment ไว้แบบนี้
Dean4j, คุณมีความคิดด้านลบอยู่เต็มตัวเลยนะ
ผมลองเล่าเรื่องผมให้ฟังแล้วกัน
มีอยุ่ช่วงที่ผมรู้สึกว่า “คนเก่งๆหายไปไหนหมด”
มีอยู่วันหนึ่งมีคน post ในพันธ์ทิพย์ว่า
“ต้องการหาคนเป็น database ช่วยกันทำ project สนุกๆกัน”
ผมก็เลย mail เล่าไปว่าเคยทำอะไร อย่างไร
ปรากฎว่า mail ที่เขาตอบกลับมา นั้นทำให้ผมช็อค ไปเหมือนกัน
เขาบอกว่า เขาเกลียดคนชนิดผมมากเลย คนที่ภูมิใจในตัวเองสูง
ประโยคนั้นเป็นประโยคที่ดีมากเลย
ทำให้ต้องกลับมาทบทวนตัวเองใหม่
ซึ่งจากการทบทวนแล้ว ผมก็พบว่า สิ่งที่ผมเล่าอย่างธรรมดาๆนั้น
สำหรับคนอื่นแล้วมันดู arrogance เกินไป
ทำให้ผมต้องระมัดระวัง
วิธีการเขียนหรือเรื่องต่างๆ ที่อาจทำให้คนอื่นเข้าใจผิดในเจตนา
แต่ก็ไม่วายผิดผลาดอีก
อย่างเมื่อปลายปีก่อน apple เขาจัดอบรมฟรี
ผมก็ไปกับเขาด้วย
ก็ไปเจอพี่คนหนึ่ง อัธยาศัยดีมาก
กลับมาก็ mail คุยกัน
พี่เขาก็ถามว่า ปัจจุบัน ทำอะไรอยู่บ้าง
ผมก็เขียนเล่าเรื่องอย่างยาวเลย
ผลเป็นอย่างไรรุ้ไหม
พี่เขาเลิกติดต่อผมเลย
ซึ่งผมเดาได้ไม่ยากเลยว่า
มันต้องเกิดจากเนื้อความในจดหมาย
ซึ่งมันน่าจะมีส่วนผสมของความ Proud มากไปหน่อย
ทำให้คนอ่านรู้สึกว่าเราเป็นคน arrogance
บางทีความอัดอั้นตันใจของเรา, ความภูมิใจที่ถุกเก็บกดของเรา
ความรู้สึกไม่เต็มของเรา, ความรู้สึกไม่พอใจต่างๆ
มันเผลอสะท้อนออกไปทางสิ่งที่เราเขียน
โดยเราก็ไม่รู้ตัว
สำหรับ post ที่คุณตอบในบทความ “BowDerKliene”
ถ้ามองในแง่ fact แล้ว. เป็นการตอบที่ดีมาก
แต่ถ้ามองในแง่ของท่าทีแล้ว
มันมีน้ำหนักของการดูถูก และการท้าตีท้าต่อยมากไปหน่อย
ค่อนข้าง arrogance สูง
ส่วนเรื่อง FUD
อย่างไง FUD ก็เป็นสิ่งที่หลีกเลี่ยงไม่ได้
ตราบใดที่ คน ยังเป็น คน อยุ่
การชักจูงคนให้เห็นอีกมุม ไม่สามารถใช้วิธีปะทะได้หรอก
มันยิ่งทำให้เขาปฏิเสธมากขึ้นเท่านั้น
จากนั้น deans กับผม ก็เขียนจดหมายคุยกันหลังไมค์
นี่คือจดหมายที่ผมตอบเขา
ผมกับคุณมีส่วนหนึ่งที่เหมือนกัน ก็คือ เรามีความโกรธเป็นเจ้าเรือน
เรามีความคาดหวังสูงกับสิ่งรอบข้าง
ซึ่งมันมักจะทำให้เราผิดหวังกับโมโหอยู่บ่อยๆ
อย่าง mk บางทีตอนแรกคุณก็อาจจะรู้สึกว่า
เฮ้ย คนนี้ น่าจะเป็นเพื่อนกับเราได้ เขามีเป้าหมายบางอย่างที่ตรงกับเรา
แต่สุดท้ายคุณก็เริ่มพบว่า มันมีบางสิ่งที่มันไม่ตรงกันนัก
ความคิดเห็น อุดมการณ์ การแสดงออก
ส่วนเรื่องที่คุณผิดหวังกับวิธีคิดของเขา
ผมขอให้มองเขาเป็นคนธรรมดาเหมือนเรานี่แหล่ะ
มีการก้าวที่ผิดพลาด มี double standard (ทุกคนเป็นเหมือนกันหมด)
มีความขัดแย้งในสิ่งที่เชื่อกับสิ่งที่ทำ
สิ่งที่เขากำลังทำอยู่ ก็คือการเรียนรู้ชีิวิตของเขา
พูดง่ายนะแต่ทำยาก
อย่างผม สมัยก่อนฟังเพลงคาราบาว ชอบมาก
แต่พอรู้ว่าชีวิตนักร้อง กับ เนื้อหาเพลงของเขา มันไม่ไปด้วยกัน
ก็เลยเลิกฟัง ทำใจไม่ได้
พวกอาการนี้ เวลาเกิดขึ้นแล้วมันแก้ไขให้กลับมาเหมือนเดิมยาก
ปัจจุบัน ก็เลยต้องหาวิธีสกัด ไม่ให้เกิดความคาดหวังขึ้นมา
จะได้ไม่ต้องผิดผวัง
การปะทะเกิดขึ้นได้
แต่อย่าให้อารมณ์ร้ายๆ มามีผลต่อชีวิตเรา
อันนี้คือบางส่วนที่เขา ตอบกลับมา
ประเด็นคือสิ่งที่ mk ปฏิบัติต่อผมก็น่ารังเกียจจริงๆ แล้วเต็มไปด้วยอคติ ความต้องการเอาชนะ เค้ามีปัญหาอะไรกับผม เค้าไม่เคยคิดจะเคลียร์ ผมเคยพยายามที่จะเคลียร์หลังไมค์ แต่เค้าก็ได้แต่หนีไป แถมมีแต่คำพูดขู่ และดูถูกผมซะยิ่งกว่า
...
ผมอยากให้พี่รับรู้ไว้ว่าไม่ใช่ผมที่เริ่มก่อน แต่เป็นเค้าที่เล่นนอกเกมสารพัดจนทำให้ผมเก็บอาการไม่อยู่ เค้าพยายาม discredit ผมหลายทาง เค้าเลือกที่จะประณามผมในที่สาธารณะ space ตัวเอง ทั้งๆ ที่ผมพยายามจะเคลียร์กับเค้าในที่ส่วนตัว จนที่สุดมันลงเอยอย่างนี้ผมจึงค่อยออกมา
เมื่อก่อนผมไม่เข้าใจที่ deans พูดหรอกนะ แต่ปัจจุบัน พฤติกรรมของ markpeak มันยืนยันตามคำพูดน้อง deans ทุกอย่าง
ตัดภาพกลับมาปัจจุบัน
หลังจากเรามี party "java เกรียน day"
ทุกอย่างที่ผ่านมา 3 ปี ก็ชัดเจนแล้วสำหรับผม
สุดท้ายผมก็ทำในสิ่งที่ผมแนะนำคนอื่นไม่ได้
อารมณ์ร้ายๆ ก็มามีผลต่อชิวิตผม
ศาสดาเจ็บใจมาก ตามมาเหน็บผมอีกแล้ว, พวกเกรียนใน net นี่ คงรู้สึกว่าพูดอย่างไรก็ได้เพราะใน net มันไกลตีน หรือเราควรจะลดระยะดี
หวังว่าสุดท้าย ตีนผมคงจะไม่ปะทะปากใครนะ
Related link from Roti
Labels:
จาวาเร็วส์
Tuesday, November 09, 2010
funciton form ใน javascript
หลังๆมา style การเขียน javascript ของผมมักจะตกไปอยู่ใน form แบบนี้
(โลกของ javascript ไม่มี class, ทุกอย่างเป็น object)
หลังๆ javascript code ที่เขียนมันเริ่มใหญ่ (ถึงตอนนี้ก็ราวๆ 70000 บรรทัดแล้ว)
เวลา debug ก็เริ่มงงๆว่า ใครมันเป้นคนเรียก function ที่กูเขียนวะ
ใน webkit มันมี function ที่ชื่อ console.trace()
funciton นี้จะช่วย dump stacktrace ณ จุดที่เราใส่
ลองทดลองใส่ console.dump ใน code ข้างบน ก่อนตำแหน่ง alert
ผลลัพท์ที่ได้

:( ได้ anonymous ออกมาหมดเลย ตกลงก็เลยไม่รู้เลยว่าใครเรียก
แต่ทุกปัญหามีทางออก วิธีแก้ก็คือ ปรับรูป form การประกาศ javascript เสียใหม่ เปลี่ยนเป็น
ทดลอง run ใหม่

ทีนี้ก็ต้องเลือกแล้ว จะเอา form เยิ่นเย้อ หรือเอาแบบที่เวลาไล่ stacktrace แล้วมันไล่ง่าย
(โลกของ javascript ไม่มี class, ทุกอย่างเป็น object)
myService = {
sayHi: function(msg) {
this.output("-" + msg + "-");
},
output: function(msg) {
alert(msg);
}
}หลังๆ javascript code ที่เขียนมันเริ่มใหญ่ (ถึงตอนนี้ก็ราวๆ 70000 บรรทัดแล้ว)
เวลา debug ก็เริ่มงงๆว่า ใครมันเป้นคนเรียก function ที่กูเขียนวะ
ใน webkit มันมี function ที่ชื่อ console.trace()
funciton นี้จะช่วย dump stacktrace ณ จุดที่เราใส่
ลองทดลองใส่ console.dump ใน code ข้างบน ก่อนตำแหน่ง alert
ผลลัพท์ที่ได้

:( ได้ anonymous ออกมาหมดเลย ตกลงก็เลยไม่รู้เลยว่าใครเรียก
แต่ทุกปัญหามีทางออก วิธีแก้ก็คือ ปรับรูป form การประกาศ javascript เสียใหม่ เปลี่ยนเป็น
myService = {
sayHi: function sayHi(msg) {
this.output("-" + msg + "-");
},
output: function output(msg) {
console.trace();
alert(msg);
}
}ทดลอง run ใหม่

ทีนี้ก็ต้องเลือกแล้ว จะเอา form เยิ่นเย้อ หรือเอาแบบที่เวลาไล่ stacktrace แล้วมันไล่ง่าย
Related link from Roti
Labels:
javascript
Wednesday, October 27, 2010
ติดใจ repl ของ Clojure
ช่วงนี้ research หาลู่ทางรับงานจากอเมริกา
โจทย์ก็คือไป crawl ดึงข้อมูล จาก medicare.gov
ความยากอยู่ตรง site นั้นใช้ .net เขียนแบบ component based (stateful)
การจะได้ข้อมูลมา ต้องฝ่าด่านตอบคำถาม จำนวน 4-5 หน้าเข้าไปก่อน
ก็เลยต้องใช้ browser จริงๆเข้าไปดึงข้อมูล
หวยก็เลยออกมาที่ Selenium + WebDriver
แต่ครั้นจะเขียนด้วย java ก็ไม่สนุก
เขียนด้วย ruby/python ก็เคยเขียนแล้ว
ก็เลยเลือกใช้ Clojure
Lisp มันมีข้อดีอย่างหนึ่งก็คือ
มันมี REPL ทำให้เราสามารถเขียนโปรแกรมในลักษณะ incremental ได้
เขียนไป ทดลองไป ปรับแต่งไป
สภาพแวดล้อมที่เลือกใช้พัฒนาก็คือ
emacs + cake
ลองดูตัวอย่าง ตอนทดสอบได้ใน video นี้
(ดูช่วงต้นๆก็พอ, net/web มันช้า หลังๆหมดไปกับการรอมันโหลด
ใครว่า web ราชการไทยช้า web ราชการฝรั่งก็ช้าเหมือนกัน)

Updated: video upload ผ่านทาง blogger ได้ความละเอียดต่ำเหลือเกิน
ดูรูปประกอบแล้วกัน

ตัวอย่าง code ที่ใช้
โจทย์ก็คือไป crawl ดึงข้อมูล จาก medicare.gov
ความยากอยู่ตรง site นั้นใช้ .net เขียนแบบ component based (stateful)
การจะได้ข้อมูลมา ต้องฝ่าด่านตอบคำถาม จำนวน 4-5 หน้าเข้าไปก่อน
ก็เลยต้องใช้ browser จริงๆเข้าไปดึงข้อมูล
หวยก็เลยออกมาที่ Selenium + WebDriver
แต่ครั้นจะเขียนด้วย java ก็ไม่สนุก
เขียนด้วย ruby/python ก็เคยเขียนแล้ว
ก็เลยเลือกใช้ Clojure
Lisp มันมีข้อดีอย่างหนึ่งก็คือ
มันมี REPL ทำให้เราสามารถเขียนโปรแกรมในลักษณะ incremental ได้
เขียนไป ทดลองไป ปรับแต่งไป
สภาพแวดล้อมที่เลือกใช้พัฒนาก็คือ
emacs + cake
ลองดูตัวอย่าง ตอนทดสอบได้ใน video นี้
(ดูช่วงต้นๆก็พอ, net/web มันช้า หลังๆหมดไปกับการรอมันโหลด
ใครว่า web ราชการไทยช้า web ราชการฝรั่งก็ช้าเหมือนกัน)
Updated: video upload ผ่านทาง blogger ได้ความละเอียดต่ำเหลือเกิน
ดูรูปประกอบแล้วกัน

ตัวอย่าง code ที่ใช้
(defn send-key [by txt]
(let [elm (.findElement *driver* by)]
(.sendKeys elm (into-array [txt]))))
(defn click [by]
(let [elm (.findElement *driver* by)]
(.click elm)))
(defn init-queue []
(def *queue* (LinkedBlockingQueue.)))
(defn start-thread [driver func]
(.start
(Thread.
(fn []
(loop []
(let [code (.take *queue*)]
(binding [*driver* driver]
(func code)))
(recur))))))
(defn fetch [code]
(go "https://www.medicare.gov/find-a-plan/questions/home.aspx")
(send-key (by-css-selector "div#zip-code-field > input") code)
(click (by-css-selector "input[type=submit][alternatetext=\"Find Plans\"]")))
Related link from Roti
Labels:
clojure
Tuesday, October 26, 2010
เรียนรู้วิธีที่ ExtJS format date
ใน ExtJS เราใช้ function format ในการกำหนดรูปแบบการแสดงผลของ Date object
ลองดูตัวอย่าง
คำถามที่น่าสนใจก็คือ เขาใช้วิธีไหนในการ implement function นี้
ลองเปิดไล่ดู code ใน file src/util/Date.js
เริ่มจาก object ที่ชื่อ formatCodes
คำถามที่ตามมาก็คือ ทำไมถึงเก็บ code ฝั่งขวาเป็น String
ลองไล่จาก top down บ้าง, โดยย้อยกลับไปดู function format ว่า code ข้างในเป็นอย่างไร
จะเห็นว่า เมื่อได้รับ parameter เป็น format แล้ว, function มันจะพยายาม lookup หา function จากตาราง Date.formatFunctions ก่อน
ถ้าไม่เจอ ก็จะไปเรียก Date.createFormat เพื่อสร้าง function ให้ก่อน
ลองตามไปดู function createFormat บ้าง
code ที่เป็นพระเอกของเราก็คือ บรรทัดสุดท้าย
จะเห็นว่ามัน loop ไปตามแต่ละ character ที่อยู่ใน format string ที่เราส่งให้
จากนั้นก็ไปเอาไป lookup ตาราง formatCodes ที่เราเห็นข้างบน ได้ค่ามาก็จัดการ แปะให้กลายเป็น anonymous function
แล้วก็เก็บ cache ไว้ใน Date.formatFunctions
ลอง dump Date.formatFunctions มาดู
พอเห็น code แบบนี้แล้ว การเพิ่มวันที่ไทยเข้าไปเองก็ไม่ยากแล้ว
ลองดูตัวอย่าง
new Date().format("c")
"2010-10-26T08:35:30+07:00"
new Date().format("d/n/Y")
"26/10/2010"
คำถามที่น่าสนใจก็คือ เขาใช้วิธีไหนในการ implement function นี้
ลองเปิดไล่ดู code ใน file src/util/Date.js
เริ่มจาก object ที่ชื่อ formatCodes
formatCodes : {
d: "String.leftPad(this.getDate(), 2, '0')",
D: "Date.getShortDayName(this.getDay())", // get localised short day name
j: "this.getDate()",
l: "Date.dayNames[this.getDay()]",
N: "(this.getDay() ? this.getDay() : 7)",
S: "this.getSuffix()",
w: "this.getDay()",
z: "this.getDayOfYear()",
W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
F: "Date.monthNames[this.getMonth()]",
m: "String.leftPad(this.getMonth() + 1, 2, '0')",
M: "Date.getShortMonthName(this.getMonth())", // get localised short month name
n: "(this.getMonth() + 1)",
....
}คำถามที่ตามมาก็คือ ทำไมถึงเก็บ code ฝั่งขวาเป็น String
ลองไล่จาก top down บ้าง, โดยย้อยกลับไปดู function format ว่า code ข้างในเป็นอย่างไร
Date.prototype.format = Date.prototype.dateFormat;
dateFormat : function(format) {
if (Date.formatFunctions[format] == null) {
Date.createFormat(format);
}
return Date.formatFunctions[format].call(this);
},
จะเห็นว่า เมื่อได้รับ parameter เป็น format แล้ว, function มันจะพยายาม lookup หา function จากตาราง Date.formatFunctions ก่อน
ถ้าไม่เจอ ก็จะไปเรียก Date.createFormat เพื่อสร้าง function ให้ก่อน
ลองตามไปดู function createFormat บ้าง
code ที่เป็นพระเอกของเราก็คือ บรรทัดสุดท้าย
createFormat : function(format) {
var code = [],
special = false,
ch = '';
for (var i = 0; i < format.length; ++i) {
ch = format.charAt(i);
if (!special && ch == "\\") {
special = true;
} else if (special) {
special = false;
code.push("'" + String.escape(ch) + "'");
} else {
code.push(Date.getFormatCode(ch))
}
}
Date.formatFunctions[format] = new Function("return " + code.join('+'));
},
จะเห็นว่ามัน loop ไปตามแต่ละ character ที่อยู่ใน format string ที่เราส่งให้
จากนั้นก็ไปเอาไป lookup ตาราง formatCodes ที่เราเห็นข้างบน ได้ค่ามาก็จัดการ แปะให้กลายเป็น anonymous function
แล้วก็เก็บ cache ไว้ใน Date.formatFunctions
ลอง dump Date.formatFunctions มาดู
Date.formatFunctions["d/n/Y"]
function anonymous() { return String.leftPad(this.getDate(), 2, '0')+'/'+(this.getMonth() + 1)+'/'+this.getFullYear();
}
พอเห็น code แบบนี้แล้ว การเพิ่มวันที่ไทยเข้าไปเองก็ไม่ยากแล้ว
Related link from Roti
Labels:
extjs,
javascript
Subscribe to:
Posts (Atom)




