Tuesday, October 17, 2006

Mercurial

ช่วงนี้มี project เล็กๆน้อยๆเต็มไปหมด
อยากทำ version control ได้
แต่ไม่อยากไปนั่ง create repository ที่ server
หรือลง subversion server ที่เครื่องตัวเอง
ก็เลยมองหา Revision Control ตระกูล Distributed มาลองใช้ดู

ลองใช้อยู่ 2 ตัวคือ Mercurial กับ Darcs
สุดท้ายก็ไปจบลงที่ Mercurial เพราะ
  • คำสั่งมันดูไกล้เคียงกับ svn ดี
  • เวลาจะ sync ข้ามเครื่อง
    ตัว Mercurial สามารถ start embed web server ได้เองเลย
    ไม่ต้องเสียเวลาไปทำ link ไว้ใน apache htdocs

Related link from Roti

Monday, October 16, 2006

คำชม

น่าสนใจนะ ระหว่างคำชม
"You are a good drawer" กับ
"You did a good job drawing"
อันไหนมี effect ต่อเด็กอย่างไร

Link

Related link from Roti

Migrator

ใครที่ได้ใช้ Rails แล้ว
เวลากลับมาใช้ Java ก็มักจะนำเอาบางอย่างติดมือกลับมาด้วย
อย่าง project Migrator นี้ก็เหมือนกัน
เกิดจากคนเขียนที่เคยใช้ Rails มาก่อน แล้วต้องกลับมาทำ java project

Project ที่แล้วของผม
ก็มีการนำเอา concept ของ Migration มา apply ใช้เหมือนกัน
เนื่องจากการพัฒนา ใช้ methodology แบบ Agile,
schema ของ Database จะค่อยๆ evolve
ก็เลยอยากให้สามารถเก็บ version ของ Database Schema ได้ด้วย
(เนื่องจาก script sql อยู่ใน codebase ที่เก็บลง version control)

Related link from Roti

Tuesday, October 10, 2006

Rails Multibyte Support

Changeset 5223 เพิ่ม feature ในการ support multibyte
ลองดูตัวอย่าง

>> $KCODE='UTF8'
=> "UTF8"
>> name = 'ภาษาไทย'
=> "ภาษาไทย"

>> name.length
=> 21
>> name.chars.length
=> 7

>> name.reverse
=> "\242\270룠蒹ಸ੸ಸ࠸\340"
>> name.chars.reverse
=> #<ActiveSupport::Multibyte::Chars:0x28ad624 @string="ยทไาษาภ">
>> name.chars.reverse.to_s
=> "ยทไาษาภ"

>> name[1..3]
=> "\270\240\340"
>> name[0..3]
=> "ภ\340"
>> name.chars[0..3].to_s
=> "ภาษา"

Related link from Roti

Monday, October 09, 2006

ทดสอบ Cometd

วันนี้ทดลองทดสอบ Cometd
โดย definition ของ Cometd ก็คือ

Cometd is a scalable HTTP-based event routing bus that uses a push technology pattern known as Comet.

สิ่งที่ Cometd พยายามทำ ก็คือ การกำหนดมาตรฐาน protocol สำหรับ client กับ cometd server
ตัว draft ของ Protocol สามารถดูได้ที่นี่
http://svn.xantus.org/shortbus/trunk/bayeux/protocol.txt

ตัว Cometd server ตอนนี้เห็นว่ามี implement ด้วย
python, http://svn.xantus.org/shortbus/trunk/cometd-twisted/
perl http://svn.xantus.org/shortbus/trunk/cometd-perl/
แล้วก็ Java
(ผมก็กะว่าจะทำ erlang version เหมือนกัน)

ในฝั่ง Java ตอนนี้มี Jetty เป็นหัวหอก
โดยใน jetty version 6 , jetty provide CometdServlet มาให้เลย (อยู่ใน directory extras)

ที่ Jetty เป็นหัวหอกในเรื่องนี้ ก็เพราะเขามี feature Continuations ที่คนอื่นยังไม่มี
เขาก็เลย implement และผลักดัน Cometd ได้อย่างไม่เกรงกลัวว่าจะทำให้เกิดปัญหา server overload
(เคยเขียนเรื่อง Jetty Continuations ไปแล้ว ตามอ่านได้ที่นี่ Link)

