หามานาน
สมหวังสักที
Desktop Manager
Friday, March 10, 2006
Pattern การ implement Object ใน Prototype.js (1.4.0)
style ปกติที่เราใช้สร้าง javascript object
ก็คือการใช้ function
ตัวอย่าง
ซึ่งก็มีหลายคนออกมาชี้ว่า
วิธีนี้ ถ้าเรามี object จำนวนมาก
มันจะเปลือง memory นะ, เพราะ method dump
มันถูก declare ขึ้นมา 1 function ต่อ 1 object
ก็เลยมีการพลิกแพลงออกไปใช้ prototype
(เวลา javascript object ถูกเรียกใช้งาน มันจะมองหา attribute ภายใน
scope ของมันก่อน ถ้าไม่เจอก็จะค้นหาจาก object ที่ pointer prototype ชี้อยู่)
Prototype.js ก็เห็นดีเห็นงามกับแนวทางที่ 2 (อันนี้เป็นสาเหตุ ว่าทำไม library ถึงชื่อ prototype)
แต่ตบแต่ง style เสียใหม่
ได้หน้าตา การประกาศ object ออกมาแบบนี้
ซึ่งก็ดูดีขึ้นนะ (ถ้าเข้าใจว่ามันทำงานอย่างไร)
magic อยู่ที่ function
เมื่อเราเรียก
ตัวแปร Person จะชี้ไปยัง function ที่ return กลับออกมาจาก Class object
และเมื่อเราเรียก Person.new ก็จะเกิดการเรียกใช้ function ที่ชื่อ initialize
ซึ่งถูก declare ไว้ใน Person.prototype object
เมื่อมี object แล้วก็ต้องมีการ extend หรือ inheritance
ใครที่มาจากสาย java แล้วใช้ความคิดแบบ java เข้ามาจับ
รับรองว่าได้ปวดหัวกับการ debug แน่นอน
คำแนะนำที่ดี ก็คือ อย่า design แบบ deep hierachy tree เลย
พวก polymorphic หรือ overloading
ก็อย่าไปนึกถึง
แต่ถ้าอยากลองดู ลองอ่านอันนี้ดู Object Hierarchy and Inheritance in Javascript
ซึ่งดูเหมือนจะเป็น technique แบบเก่า
ถ้าอยากได้แบบใหม่ๆหน่อย ก็ลองอ่านนี่ดู
Javascript Inheritance
แต่ผมไม่ค่อยชอบ technique ที่เขาแนะนำเท่าไร
มันดูแปลกๆในส่วนของการ copyPrototype
ใน Prototype.js ก็มี method extend ให้ใช้เหมือนกัน
แต่ส่วนใหญ่จะใช้ในลักษณะของ Mixin แบบ ruby เสียมากกว่า
โดยการ design จะใช้วิธีเสริม function เข้าไปใน object ที่มีอยู่แล้ว
เช่น
ทำให้เราสามารถทำแบบนี้ได้
ก็คือการใช้ function
ตัวอย่าง
function Person(name, age) {
this.name = name;
this.age = age;
this.dump = function() {
return this.name + ", " + this.age;
}
}
var p = new Person("pann", 1);
ซึ่งก็มีหลายคนออกมาชี้ว่า
วิธีนี้ ถ้าเรามี object จำนวนมาก
มันจะเปลือง memory นะ, เพราะ method dump
มันถูก declare ขึ้นมา 1 function ต่อ 1 object
ก็เลยมีการพลิกแพลงออกไปใช้ prototype
(เวลา javascript object ถูกเรียกใช้งาน มันจะมองหา attribute ภายใน
scope ของมันก่อน ถ้าไม่เจอก็จะค้นหาจาก object ที่ pointer prototype ชี้อยู่)
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
dump: function() {
return this.name + ", " + this.age;
}
}
Prototype.js ก็เห็นดีเห็นงามกับแนวทางที่ 2 (อันนี้เป็นสาเหตุ ว่าทำไม library ถึงชื่อ prototype)
แต่ตบแต่ง style เสียใหม่
ได้หน้าตา การประกาศ object ออกมาแบบนี้
var Person = Class.create();
Person.prototype = {
initialize: function(name, age) {
this.name = name;
this.age = age;
},
dump: function() {
return this.name + ", " + this.age;
}
}
ซึ่งก็ดูดีขึ้นนะ (ถ้าเข้าใจว่ามันทำงานอย่างไร)
magic อยู่ที่ function
Class
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
เมื่อเราเรียก
var Person = Class.create()
ตัวแปร Person จะชี้ไปยัง function ที่ return กลับออกมาจาก Class object
และเมื่อเราเรียก Person.new ก็จะเกิดการเรียกใช้ function ที่ชื่อ initialize
ซึ่งถูก declare ไว้ใน Person.prototype object
เมื่อมี object แล้วก็ต้องมีการ extend หรือ inheritance
ใครที่มาจากสาย java แล้วใช้ความคิดแบบ java เข้ามาจับ
รับรองว่าได้ปวดหัวกับการ debug แน่นอน
คำแนะนำที่ดี ก็คือ อย่า design แบบ deep hierachy tree เลย
พวก polymorphic หรือ overloading
ก็อย่าไปนึกถึง
แต่ถ้าอยากลองดู ลองอ่านอันนี้ดู Object Hierarchy and Inheritance in Javascript
ซึ่งดูเหมือนจะเป็น technique แบบเก่า
ถ้าอยากได้แบบใหม่ๆหน่อย ก็ลองอ่านนี่ดู
Javascript Inheritance
แต่ผมไม่ค่อยชอบ technique ที่เขาแนะนำเท่าไร
มันดูแปลกๆในส่วนของการ copyPrototype
ใน Prototype.js ก็มี method extend ให้ใช้เหมือนกัน
แต่ส่วนใหญ่จะใช้ในลักษณะของ Mixin แบบ ruby เสียมากกว่า
โดยการ design จะใช้วิธีเสริม function เข้าไปใน object ที่มีอยู่แล้ว
เช่น
var Enumerable = {
...
findAll: function(iterator) {
var results = [];
this.each(function(value, index) {
if (iterator(value, index))
results.push(value);
});
return results;
},
...
}
Object.extend(Array.prototype, Enumerable);
ทำให้เราสามารถทำแบบนี้ได้
[1,2,3].findAll(function(value) {
return value > 1;
})
// => [2,3]
Related link from Roti
ลานนาจัง กับ ทักษิน
แถาบ้านมีคนญี่ปุ่นอยู่คนหนึ่ง ชื่อ ยูโกะจัง
ทำงานเป็น air hostage อยู่การบินไทย
ยูโกะมีลูกสาวคนหนึ่ง ชื่อ ลานนาจัง
(ชื่อไทยซะด้วย)
ตอนนี้ ลานนาจัง อายุได้ 7 เดือนแล้ว
กำลังน่ารักเลย
วันก่อนภรรยาผมเล่าให้ฟังว่า
ยูโกะจังบ่นให้ฟังว่า
Note: กรุณาอ่านออกเสียงแบบคนญี่ปุ่นพูดไทย
ทำงานเป็น air hostage อยู่การบินไทย
ยูโกะมีลูกสาวคนหนึ่ง ชื่อ ลานนาจัง
(ชื่อไทยซะด้วย)
ตอนนี้ ลานนาจัง อายุได้ 7 เดือนแล้ว
กำลังน่ารักเลย
วันก่อนภรรยาผมเล่าให้ฟังว่า
ยูโกะจังบ่นให้ฟังว่า
ลานนาจังเกิดวันเดียวกับทักษิน worry นะคะ..
โตขึ้นมาจะเป็นยังไง ...
money money หรือเปล่า, material girl...
Note: กรุณาอ่านออกเสียงแบบคนญี่ปุ่นพูดไทย
Related link from Roti
Form Object ใน Prototype.js (1.4.0)
หลังจากดู presentation A (Re)-Introduction to javaScript
ของคุณ Simon Willison จบแล้ว ก็เกิดความเข้าใจใหม่ๆขึ้นมาอีกมาก
เดิมผมจะมีปัญหากับการอ่าน javascript ที่เขียนแนว Object อยู่มาก
ที่เป็นแบบนี้ ก็เพราะ ผมเอาแนวคิดของ java (class-based) ไปตีความเจ้า javascript (Prototype-based)
ก็เลยเกิดอาการ มึนๆ งงๆ
แต่หลังจากเรียนรู้ ruby, lisp มาระยะหนึ่ง
ซึ่งช่วยขยายกรอบความคิดเกี่ยวกับเรื่อง programing language ขึ้นอีกเยอะ
ก็เลยทำให้หลังจากดู presentation ข้างบนจบ (slides ยาวมาก)
ก็เลยเกิดอาการ Satori เล็กๆขึ้นมา
ผลของ Satori ก็เลยทำให้เกิดความฮึกเหิม ย้อนกลับไปใล่ดู
source code ของ Prototype.js
โดยเลือกดูส่วนที่เกี่่ยวกับการจัดการ Form ก่อน
Object ของ Prototype ที่ใช้จัดการกับ form
ใช้ชื่อตรงตัวเลยว่า
ใน source code มีการประกาศไว้ดังนี้
method ประกอบด้วย
เห็นได้ว่า method ทั้งหมด มี require parameter
เป็น form element หรือ form name ทั้งสิ้น (รับได้ทั้ง 2 แบบ)
Helper object ที่
ใน Prototype มี Helper Function ที่ชื่อ
ซึ่งจริงๆแล้ว ก็คือ short-cut ของ Form.Element.getValue นี่เอง
ของคุณ Simon Willison จบแล้ว ก็เกิดความเข้าใจใหม่ๆขึ้นมาอีกมาก
เดิมผมจะมีปัญหากับการอ่าน javascript ที่เขียนแนว Object อยู่มาก
ที่เป็นแบบนี้ ก็เพราะ ผมเอาแนวคิดของ java (class-based) ไปตีความเจ้า javascript (Prototype-based)
ก็เลยเกิดอาการ มึนๆ งงๆ
แต่หลังจากเรียนรู้ ruby, lisp มาระยะหนึ่ง
ซึ่งช่วยขยายกรอบความคิดเกี่ยวกับเรื่อง programing language ขึ้นอีกเยอะ
ก็เลยทำให้หลังจากดู presentation ข้างบนจบ (slides ยาวมาก)
ก็เลยเกิดอาการ Satori เล็กๆขึ้นมา
ผลของ Satori ก็เลยทำให้เกิดความฮึกเหิม ย้อนกลับไปใล่ดู
source code ของ Prototype.js
โดยเลือกดูส่วนที่เกี่่ยวกับการจัดการ Form ก่อน
Object ของ Prototype ที่ใช้จัดการกับ form
ใช้ชื่อตรงตัวเลยว่า
Form
ใน source code มีการประกาศไว้ดังนี้
var Form = {
serialize: function(form) {
...
},
getElements: function(form) {
...
},
...
}
method ประกอบด้วย
- serialize
return string ที่ใช้ในการ submit form ผ่าน ajax
ตัวอย่างการใช้งาน
สมมติ html ดังนี้
<form id="myform" action="#">
<input name="input1" type="text" value="xxx"/>
<input type="checkbox" name="input3" checked="checked" />
<input name="input2" type="submit"/>
</form>
แล้วใช้คำสั่งForm.serialize
Form.serialize('myform'); // => input1=xxx&input3=on&input2= - getElements
รับ parameter เป็น form เหมือนกัน
ผลลัพท์ที่ได้คือ Array ของ Element ที่อยู่ใน form (เฉพาะพวกที่ใช้ input เช่น input, textarea, ...) - getInputs
ค้นหา Element ประเภทinput
โดย
รับ parameter เป็น form, ประเภทของinput
และ ชื่อของ element นัั้น
เช่น
Form.getInputs('myform', 'text', 'input1') - disable
ไว้สั่ง diable form ที่ต้องการ - enable
สั่ง enable form ที่ต้องการ - findFirstElement
อันนี้ดูไม่ค่อยมีประโยชน์เลย รู้สึกว่าจะมีไว้ใช้ในfocusFirstElement
- focusFirstElement
- reset
เห็นได้ว่า method ทั้งหมด มี require parameter
เป็น form element หรือ form name ทั้งสิ้น (รับได้ทั้ง 2 แบบ)
Helper object ที่
Form
เรียกใช้ มีอยู่ 2 ตัวคือ- Form.Element
มีแค่ 2 method คือ- serialize(element)
อันนี้ถูกเรียกจาก Form.serialize โดยมีเป้าหมายพื่อ encode ข้อมูลเพื่อ submit - getValue(element)
อันนี้ไว้ใช้ get ค่าที่อยู่ใน Element ที่ต้องการ
รับ parameter เป็น element id หรือ element object ก็ได้
- serialize(element)
- Form.Element.Serializers
อันนี้เป็น lower layer แล้ว ถูกเรียกใช้จาก Form.Element อีกที
ใน Prototype มี Helper Function ที่ชื่อ
$F
ซึ่งจริงๆแล้ว ก็คือ short-cut ของ Form.Element.getValue นี่เอง
var $F = Form.Element.getValue;
Related link from Roti
Thursday, March 09, 2006
Synergy
ได้โปรแกรมดีๆมาช่วยงานอีกตัวแล้ว
Synergy เป็นโปรแกรมที่่ช่วยให้เรา share keyboard และ mouse
ระหว่างเครื่องคอมพิวเตอร์ โดยไม่ต้องใช้ hardware
รวมทั้งยัง support การ share ระหว่าง platform ด้วย (windows, Linux/Unix, Mac OS X)
การใช้งานก็ไม่ยาก
เครื่องคอมพิวเตอร์ที่เราจะใช้ keyboard และ mouse
จะ start ใน mode ของ server
ส่วนเครื่องที่เหลือ start ใน mode client
การ start ใน mode server ต้องมี config file ด้วย
หน้าที่ของ config file ก็คือจัดเรียง screen
ว่าเครื่องไหนอยู่ขวา, ซ้าย, บน, ล่าง เมื่อเทียบกับเครื่องอื่น
การจัดเรียงนี้ จะช่วยให้เราลาก mouse ข้ามเครื่องได้
ตัวอย่าง config ของผม
Synergy เป็นโปรแกรมที่่ช่วยให้เรา share keyboard และ mouse
ระหว่างเครื่องคอมพิวเตอร์ โดยไม่ต้องใช้ hardware
รวมทั้งยัง support การ share ระหว่าง platform ด้วย (windows, Linux/Unix, Mac OS X)
การใช้งานก็ไม่ยาก
เครื่องคอมพิวเตอร์ที่เราจะใช้ keyboard และ mouse
จะ start ใน mode ของ server
ส่วนเครื่องที่เหลือ start ใน mode client
การ start ใน mode server ต้องมี config file ด้วย
หน้าที่ของ config file ก็คือจัดเรียง screen
ว่าเครื่องไหนอยู่ขวา, ซ้าย, บน, ล่าง เมื่อเทียบกับเครื่องอื่น
การจัดเรียงนี้ จะช่วยให้เราลาก mouse ข้ามเครื่องได้
ตัวอย่าง config ของผม
section: screens
g5.local: # my Apple G5
erp: # my Laptop Gentoo
end
section: links
g5.local:
left = erp
erp:
right = g5.local
end
section: options
keystroke(alt+f1) = switchInDirection(left)
keystroke(alt+f2) = switchInDirection(right)
end
Related link from Roti
Wednesday, March 08, 2006
Search Rails api with ri
เดิมเวลาผมจำไม่ได้ว่า method ที่ต้องการมี argument อะไรให้ pass บ้าง
ก็จะ start
document ของ rails ในกรณีนี้
ได้มาจากการใช้ program rdoc generate html files ขึ้นมา
ซึ่งปกติเวลาเรา install rails ด้วย gem
มันจะ automatic ทำให้อยู่แล้ว
วันนี้มีอีก solution หนึ่ง
ก็คือการใช้ ri ในการ search
โดยปกติ ri จะค้นหา document ที่อยู่ภายใต้ site-directory
(เครื่องผมอยู่ที่ /usr/share/ri)
กับภายใต้ ~/.rdoc
เราสามารถใช้คำสั่ง
เพื่อสร้าง output file ที่ ri สามารถใช้ได้
โดย files ที่ได้จะอยู่ภายใต้ directory
ตัวอย่างเช่น ถ้าผมต้องการให้ ri สามารถ search activerecord ได้
ก็จะทำการสั่งดังนี้
สำเหตุที่ใช้ ri ก็เพราะว่าต้องการเอาไปใช้กับ emacs
ก็จะ start
gem_server
แล้วใช้ browser ค้นดูdocument ของ rails ในกรณีนี้
ได้มาจากการใช้ program rdoc generate html files ขึ้นมา
ซึ่งปกติเวลาเรา install rails ด้วย gem
มันจะ automatic ทำให้อยู่แล้ว
วันนี้มีอีก solution หนึ่ง
ก็คือการใช้ ri ในการ search
โดยปกติ ri จะค้นหา document ที่อยู่ภายใต้ site-directory
(เครื่องผมอยู่ที่ /usr/share/ri)
กับภายใต้ ~/.rdoc
เราสามารถใช้คำสั่ง
rdoc --ri
เพื่อสร้าง output file ที่ ri สามารถใช้ได้
โดย files ที่ได้จะอยู่ภายใต้ directory
~/.rdoc
ตัวอย่างเช่น ถ้าผมต้องการให้ ri สามารถ search activerecord ได้
ก็จะทำการสั่งดังนี้
cd /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib
rdoc --ri
สำเหตุที่ใช้ ri ก็เพราะว่าต้องการเอาไปใช้กับ emacs
Related link from Roti
pack200
ตกข่าวอีกตามเคย
พึ่งรู้ว่า java web start ของ jdk1.5 support gzip format
ที่ได้จากโปรแกรม pack200
(ช่วย compress jar file ให้มีขนาดเล็กลงได้)
อ่านที่นี่
Pack200 and Compression
ตัวอย่างที่ sun แสดงไว้ เขาใช้ servlet เป็นคนเลือก format ในการส่งกลับ
กรณีที่ใช้ apache อย่างเดียว ก็ให้ดูตัวอย่างการ config จาก link นี้
How to use Pack200 for your Java Web Start applications on Apache Web Server
ตอนที่เห็นครั้งแรก ก็นึกว่ามันเป็น compress format ใหม่ๆ
แต่จริงๆแล้วมันก็คือ gzip format ธรรมดานี่แหล่ะ
โดยขั้นตอนการทำงาน เท่าที่ดู (เดา)
ก็คือ
เริ่มจาก มันจะ unpack jar เราก่อน (jar ก็เป็น compress format แบบหนึ่ง)
จากนั้นก็ pack กลับภายใต้ชื่อ file-name.pack
ตรงนี้ไม่รู้ว่า format เป็นอะไร
แต่ถ้าลองเทียบกับ tar format แล้ว
มันจะมีขนาดเล็กว่านิดหน่อย
(ทดสอบโดยใช้คำสั่ง jar xf เพื่อ extract jar file ออกมา
จากนั้นก็ใช้คำสั่ง tar cf กับเนื้อหานั้นๆ)
สุดท้ายก็ compress pack format ด้วย gzip
(file ที่ได้ ก็เลยชื่อ file-name.pack.gz)
ลองทดลองกับ jar file ดังนี้
พึ่งรู้ว่า java web start ของ jdk1.5 support gzip format
ที่ได้จากโปรแกรม pack200
(ช่วย compress jar file ให้มีขนาดเล็กลงได้)
อ่านที่นี่
Pack200 and Compression
ตัวอย่างที่ sun แสดงไว้ เขาใช้ servlet เป็นคนเลือก format ในการส่งกลับ
กรณีที่ใช้ apache อย่างเดียว ก็ให้ดูตัวอย่างการ config จาก link นี้
How to use Pack200 for your Java Web Start applications on Apache Web Server
ตอนที่เห็นครั้งแรก ก็นึกว่ามันเป็น compress format ใหม่ๆ
แต่จริงๆแล้วมันก็คือ gzip format ธรรมดานี่แหล่ะ
โดยขั้นตอนการทำงาน เท่าที่ดู (เดา)
ก็คือ
เริ่มจาก มันจะ unpack jar เราก่อน (jar ก็เป็น compress format แบบหนึ่ง)
จากนั้นก็ pack กลับภายใต้ชื่อ file-name.pack
ตรงนี้ไม่รู้ว่า format เป็นอะไร
แต่ถ้าลองเทียบกับ tar format แล้ว
มันจะมีขนาดเล็กว่านิดหน่อย
(ทดสอบโดยใช้คำสั่ง jar xf เพื่อ extract jar file ออกมา
จากนั้นก็ใช้คำสั่ง tar cf กับเนื้อหานั้นๆ)
สุดท้ายก็ compress pack format ด้วย gzip
(file ที่ได้ ก็เลยชื่อ file-name.pack.gz)
ลองทดลองกับ jar file ดังนี้
- oscar.jar
(OSGi framework)
jar size 149469 bytes
pack200 size 45426 bytes
jar.gz size 138213 bytes - SwingSet2.jar
เป็น demo ที่ bundle มากับ jdk
jar size 1432007 bytes
pack200 size 1148563 bytes
jar.gz size 1390818 bytes - Stylepad.jar
มากับ demo เหมือนกัน
jar size 102221 bytes
pack200 size 65864 bytes
jar.gz size 96329 bytes
Related link from Roti
รูปเส้นทางขี่จักรยาน trip-น่าน
ตัวอย่างเส้นทางที่ขี่ งามมาก ขี่ไต่ไปตามสันเขา
ภาพที่เห็น รู้สึกจะเป็นแถว กิ่วมรณะ
ที่ได้ชื่อนี้ ก็เพราะว่า สมัยที่ยังมีการปะทะกันอยู่
จุดนี้คือจุดซุ่มโจมตีของ ผกค. (ชัยภูมิเหมาะสมมาก)
พี่ๆที่ไปด้วย เขาลงเรื่องไว้ที่นี่
http://thaimtb.com/cgi-bin/viewkatoo.pl?id=81687
http://www.thaimtb.com/cgi-bin/viewkatoo.pl?id=81340
Related link from Roti
Embeded Java
อาทิตย์ก่อนได้ลองเล่น Snap ซึ่งเป็น product ของ ImSys
ตัวอย่าง features
- Sun certified J2ME-CLDC
- Native Java execution
- 10/100Base-T Etherne
- 2 Mbytes flash memory
- 8 Mbytes DRAM
feature ที่ระบุว่าสามารถทำ native java execution
ก็เพราะ cpu ที่ snap board ใช้ (CISC/WISC)
สามารถ program ระดับ microcode ได้
(แก้ไขระหว่าง runtime ได้อีกต่างหาก)
ก็เลยสามารถ implement ให้ interpret java byte code ได้
Note: คำว่า WISC ย่อมาจาก Writable Instruction Set Computing
การพัฒนา java ก็ใช้ developer tool อะไรก็ได้
ขอให้ compile ให้ได้ byte code แล้วกัน
พอได้ class file ก็ใช้ ftp load โปรแกรมลงไป (snap start ftp server ได้)
ตอนแรก กะว่าจะทดลองลง Oscar (OSGi Framework) ดู
ปรากฎว่ามีปัญหาเรื่องขนาด เพราะ OSGi ดูเหมือนจะเล็ก แต่จริงๆแล้วขนาดไม่เบาเลย
ก็เลยเลือกแต่ core กับ shell bundle ลงไป
สุดท้ายไปติดปัญหาว่า snap ไม่ support jar file ก็เลยล้มเลยความตั้งใจ
จากนั้นก็แอบดู model ของการ implement cgi program
ก็ง่ายๆ ตรงไปตรงมาดี หน้าตาประมาณนี้
public class HelloCgi implements HttpCgi {
public void execute(Hashtable variables, OutputStream os) throws .. {
....
}
}
ตอน start server ก็แค่
HttpServer hs = new HttpServer();
Thread t = new Thread(hs)
hs.addCgi(new HelloCgi());
t.start();
ยังเหลือที่อยากลองอีกอย่าง ก็คือ อยากลองดูว่า เราสามารถ implement Jini บน snap ได้หรือไม่?
Related link from Roti
Monday, March 06, 2006
How to be an expert
เห็นที่ bact' ลง link video แสดงการเล่น yoyo ชั้นเซียนแล้ว
ไปอ่านเจอ How to be an expert ก็เลยเอาทำ link ไว้
ไปอ่านเจอ How to be an expert ก็เลยเอาทำ link ไว้
Related link from Roti
Subscribe to:
Posts (Atom)