สำหรับในส่วน client ตอนนี้ก็มี Dojo ที่ implement ใน Trunk แล้ว
โดยอยู่ใน package dojo.io.cometd
ประเด็นที่น่าสนใจใน Dojo Cometd client ก็คือ
technique ของการ implement มีให้เลือกหลายแบบคือ
  • iFrame
  • mime-message-block
  • long-poll
  • callback-polling

ผมลองทดสอบแค่ long-poll
เท่าที่ลองทดสอบดูในเบื้องต้น ก็พบปัญหาว่า
jetty return response ในตอน handshake กลับมาไม่ตรงตาม Spec ใน protocol
(แทนที่จะ return array ครอบ json Object, มันกลับ return json Object มาเลย,
ผมใช้วิธี quickfix แก้ source code ใน dojo ให้ทำงานได้ไปก่อน)
ปัญหาอีกข้อที่เจอก็คือ ตัว Demo ยัง run ใน IE หรือ Safari ไม่ได้

Related link from Roti

Camlp4

วันนี้มีเหตุให้ต้อง compile โปรแกรมที่เขียนด้วย OCaml
ก็เลยทำให้ได้รู้จักกับ Camlp4

Camlp4 เป็นโปรแกรมที่เปิดให้เราสามารถ modify syntax ของ OCaml ได้
ทำให้เราสร้าง DSL หรือ customize OCaml syntax ได้

ไว้ให้ผมเป็น OCaml ก่อน แล้วจะเขียนอธิบายเรื่องนี้ให้ฟัง

Related link from Roti

Friday, October 06, 2006

ผลการวิจัยจาก google code

Rubyist มี blog ที่พูดถึง Measuring programmer happiness?
วัดโดยใช้ข้อมูลจาก google code

Related link from Roti

Thursday, October 05, 2006

Magic in Rails Routing

Jamis Buck เขาเขียนอธิบาย กลไก routing ของ Rails ว่าทำงานอย่างไร
ตอนแรกพูดถึง
Under the hood: Rails' routing DSL
ว่าด้วยการทำงานภายใน เวลา rails เริ่มอ่าน file $RAIL_ROOT/config/route.rb
จะมีการทำงานภายในอย่างไร

ส่วนตอนสองพูดถึง
Under the hood: route recognition in Rails
อธิบายว่า ถ้ามี request วิ่งเข้ามาแล้ว
กลไก routing จะ recognize url ได้อย่างไร

ส่วนที่น่าสนใจในตอนที่ 1 ก็คือ
การ dynamic generate anonymous module
แล้วค่อย include มันเข้ากับ ActionController

ส่วนตอนที่ 2 มี code ที่พิสดารมากอยู่จุดหนึ่ง ก็คือ
def recognize(path, environment={})
write_recognition
recognize path, environment
end

ความพิสดารอยู่ที่มัน recursive เรียกตัวมันเอง
แต่ก่อนที่จะเรียกตัวมันเอง มันทำการ rewrite ตัวเองด้วย method write_recognition
รูปแบบนี้เป็น lazy method แบบหนึ่ง
นั่นคือยังไม่เตรียมอะไร จนกว่าจะถูกเรียกใช้

Related link from Roti

Training Professors

BitWorking เขาลง link เรื่อง video แสดงการฝึกปลาทอง ใน youtube
แต่ที่ผมชอบไม่ใช่เรื่องนี้หรอก แต่เป็นเรื่องที่เขาเล่าให้ฟัง
She was taking a psychology class with a professor that really liked his students to take notes. He also liked to pace in front of the blackboard when he lectured. After finishing the section on Pavlov the class got together and decided to only take notes when the professor was in front of the left side of the blackboard. After a week he was only pacing there. So the next week they cut the left hand side in half and did it again. And again. They kept cutting his pacing space in half and in a month had him firmly planted on the left hand side of the blackboard.

ในอีกแง่หนึ่ง เรื่องนี้เป็นเรื่องที่เกิดตลอดเวลา ทั้งที่ตั้งใจและไม่ตั้งใจ
แต่เรา(ผู้ที่อาจโดนกระทำอยู่)จะรู้ตัวหรือเปล่า?

Related link from Roti

Wednesday, October 04, 2006

XQuery

ช่วงนี้มีโปรเจคที่ต้องยุ่งกับ XML เยอะๆอยู่ตัว
ก็เลยมองหา solution ที่มาช่วยจัดการ
หนึ่งใน solution นั้นก็คือ XQuery

query language ของ Relational Database คือ SQL
query language ของ XML ก็คือ XQuery

ตัว syntax ของ XQuery มีบางคนเรียกย่อๆว่า FLWOR
ซื่อย่อมาจาก causes หลักๆที่ XQuery support นั่นคือ
  • F -> For
  • L -> Let
  • W -> Where
  • O -> Order by
  • R -> Return

มาตรฐานของ XQuery จะ depend อยู่บน มาตรฐานของ XPath 2.0
นั่นคือการอ้างถึง element ต่างๆ จะทำผ่าน XPath expression
ใครอยากเห็นว่าหน้าตา syntax เป็นอย่างไร ให้ดูที่ link นี้
Blooming FLWOR - An Introduction to the XQuery FLWOR Expression

ตัว language เห็นบางคนก็บอกว่า มีแนวทางไปในทางเดียวกับ Functional Language
อ่านดูได้ใน XQuery: a typed functional language for querying XML
ส่วนบางคนก็บอกว่า XQuery is imperative
ถ้ามีสองความคิดเห็นอย่างนี้ แสดงว่า xquery มันน่าอยู่กลางๆ spectrum ที่ฝั่งซ้ายเป็น declarative
ส่วน ฝั่งขวาเป็น imperative
(ไม่ว่าจะเป็นอะไร ก็ช่างหัวมันเถิด ใช้งานได้ดีก็พอแล้ว)

ผมชอบความ powerful ของมัน ลองดูตัวอย่างนี้
สมมติเรามี xml ที่ present Part ในลักษณะ Flat อยู่
<?xml version="1.0" encoding="ISO-8859-1"?>
<partlist>
<part partid="0" name="car"/>
<part partid="1" partof="0" name="engine"/>
<part partid="2" partof="0" name="door"/>
<part partid="3" partof="1" name="piston"/>
<part partid="4" partof="2" name="window"/>
<part partid="5" partof="2" name="lock"/>
<part partid="10" name="skateboard"/>
<part partid="11" partof="10" name="board"/>
<part partid="12" partof="10" name="wheel"/>
<part partid="20" name="canoe"/>
</partlist>

ถ้าเราต้องการ convert ให้เป็นแบบนี้
<parttree>
<part partid="0" name="car">
<part partid="1" name="engine">
<part partid="3" name="piston"/>
</part>
<part partid="2" name="door">
<part partid="4" name="window"/>
<part partid="5" name="lock"/>
</part>
</part>
<part partid="10" name="skateboard">
<part partid="11" name="board"/>
<part partid="12" name="wheel"/>
</part>
<part partid="20" name="canoe"/>
</parttree>

เราสามารถทำได้ โดยเขียน XQuery ในแบบนี้
declare function local:one_level($p as element()) as element()
{
<part partid="{ $p/@partid }"
name="{ $p/@name }" >
{
for $s in doc("partlist.xml")//part
where $s/@partof = $p/@partid
return local:one_level($s)
}
</part>
};

<parttree>
{
for $p in doc("partlist.xml")//part[empty(@partof)]
return local:one_level($p)
}
</parttree>

ช่วงนี้เพื่อทดสอบความเป็นไปได้ต่างๆ ผมก็เลยลองหา Opensource มาเล่นก่อน
ตัวที่น่าสนใจก็คือ eXist
ซึ่งเจ้านี้ claim ว่า XQuery ของเขา test ตามมาตรฐานของ w3c ผ่านกว่า 80% แล้ว

Architecture ของ eXist (ในแง่ implement) ก็น่าสนใจ ตรงที่ Framework ที่เขาใช้เขียน server
base อยู่บน Cocoon ซึ่งเป็น Development Framework ที่อิงกับ XML อย่างแนบแน่น

Related link from Roti

Tuesday, October 03, 2006

IEs4Linux



ช่วงหลังๆนี่ ละเลย IE มาตลอด (2 ปีแล้ว)
อย่างบางโปรเจคที่บังคับให้ใช้ firefox ได้ ผมก็จะ implement โดยไม่สนใจ IE เลย
(แต่จะมีน้องๆที่เสียดาย IE มาคอย port ให้ IE ใช้ได้)

มีโปรเจคใหม่อยู่ตัว ที่ต้อง support IE แน่ๆ
แต่เนื่องจากเครื่องที่ใช้เป็น Linux กับ Mac
ก็เลยต้องขวนขวายมากกว่าปกติ

เดิมมองไว้ที่ vmware
แต่ลองแล้ว มันหนักไปหน่อย
สุดท้ายก็ไปลงตัวที่ IEs4Linux
ซึ่ง run โดยใช้ Wine
การติดตั้งก็ง่ายมาก (ผมใช้ fedora)
ลงทีเดียวได้ครบตั้งแต่ version 5, 5.5, 6
ใครสนใจก็ลองดูได้

Related link from Roti

Monday, October 02, 2006

Prevayler

มองหา Persistent Storage ที่เหมาะๆมานานแล้ว
วันนี้ได้ฤกษ์ลองเล่น ​Prevayler ดู
(จริงๆ แล้ว prevayler มีมานานมากแล้ว
แต่ด้วย nature ของผมที่เมื่อก่อนเป็นพวก emotionally attached to database
พอเห็นคำเปรยที่ว่า Memory Only ก็เดินหนีแล้ว
)

ลองดู Architecture ก่อน
  • Prevayler maintain ข้อมูลใน Memory เท่านั้น
  • ข้อมูลที่ maintain อยู่ในรูป Plain Old Java Object
  • เนื่องจากข้อมูลเก็บอยู่บน Memory เป็นหลัก
    เพื่อให้ persistent สามารถ keep state ได้
    prevayler ใช้วิธีทำ snapshot ลงบน Disk
  • การแก้ไขข้อมูลจะต้องทำผ่าน Transaction
    โดยใช้ pattern ที่เรียกว่า Command pattern
  • เมื่อเราสั่ง execute Command Object(Transaction)
    Prevayler จะทำการ serialize Command Object ของเราลง Journal file ก่อนที่ update ข้อมูลใน memory
    เพื่อทีในกรณีที่ system fail ก่อนที่จะทำ snapshot
    จะได้สามารถทำ recover persistent state กลับมาได้

ฟังดูแล้ว ก็น่าสนใจดี

ลองดูภาพการใช้งานจริง
สมมติ application ตัวอย่างเป็น Bank application
ที่ต้อง maintain account ของ customer

ใน prevayler ไม่มี concept เรื่อง table แบบ Relational DB
ข้อมูลที่จะเก็บลง Prevayler ต้องอยู่ในรูป Object
ดังนั้นเราจึง define Bank Class ขึ้นมา เพื่อใช้ maintain account object ของเรา
public class Bank implements Serializable {

private static final long serialVersionUID = -3472784405094724103L;

public List<Account> accounts = new ArrayList<Account>();

public List<Account> getAccounts() {
return accounts;
}

public void addAccount(Account acct) {
accounts.add(acct);
}

}

ตัว Account Class ก็เขียนง่ายๆดังนี้
public class Account implements Serializable {

private static final long serialVersionUID = 5447177127896043827L;

private String code;
private BigDecimal amount;

public Account(String code, BigDecimal amount) {
this.code = code;
this.amount = amount;
}

... getter/setter here.

}


เนื่องจากกลไกที่ prevayler ใช้ในการทำ snapshot
ก็คือ java serialize ธรรมดา (ตรงนี้สามารถเปลี่ยนวิธีได้ เช่นไปใช้ xml serialize)
ดังนั้น class Bank กับ Account ของเรา ก็เลยต้อง implement Serializable

การเริ่่มต้นใช้งาน prevayler จะเริ่มต้นดังนี้
Prevayler prevayler = PrevaylerFactory.createPrevayler(new Bank(), "bank");     
Bank bank = (Bank) prevayler.prevalentSystem();


ในการที่จะสร้าง Account ขึ้นมา, เราจะไม่ใช้วิธี access Bank Object ตรงๆ
แต่จะทำผ่าน Command Object
ลองดูตัวอย่าง Command Object ที่ใช้ create Account
public class CreateAccount implements Transaction {

private static final long serialVersionUID = 8524963860312931007L;

private Account account;

public CreateAccount(Account account) {
this.account = account;
}

public void executeOn(Object prevalentSystem, Date executionTime) {
Bank bank = (Bank) prevalentSystem;
bank.addAccount(account);
}

}

เมื่อจะใช้งาน ก็สั่งผ่าน prevayler object
prevayler.execute(new CreateAccount(new Account("11", new BigDecimal("200.00"))));


ที่นี้ก็มาถึงคำถามถึงจุดนี้ถ้าเราปิดโปรแกรมเราลงไป แล้วเปิดขึ้นมาใหม่
Bank Object เราจะยังมี Account Object ที่พึ่งสร้างอยู่หรือไม่
คำตอบก็คือ "มี"
เพราะเมื่อเราสั่ง execute Command Object เมื่อไร
prevayler จะทำการสร้าง journal file ขึ้นมา
(1 command ต่อ 1 journal file)
กลไกการเขียน journal ก็ใช้ java serialize ธรรมดา

ที่นี้การเก็บข้อมูลในรูป journal อย่างเดียวคงไม่เหมาะแน่
เพราะมันจะเยอะแยะไปหมด และน่าจะกินเวลา startup time
(prevayler cliam ว่าสามารถ execute journal ใน rate 6000 journal/sec.)
prevayler ก็เลยมีความสามารถในการทำ snapshot ด้วย
โดยการสั่ง
prevayler.takeSnapshot();


หลังจากทดลองเล่น + อ่าน Architecture แล้ว
ก็จัดการ add เข้า Collection Tools ของตัวเอง
โดย usecase ที่จะนำไปใช้ ก็คือ
  • พวก Desktop Application ตัวเล็กๆ
  • กลไก Data บางอย่างที่ขี้เกียจทำ ORM (เริ่มเบื่อแล้ว)
    เช่น User preference ใน Web application
  • เอาไว้เก็บพวก workflow instance ก็ไม่เลว
  • เก็บ Fact ของพวก rule base ก็น่าจะได้


ข้อเตือนใจ
  • Prevayler maintain ทุกอย่างใน memory
    snapshot เป็นแค่ backup
    ดังนั้นต้องแน่ใจว่ามี Ram พอ, กับข้อมูลไม่เยอะจนเกินไป
  • อย่าไปนึกว่าจะมี กลไก Index แบบ Relational database
    การ access object เป็นไปตาม java object ธรรมดา
    ดังนั้นอะไรที่อยากให้ access เร็ว ก็ต้องใช้พวก Map
  • ถ้า Domain เราซับซ้อน
    command object ก็จะมีปริมาณสูง ทำให้ maintain ลำบากขึ้น (อะไร,อยู่ที่ไหน)

Related link from Roti

Friday, September 29, 2006

Agile

บทบ่นล่าสุดของ Steve Yegge ,Good-Agile-Bad-Agile
พูดถึง Agile software developement
(คนอะไร เขียน blog โคตรยาวเลย, ผมขี้เกียจอ่านทั้งหมด ก็เลยเลือก scan อ่าน)
ในประเด็นว่า อะไรที่ชอบ อะไรที่ไม่ชอบ
แล้่วก็ยกตัวอย่าง บรรยากาศที่ทำงานของ Google ว่ามันเจ๋งอย่างไร

- there are managers, sort of, but most of them code at least half-time, making them more like tech leads.
(บริษัทฯเราก็เข้าข่ายนี้เหมือนกัน)

- developers can switch teams and/or projects any time they want, no questions asked; just say the word and the movers will show up the next day to put you in your new office with your new team.

- Google has a philosophy of not ever telling developers what to work on, and they take it pretty seriously.

- developers are strongly encouraged to spend 20% of their time (and I mean their M-F, 8-5 time, not weekends or personal time) working on whatever they want, as long as it's not their main project.
(อ้า ข้อนี้ก็ตรงกัน แต่ของเราเผลอๆ สัดส่วนอาจมากกว่า 20 %)

- there aren't very many meetings. I'd say an average developer attends perhaps 3 meetings a week, including their 1:1 with their lead.
(อันนี้ บริษัทฯ ผมน้อยกว่ามาก, บางอาทิตย์ก็ไม่มี meeting)

- it's quiet. Engineers are quietly focused on their work, as individuals or sometimes in little groups or 2 to 5.
(ไม่เหมือนกัน ที่บริษัทฯของผมเสียงดังมาก
บางวันก็มีเสียงร้องให้ของลูกชายผมด้วย)

- there aren't Gantt charts or date-task-owner spreadsheets or any other visible project-management artifacts in evidence, not that I've ever seen.
(ของผมนานๆจะมีที โดยมากมักจะมีในช่วงเริ่มต้นโครงการ)

ส่วนที่ชอบก็คงในส่วน comment ที่มีคนตอบกลับ
(ยาวกว่าบทบ่นอีก)
มีที่ตรงใจอยู่อันหนึ่ง Link
ก็คือ Agile มันเป็นเรื่องของ culture
เพราะเมื่อต้นอาทิตย์ก็ได้เข้าไปที่ ตลาดหลักทรัพย์ฯ
โดยเข้าไปอธิบายเรื่อง methodology ที่บริษัทฯใช้อยู่
(เนื่องจากจะมีโปรเจคที่ต้องทำร่วมกัน ก็เลยต้องแลกเปลี่ยนกันก่อน)
ก็สัมผัสได้ถึง mismatch ของวัฒนธรรมองค์กรอยู่เหมือนกัน

Related link from Roti

Thursday, September 28, 2006

Nuxeo & OSGi

Nuxeo ก็เป็นอีกรายที่เปลี่ยน Architecture มาใช้ OSGi
ลองอ่านเหตุผลในการ switch ของเขาดู Link

ตัวอย่าง use case ในการใช้ extension-point ของ Nuxeo ก็เช่น
  • define actions and menus
  • define content schemas
  • define views
  • define content objects
  • define permissions
  • define PageFlows
  • define Business Process
  • define content trnsformations
  • define rule for rule engine
  • define script extension (JRuby, Jython,...)
  • define JMS Event queue
  • define event type
  • define security policies
  • define Access Control Policies
  • define Storage Backend
  • define query engine
  • define indexing engine


ใครที่ยังไม่เคยเห็น Architecture ของ OSGi ขอแนะนำให้ทดลองเล่นหรืออ่านดูครับ
โดยเฉพาะ model ในส่วน Extension Point หรือ Plugin
ออกแบบได้งามมากๆ

Related link from Roti

Wednesday, September 27, 2006

My Neighbor Totoro



หนังเรื่อง My Neighbor Totoro กลายเป็นหนังเรื่องโปรดของครอบครัวผมไปแล้ว
ไม่ว่าจะเป็น พ่อ แม่ ปู่ ย่า หรือ เจ้าลูกชาย

หนังเรื่องนี้เป็นหนังที่ดูซ้ำได้โดยไม่เบื่อ
ผมดูกับลูกชายไปสามรอบแล้ว ก็ยังสนุกอยู่
(เมื่อกี๊แฟนเดินมาแซวว่า ของฉันดูไปห้ารอบแล้ว)

Related link from Roti

Friday, September 22, 2006

Java กับ Tail-Recursive

คุณสมบัติอย่างหนึ่ง ของภาษาคอมพิวเตอร์ในตระกูล Functional language (lisp, haskell, erlang)
ก็คือ ต้องสามารถ optimize tail-recursive ได้
โดยการ call แบบนี้ จะไม่มีการใช้ stack
เพื่อป้องกันการเกิดปัญหา stack overflow
(เนื่องจาก nature ของ Functional Language
มันส่งเสริมให้ใช้ recursive)

พึ่งรู้ว่า IBM JRE สามารถทำ optimize tail-recursive ได้เหมือนกัน
โดยทำ ณ ขณะ runtime (ไม่ได้ทำตอน compile)
ทดลองเขียนโปรแกรมทดสอบง่ายๆดู
public class TestRecursive {

public int run(int i) {
return run(i);
}

public static void main(String[] args) {
new TestRecursive().run(10);
}

}

ทดลอง run ใน jre ของ IBM มันจะ run ไปเรื่อยๆไม่รู้จบ
แต่ถ้าเป็นเจ้าอื่น จะเกิด Stack overflow ในพริบตา

เท่าที่ทดลองดู ยังเห็นแค่มี jre (1.4) ของ IBM เท่านั้นที่ทำได้
ของ Sun (1.5), BEA (1.4), Mac (1.5) ทำแบบนี้ไม่ได้

Related link from Roti

ผลกระทบเล็กๆของการปลด คตง.

ได้ยินคำบ่นของฝ่ายพัสดุในกรมบัญชีกลาง
บอกว่าเสียดายตังค์ค่าซื้อรถเบนซ์ 10 คัน
ที่ คตง. พึ่งสั่งซื้อมาเป็นรถประจำตำแหน่งเหลือเกิน
น่าจะปลดให้ไวกว่านี้

Related link from Roti

Rails in Academia

ลองอ่าน comment ดูว่ามึใครเข้าใช้ทำอะไรบ้าง
Link

Related link from Roti

Codefest #2

กลับมาอีกรอบแล้ว สำหรับกิจกรรมเขียนโปรแกรม CodeFest
หลายคนมักจะเข้าใจผิดนะว่า CodeFest เป็นการแข่งขัน
จริงๆแล้วมันเป็นกิจกรรมแลกเปลี่ยนประสบการณ์
(อันนี้ไม่ตรงนิยามแบบที่ฝรั่งเขาทำเท่าไร แต่จะเป็นไรไปหล่ะ
ในเมื่อบริบทเมืองไทย มันคนละอย่างกับเขา)

ครั้งนี้ว่าจะไปเป็น staff เถื่อนสักหน่อย
(จัดก่อนหน้า BTD ไปอาทิตย์หนึ่ง เกือบชนกันแล้ว)
คราวนี้คงได้มีโอกาสคุยได้ทั่วๆหน่อย
เพราะครั้งที่แล้ว มัวแต่ลุ้นให้โปรแกรมตัวเองเสร็จ เลยไม่ค่อยได้คุยเท่าไร

ที่อยากคุยก็คือ อยากให้น้องๆที่เข้าร่วม
เห็นภาพที่ไกลกว่าที่เขาเคยเห็น
(เช่นครั้งที่แล้วในกลุ่มผมคนที่เคยเขียนแต่ C, php ก็ได้เห็น erlang, python, dojo)
โดยมีโจทย์ที่น่าสนใจก็คือ
ทำอย่างไร จะเปลี่ยนจากคนที่ นัยตาขุ่นทึบ เป็นนัยตาวิบวับ ได้
(อันนี้ขออธิบายหน่อย
ไม่รู้ว่าเคยสังเกตกันหรือเปล่าว่า
เวลาเราอธิบายเรื่องที่เราคิดว่ามันน่าสนใจให้กับคนที่ไม่เคยรับรู้เรื่องนั้นมาก่อน
ถ้าเราสังเกตดูที่ดวงตาของเขา เราจะเห็นว่ามันลอยๆ ขุ่นๆ ไม่มีประกาย
แต่ถ้าเมื่อไรก็ตามที่เขา get และสนุก กับเรื่องนั้น
ดวงตาก็จะเปลี่ยนเป็นมีประกายวิบวับขึ้นมาทันที)
(พฤติกรรมนี้ เข้าข่ายศัพท์ที่ mk เรียกว่า เผยแพร่ลัทธิ)

อ้ออีกข้อหนึ่งที่อยากคุยก็คือ
อยากให้ตัวเองเห็นภาพไกลกว่าที่ตัวเองคิดเช่นเดียวกัน

ปล. พูดถึงเรื่องตาใสแล้ว
นึกถึงเรื่องเมื่ออาทิตย์ก่อน ครอบครัวผมจัด party
ทำพวกปิ้งๆย่างๆกัน
ผมชวนหลานผมซึ่งเป็นเด็กสมัยใหม่ เติบโตมากับเกมส์คอมพิวเตอร์
มานั่งจุดไฟในเตากัน
เริ่มแรก สายตาหลานผมมันว่างเปล่า มากเลย
กว่าจะทำให้เขาเริ่มสนุกกับกองไฟได้
ต้องใช้กุศโลบายหลายอย่างเลย

ปล.2 codefest ของเราใช้ชื่อว่า การเขียนโปรแกรมมาราธอน
ในวงการอื่นๆก็มีกิจกรรมมาราธอนแบบนี้เหมือนกัน
ลองดู SketchCrawl ซึ่งเป็นกิจกรรม drawing มาราธอน

Related link from Roti

Thursday, September 21, 2006

Breath Holding Spell

เข้าโรงพยาบาลไปนอนเล่นกับคุณลูก 4 วัน กับ 3 คืน
เริ่มจากคุณลูกเกิดอาการท้องเสีย virus ลงกระเพาะ
อาเจียนและท้องเสียสลับกันไป
พอสูญเสียน้ำหนักเข้า ก็เริ่ม dehydrate
คอพับคออ่อน แล้วก็เริ่มพูดไม่รู้เรื่อง
สุดท้ายพองอแงหนักๆ ก็ิเกิดอาการแข็งเกร็ง
หน้าเปลี่ยนเป็นสีม่วง รอบตาเปลี่ยนเป็นสีดำ ปากอ้าค้าง ตาเหลือก แล้วก็ หยุดหายใจ
พ่อก็เลยต้องรีบพาไปโรงพยาบาลโดยด่วน
โชคดีที่ระหว่างที่ถอยรถ มีมอเตอร์ไซด์สายตรวจผ่านมาพอดี
ก็เลยขอซ้อนท้ายไปโรงพยาบาล
ระหว่างทางคุณลูกก็ฟื้นขึ้นมา ช่วยให้กำลังใจคุณพ่อได้เยอะ

อยู่โรงพยาบาล ก็ไม่มีอะไรมาก นอนรับน้ำเกลือเป็นหลัก
แต่ที่ติดใจก็คือ อาการแข็งเกร็ง หยุดหายใจ นั้นเกิดจากอะไร, เรียกว่าอะไร
ผลการตรวจเลือก ค่าที่ตกนอก range ก็คือ potassium ซึ่งมีสูงกว่าปกติ
แล้วก็ co2 ซึ่งมีน้อยกว่าปกติ
สงสัยในเรื่อง co2 ก็เลยเปิดหนังสือค้นหา ก็มีอาการชักอันหนึ่งที่เรียกว่า
Hyperventilation
ที่มีอาการใจผิดรูปแบบ จน co2 ในร่างกายอยู่ในระดับต่ำ
ส่งผลให้ปริมาณ calcium ในร่างกายน้อยลง ทำให้เกิดอาการมือจีบเกร็ง

อีก 2 วันต่อมาได้คุยกับหมอว่า มีอาการแบบนี้นะ จะใช่ Hyperventilation หรือเปล่า
หมอก็บอกว่า ไม่น่าจะใช่ น่าจะเป็น Breath Holding Spell เสียมากกว่า
อ่านดูแล้ว ก็อาการตรงกับที่ลูกเราเป็น
ยกเว้นว่า ช่วงเวลาที่เขาพูดถึง เขาบอกว่าส่วนใหญ่จะเป็นประมาณ 30 วินาที
และนานสุดก็มักจะไม่เกิน 1 นาที
ส่วนลูกผมดูแล้ว น่าจะเกิด 1 นาทีนะ
แต่ไม่รู้ว่าเท่าไรแน่ เพราะเวลาที่ตกใจ เวลาในความรู้สึกเรามักจะกินเวลานานเกิดกว่าเวลาจริงเสมอ

ส่วนวิธีแก้ไข คุณหมอบอกวิธีว่า
ถ้าเกิด Breath Holding Spell แล้ว ก็ให้เราบีบที่เอ็นร้อยหวายของลูกแรงๆ
ถ้ายังไม่หายอีก ก็ให้เป่าปาก เพื่อช่วยเอาออกซิเจน เข้าไปเลี้ยงสมอง

Related link from Roti