วันพุธ, พฤศจิกายน 21, 2550

เน็ตติดๆขัดๆ ปัญหาอยู่ที่ไหน

ตอนนี้กลายเป็นคนขี้บ่นไปแล้ว มีแต่เรื่องให้บ่นตลอดเวลา

ช่วงนี้รู้สึกว่าเน็ตติดๆขัดๆ บางเว็บบางช่วงเข้าได้บ้างไม่ได้บ้าง
ตอนแรกก็นึกว่าคงเป็นที่เว็บไซต์นั้นเอง เซิร์ฟเวอร์อาจจะมีปัญหา ทราฟฟิกอาจจะเยอะ
แต่ตอนนี้ชักจะสงสัยว่าไม่ใช่เรื่องนั้น เพราะลองเรียกไปจาก "ที่อื่น" กลับเข้าได้ฉลุยเลย

ล่าสุดเข้า wikipedia ไม่ได้ ในขณะที่ google maps เข้าได้บ้างไม่ได้บ้างตามเรื่องตามราว
search ดูก็ไม่พบว่าฝรั่งจะ complain ว่าเซิร์ฟเวอร์ของ google หนืด

ชักจะสงสัยว่ามีปัญหาที่ ISP บ้านเรานี่แหละ

transparency proxy หรือเปล่า?

อนาคตของ .th

ว่าจะเขียนต่อจากบล็อกที่แล้วว่า อยากเห็น thnic ทำอะไร ก็มาได้ข่าวใหม่ 2-3 เรื่อง

เรื่องแรก หนึ่งใน authorized reseller สำหรับ .th คือ dotarai นั้นใช้ที่อยู่เดียวกับ thnic นัยว่าจะเป็นบริษัทเีัดียวกันหรืออย่างไรไม่ทราบ แต่อีกสองเจ้าที่เหลือนั้นคงไม่เกี่ยว และยังเป็นปริศนาต่อไปว่า thnic มีนโยบายในการแต่งตั้ง dealer อย่างไร

เรื่องที่สอง เมื่อเจอ dotarai ก็พบว่า dotarai กลายเป็น .com registrar รายแรกของไทยอย่างเป็นทางการไปแล้ว

สมมติไว้ก่อนว่า dotarai กับ thnic คือองค์กรเดียวกัน เพราะถ้าเป็นคนละองค์กรเรื่องนี้คงไม่งามถึงไม่งามมากที่สุด ขอเอาไว้คิดทีหลังละกัน

สิ่งที่ dotarai ทำก็คือสิ่งที่ผมฝันอยากให้มีนานแล้ว เพราะเท่ากับว่าเราดึงงานส่วน registrar ของ .com มาไว้ในไทยได้ ถ้าคนไทย (ที่ใช้ .com อยู่แล้ว) หันมาใช้กับ dotarai ก็คงดี

แต่อย่าลืมนะครับว่าภารกิจแรกคือ ให้คนไทยหันมาใช่ .th มากกว่า .com เพราะประหยัดได้มากกว่าอีก เพราะเราได้งาน registry ด้วย

เรื่องนี้ thnic (และ dotarai ด้วย?) ต้องกำหนดนโยบายให้ดี อย่าให้หลงทางประชาสัมพันธ์ผิดๆ กลายเป็นว่าชักจูงคนไทยให้สิ้นเปลืองกับโดเมนเนมมากเกินความจำเป็น

ดูจะหน้าเว็บของ dotarai แล้วยังเป็นห่วง เพราะราคา .com ถูกกว่าราคา .th เท่าตัว เทียบกันให้เห็นจะๆ ไม่รู้จะกลายเป็นการโฆษณาให้คนหันไปจด .com โดยไม่ได้ตั้งใจหรือเปล่า

ที่แย่หนักคือราคาของ dotarai ไฉนมันถึงได้แพงกว่า registrar เมืองนอกอยู่พอควร ทั้งๆที่ต้นทุนค่าแรงเราน่าจะต่ำกว่าเขามาก กลายเป็นว่าราคาไปฟาดฟันกับ reseller คนไทยไปเสียฉิบ

ซึ่งถ้าคิดในแกนนี้ เท่ากับว่า dotarai มีปัญหาด้านการตลาดเสียแล้ว คือ channel conflict ขัดผลประโยชน์กับพวกที่ควรจะเป็นเครือข่ายการตลาดให้ตัวเอง

ซึ่งแปลว่าจะต้องมีแรงเสียดทานจากกลุ่มนี้อยู่ไม่น้อย ซึ่งแปลว่าภารกิจการลดต้นทุน .com ให้ประเทศไทยคงยากที่จะประสบผลดังตั้งใจ

วิจารณ์มามากแล้วขอเสนอทางออกให้บ้าง ตามวถีทางประชาธิปไตยที่ดีงาม ไม่ใช่ด่าอย่างเดียว
- ลดราคาขายปลีก .th ลงมาหน่อยได้ไหม หรืออย่างน้อยก็แสดงข้อดีของการตรวจสอบตัวตนผู้สมัครให้ชัดเจนหน่อย จะได้จูงใจให้คนจด .th หน่อย แล้วพวกที่ไม่ตรวจสอบอย่าง .in.th อย่าไปคิดราคาเดียวกันเลย มันน่าเกลียด แล้วควรตั้งราคาขายปลีก .com ให้สูงกว่านี้ เพื่อไม่ให้เกิดภาพว่า .th แพงกว่า .com มาก
- น่าจะลองคิดเรื่องลดบทบาทตัวเองเป็น registry หรือถ้ายังไม่พร้อมก็ลดบทบาทการขายปลีกลง สร้างระบบ reseller ให้ดี แล้วขายผ่านเครือข่าย reseller จะได้ไม่ต้องมีปัญหา channel conflict ปล่อยให้ reseller ไปทำการตลาดแข่งกันเอง ภายใต้เป้าหมายที่ว่ามาแต่แรก 2 ข้อคือ ให้คนไทยใช้ .th แทน .com และ จูงใจคนที่ยังไงก็ต้องใช้ .com ให้หันมาใช้ registrar ของเราเองแทนของนอก
- เลิกเฮอะ ไอ้การทำ hosting เองน่ะ (อิงอยู่กับเรื่องการขายโดเมนด้วยตัวเอง) เพราะมันสร้าง channel conflict แบบไม่รู้จะคิดแก้ยังไงได้

แต่ถ้า thnic เลิกนโยบายการเป็นนิติบุคคลทีี่ไม่แสวงหาผลกำไร หรือ thnic ยังเหมือนเดิม แต่แยกร่าง dotarai ออกไปหากำไร

อันนี้ก็ตัวใครตัวมันล่ะครับ

วันเสาร์, พฤศจิกายน 17, 2550

เกิดอะไรขึ้นกับ thnic

จำไม่ได้แล้วว่ารู้จัก thnic มาตั้งแต่เมื่อไหร่ รู้แต่ว่านานมาก

ใช้บริการเองมาก็หลายปี ที่แนะนำเพื่อนฝูงให้ไปใช้ก็ไม่น้อย เพราะเห็นว่านอกจากเป็นทางออกของบริษัทที่ชื่อไปตรงกับฝรั่งหรือชื่อโดนใช้ไปแล้ว ยังทำให้ไม่ต้องเสียเงินตราออกไปต่างประเทศโดยไม่จำเป็น

สถานะของ thnic นั้นแปลกๆ จะว่าเป็นเอกชนก็ไม่น่าใช่ เพราะ .th เป็นสมบัติของคนไทย ในขณะที่จะว่าเป็นหน่วยงานรัฐ thnic ก็จดทะเบียนเป็นบริษัทอยู่ทนโท่ คงต้องว่าตาม อ.กาญจนาว่าเป็นนิติบุคคลที่ไม่แสวงผลกำไร

เข้าใจว่าตอนต้น thnic น่าจะลำบากมาก เพราะโดเมนเนม .th ยังมีคนใช้น้อย รายได้อาจจะไม่พอเลี้ยงองค์กร แต่ thnic ก็ดิ้นรนอยู่รอดมาได้ แต่วันนี้ที่มี .th เกิน 25,000 ชื่อ รายได้ปีละ 20 ล้านบาท ก็น่าจะอยู่ได้สบายๆ

ปัญหาคือ ผมว่าหลังๆ thnic ชักจะทำอะไรแปลกๆ

เรื่องแรกที่เห็นคือ ให้บริการ web hosting เอง อันนี้จะว่าเป็นแนวทางในการหารายได้ก็เรื่องหนึ่ง แต่มันอดทำให้เข้าใจว่า thnic กำลังจะหลงทางไม่ได้ เพราะไม่ใช่หน้าที่ขององค์กรที่มีหน้าที่ดูแล .th เลย

ยิ่งมาเห็นการแต่งตั้ง authorized dealers จำนวนหนึ่ง และมีเป้าหมายให้มีการใช้งาน .th เพิ่มจาก 25,000 เป็น 300,000 ภายใน 3 ปี อันนี้มึนเลยครับ

ความจริงเรื่องนี้เป็นเรื่องที่ผมเชียร์ให้มีมานานแล้วด้วยซ้ำ เพราะเห็นว่าเราอุดหนุนให้ .th อยู่ได้ เงินทองไม่ต้องรั่วไหล แต่ต้องจ่ายแพงกว่า .com ถ้าแยกส่วนให้เป็น registry, registrar แบบสากลก็จบ ไม่ต้องกังวลเรื่องผลประโยชน์ทับซ้อน และมีคนทำการตลาดหลายมือไม้ ย่อมแพร่หลายได้เร็ว และการแข่งขันจะทำให้ราคาถูกลง และมีการแข่งขันด้านบริการด้วย ถึงแม้ว่าที่ผ่านมา thnic ก็ให้บริการได้เป็นอย่างดีมาตลอด

แต่ที่ว่ามึนนี่ มึนเพราะไม่เคยได้ยินเรื่องการคัดเรื่อง dealer มาก่อน และก็ไม่มีการชี้แจงว่าเลือก dealer ยังไง และทำไมต้องมีจำนวนเท่านี้ แบ่งผลประโยชน์กันยังไง

แล้วทำไมต้อง 300,000 เป้าหมายควรจะเป็นการให้คนไทยหันมาใช้ .th แทน .com ไม่ใช่หรือ ไม่ใช่การใช้ฟุ่มเฟือยเปล่าประโยชน์

อย่าลืมนะครับว่า thnic ดูแล .th อยู่ก็จริง แต่ .th เป็นของคนไทย ไม่ใช่ของ thnic

thnic ทำงานดูแล .th ให้คนไทยมานานแล้ว ไม่อยากให้จบแบบไม่สวยครับ

ได้แต่หวังว่า thnic จะมีคำชี้แจงดีๆสำหรับเรื่องนี้

วันพุธ, พฤศจิกายน 07, 2550

เมล์สแปม กับ DATE_IN_FUTURE

เมล์จากบางคนถูก spamassassin ตีกลับบ่อยๆเพราะเข้าใจว่าเป็นสแปม

พอไปดูล็อก พบว่าเมล์พวกนั้นถูกประเมินคะแนน DATE_IN_FUTURE ไว้ค่อนข้างสูง น่าจะเป็นสาเหตุ

ถามไถ่ได้ความว่า เครื่องต้นทาง ดันไปตั้ง Time Zone ไว้ผิด พิลึกจริงๆ

ตั้ง Time Zone ผิด เวลาท้องถิ่นตรงเวลาในไทย นั่นแปลว่า GMT มันเก๊าะต้องไม่ตรง เจ้า spamassassin เลยงง

ยังงี้ก็มีด้วยแฮะ

วันพุธ, กันยายน 19, 2550

ประชาไท เสรีหรือแอบแฝง?

อ่านข่าวนี้ http://www.prachatai.com/ireport/view.php?id=69 ในประชาไทย แล้วหงุดหงิดใจ

คนรายงานอ้างว่าเป็นบทความ แต่เนื้อหาที่แค่ 2-3 ประโยค ที่เหลือลอกรายงานของ Forbes มาทั้งดุ้น และไม่ได้บอกที่มาที่ไป

ส่วนที่แย่ที่สุดคือ ประชาไท ปิดกั้นไม่ให้แสดงความเห็นในรายงานนี้ เท่ากับปิดช่องทางที่จะอธิบายให้คนเข้าใจเรื่องนี้อย่างมีสติมากขึ้น

คงต้องถามประชาไทว่า เป็น ไท จริงหรือ? หรือเป็นทาสใคร? หรือความคิดอะไร?

แล้วต่างจากสื่อเลวอื่นๆอย่างไร?


เมื่อให้ข้อมูลเพิ่มเติมในประชาไทไม่ได้ ก็ขอให้ที่นี่แล้วกัน
มูลค่าทรัพย์สินที่ Forbes เอาไปจัดอันดับ คือมูลค่าทรัพย์สินของทรัพย์สินส่วนพระมหากษัตริย์ เป็นทรัพสินของสถาบัน ไม่ใช่ทรัพย์สินของบุคคล

ส่วนที่เป็นทรัพย์สินเฉพาะบุคคลนั้น แยกเป็นอีกส่วนหนึ่งที่เรียกว่าทรัพย์สินส่วนพระองค์ ซึ่งต้องเสียภาษีเหมือนคนอื่นๆใต้รัฐธรรมนูญเดียวกัน

ส่วนจะมีมูลค่าเท่าใดนั้นไม่ทราบ

อ่านรายละเอียดเกี่ยวกับกฎหมายเรื่องนี้ได้ที่ http://www.crownproperty.or.th/history.php

หวังว่าปราชาไทได้อ่านแล้วจะเกิดความละอายแก่ใจบ้างนะครับ คนไทยไม่ได้กินหญ้าไปซะทุกคน คิดเองได้ จะคิดอ่านอย่างไร เอาความจริงมาคุยให้หมดดีกว่า

พูดความจริงครึ่งเดียวก็เท่ากับโกหกครับ

วันศุกร์, สิงหาคม 10, 2550

๕๐ หรือ ๔๐ กับ คมช. หรือ ทักษิณ

ดูรัฐธรรมนูญ ๕๐ ที่ออกมาแล้วรู้สึกผิดหวัง ส่วนที่เป็นจุดอ่อนของ ๔๐ ไม่ได้แก้ แต่ไปแก้อะไรที่ไม่เข้าท่า และไม่มีเหตุมีผลสนับสนุนเพียงพอ

โดยภาพรวมแล้วต้องบอกว่าฉบับ ๔๐ ยังดีกว่า ขอให้แก้ส่วนที่เปิดช่องให้เกิดการยึดอำนาจอธิปไตยผ่านสภาอย่างที่เคยเกิดขึ้นโดยรัฐบาลทักษิณ และเพิ่มช่องทางการมีส่วนร่วมของภาคประชาชนอย่างเป็นรูปธรรม

แค่สองเรื่องหลักๆก็น่าจะพอ

ปัญหาคือคมช.ไปตั้งธง(ผิดๆ)เอาไว้ว่า ๔๐ คือ ทักษิณ และ ๕๐ คือ คมช. ทำให้เกิดสภาพแบบ "ถอยไม่ได้" และเปิดช่องให้ทักษิณรุกผ่านช่องทางนี้

๔๐ คือ ทักษิณ ทั้งๆที่ ๔๐ โดนชำเราโดยทักษิณ

เศร้านะครับ

ส่วนภาคประชาชน น่าเสียใจเหมือนกันว่าขบวนการประชาธิปไตยบริสุทธิ์ไม่ประกาศตัวเองให้ชัดเจนว่าไม่ยืนข้างเผด็จการรัฐสภา กลับไป "แสวงจุดร่วม" ผิดที่ผิดทาง ทำให้การรณรงค์ต้านการยึดอำนาจไม่สามารถเดินไปได้สะดวกนัก

เพราะถึงคนไม่ชอบเผด็จการทหาร แต่ก็รังเกียจเผด็จการรัฐสภายิ่งกว่า

ไม่ว่าผลจะเป็นอย่างไร เชื่อว่าผู้แพ้ก็เหมือนเดิม

"ประเทศไทย" ครับ

วันจันทร์, กรกฎาคม 30, 2550

ลุงบุญมีได้ควายคืนก็เลิกได้

แต่ควายข้ายังอยู่เมืองนอกนี่หว่า จะให้ข้าเลิกได้ไง

อิอิ

คนเขียนบทนี่เหลือเกินจริงๆ

วันพฤหัสบดี, กรกฎาคม 05, 2550

อ่าน Agile Web Development with Rails ( 11 )

ทีนี้มาดูว่าเขาใช้ AJAX ใน Rails กันอย่างไร

ปกติเราใส่ปุ่มเข้าไปใน Rails โดยแทรกโค้ดง่ายๆดังนี้

<%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %>

ซึ่งในเวลาทำงานจะสร้างโค้ด html อย่างนี้

<form method="post" action="/store/add_to_cart/1" class="button-to" >
<input type="submit" value="Add to Cart" />
</form>

เราเอา AJAX มาใช้ตรงนี้โดยการแทนที่แท็ก button_to โดยโค้ดนี้

<% form_remote_tag :url => { :action => :add_to_cart, :id => product } do %>
<%= submit_tag "Add to Cart" %>
<% end %>

คำสั่ง form_remote_tag ใช้สร้างฟอร์ม โดยโค้ดระหว่างบล็อก do - end จะเป็น elements ในฟอร์มที่สร้างขึ้น

นอกจากนี้ เพื่อให้ Rails รับรู้การใช้งาน AJAX เราต้องไปเพิ่มคำสั่ง javascript_include_tag ที่ head ใน app/views/layouts/store.rhtml ดังนี้

<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot" , :media => "all" %>
<%= javascript_include_tag :defaults %>
</head>

โค้ดที่เขียนขึ้นจะถูกเรียกโดย add_to_cart แต่เราจะไม่ใช้ app/views/store/add_to_cart.rhtml อันเก่า (ลบทิ้งซะ) แต่จะใช้ app/views/store/add_to_cart.rjs แทน ดังนี้

page.replace_html("cart" , :partial => "cart" , :object => @cart)

เช่นนี้เอง

วันพุธ, กรกฎาคม 04, 2550

อ่าน Agile Web Development with Rails ( 10 )

ทีนี้เรื่อง partial templates หรือที่เรียกย่อๆว่า partials

ลองดูโค้ดนี้

<table>
<% for cart_item in @cart.items %>
<tr>
<td><%= cart_item.quantity %>×</td>
<td><%= h(cart_item.title) %></td>
<td class="item-price" ><%= number_to_currency(cart_item.price) %></td>
</tr>
<% end %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>


เขียนใหม่โดยใช้ partials ได้อย่างนี้

<table>
<%= render(:partial => "cart_item" , :collection => @cart.items) %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>

ส่วน cart_item จะแยกไว้อีกไฟล์หนึ่ง app/views/store/_cart_item.rhtml

<tr>
<td><%= cart_item.quantity %>×</td>
<td><%= h(cart_item.title) %></td>
<td class="item-price" ><%= number_to_currency(cart_item.price) %></td>
</tr>

คำสั่ง render ในไฟล์แรกจะแสดงผล app/views/store/_cart_item.rhtml (โปรดสังเกตว่ามี _ นำหน้า) โดยจะวนลูปให้อัตโนมัติครับ

วิธีนี้ทำให้เราสามารถเขียน partials ไปแปะแทรกไว้ที่ไหนก็ได้ที่ต้องการได้ทุกเมื่อครับ

วันอังคาร, กรกฎาคม 03, 2550

อ่าน Agile Web Development with Rails ( 9 )

เก็บหนังสือไปนาน กลับมาอ่านกันต่อครับ

มาดูการจัดการ error บ้าง สิบปากว่าไม่เท่าตาเห็น ดูโค้ดเอาเองก็แล้วกัน

app/controllers/store_controller.rb

def add_to_cart
begin
product = Product.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}" )
flash[:notice] = "Invalid product"
redirect_to :action => :index
else
@cart = find_cart
@cart.add_product(product)
end
end

คราวนี้ถ้าเรียก http://localhost:3000/store/add_to_cart/wibble แทนที่จะเจอ error เจ้า error ก็จะไปอยู่ใน log/development.log แล้ว อย่างงว่า wibble คืออะไร สำหรับ Rails แล้ว สิ่งที่ใส่ต่อท้ายก็คือ parameter ID นั่นไงครับ

ปัญหาอีกอย่าคือ error message ที่เราคาดหวังยังไม่โผล่ ต้องไปใส่โค้ดนี้ที่ app/views/layouts/store.rhtml ด้วย

<% if flash[:notice] -%>
<div id="notice" ><%= flash[:notice] %></div>
<% end -%>

โดยทั่วไปจะไว้บบบนสุดก่อนข้อความอื่นใดนะครับ

วันเสาร์, มิถุนายน 23, 2550

Britain's Got Talent

สลับฉากด้วยรายการ TV การแข่งขัน Britain's got telent
Connie Talbot น่าประทับใจมากกับเด็กอายุ 6 ขวบคนนี้
Paul Potts เป็นหนังดราม่าเลยครับ

ร้องไห้เลย

วันศุกร์, มิถุนายน 22, 2550

อ่าน Agile Web Development with Rails ( 8 )

ทีนี้ลองดัดแปลง cart ให้มีส่วนของจำนวนสินค้าด้วย

เพิ่ม model ดังนี้ app/models/cart_item.rb

class CartItem
attr_reader :product, :quantity
def initialize(product)
@product = product
@quantity = 1
end
def increment_quantity
@quantity += 1
end
def title
@product.title
end
def price
@product.price * @quantity
end
end


แก้ไฟล์ app/models/cart.rb เพิ่ม mothod นี้

def add_product(product)
current_item = @items.find {|item| item.product == product}
if current_item
current_item.increment_quantity
else
@items << CartItem.new(product)
end
end

แล้วแก้ app/views/store/add_to_cart.rhtml ให้เป็นดังนี้

Your Pragmatic Cart
<ul>
<% for cart_item in @cart.items %>
<li><%= cart_item.quantity %> × <%= h(cart_item.title) %></li>
<% end %>
</ul>

แก้เสร็จแล้วต้อง
rake db:sessions:clear
เพื่อล้างข้อมูล sessions เก่าที่เก็บไว้ใน database

ตอนนี้สั้นๆแค่นี้เอง ถือว่าพักผ่อน

อ่าน Agile Web Development with Rails ( 7 )

คราวนี้เราจะมาดูเรื่อง cart กันครับ โดยจะเก็บข้อมูล cart ไว้ใน session

Rails เตรียมเรื่องนี้ไว้ให้แล้ว เราสามารถเพิ่ม session เข้าไปใน data model ดังนี้
rake db:sessions:create
จะได้ไฟล์ db/migrate/004_add_sessions.rb ขึ้นมา แล้วก็
rake db:migrate
table ชื่อ sessions จะถูกสร้างขึ้นมาครับ

สิ่งที่เราต้องทำต่อคือ เปิดไฟล์ config/environment.rb เข้าไปปลด # ให้บรรทัดนี้ทำงาน
config.action_controller.session_store = :active_record_store
เพราะ default จะบันทึกข้อมูลใน session ลงไฟล์ครับ

ต้อง restart เว็บเซิร์ฟเวอร์ใหม่ session ถึงจะเริ่มทำงานครับ

ขั้นต่อไปคือการสร้าง data model ของ cart โดยสร้างไฟล์ชื่อ app/model/cart.rb ดังนี้
class Cart
attr_reader :items

def initialize
@items = []
end

def add_product(product)
@items << product
end
end
โปรดสังเกตว่าเราไม่สร้างไฟล์นี้โดย script/generate เพราะอันนั้นใช้สร้างเฉพาะ model ที่เชื่อมต่อกับ table ในฐานข้อมูลโดยตรงครับ กรณีนี้ไม่ใช่ คราวนี้ไปที่ app/controllers/store_controller.rb เพิ่ม 2 method นี้เข้าไป

private
def find_cart
session[:cart] ||= Cart.new
end

def add_to_cart
@cart = find_cart
product = Product.find(params[:id])
@cart.add_product(product)
end

ยังจำได้ไหมครับ ตอนที่แล้ว ใน app/views/store/index.rhtml มีบรรทัดนี้อยู่
<%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %>

ถ้าเราเรียกตอนนี้ก็จะขึ้น error เพราะยังไม่ได้กำหนด view ให้เลย
ก็ต้องสร้างไฟล์ app/views/store/add_to_cart.rhtml

<ul>
<% for item in @cart.items %>
<li><%= h(item.title) %></li>
<% end %>
</ul>

ทีนี้ cart ก็เริ่มใช้งานได้แล้วครับ

วันพฤหัสบดี, มิถุนายน 21, 2550

อ่าน Agile Web Development with Rails ( 6 )

ตอนที่แล้วเรายุ่งอยู่กับหลังบ้านของ depot คราวนี้มาจัดหน้าบ้านบ้างครับ

เราจะสร้าง controller ใหม่ขึ้นมาอีกอันหนึ่ง ให้ชื่อว่า store
ruby script/generate controller store index
index ที่แปะท้ายเพิ่มมาจากที่เราคุ้นเคยนั้นมีเพื่อบอกให้ Rails สร้าง action ชื่อ index ใส่ไว้ใน controller นี้ด้วยครับ

การทำอย่างนี้ นอกจาก Rails จะสร้าง app/controllers/store_controller.rb แล้ว ยังสร้าง app/views/store/index.rhtml ให้เราด้วยเลย

ที่ app/controllers/store_controller.rb เราจัดการแก้โค้ดให้เป็นดังนี้
class StoreController < ApplicationController
def index
@products = Product.find_products_for_sale
end
end

แล้วเราก็ไปแก้ product model เพิ่ม mothod ชื่อ find_products_for_sale เข้าไปดังนี้
def self.find_products_for_sale
find(:all, :order => "title" )
end

คำสั่ง find จะคืนค่ากลับมาเป็น array ของข้อมูลจาก product ที่มีเงื่อนไข :all (เอาหมด) และเรียงลำดับตามฟิลด์ "title" ที่ระบุโดย :order => "title"

คราวนี้ไปจัดการกับ app/views/store/index.rhtml ให้เป็นอย่างนี้

Your Pragmatic Catalog
<% for product in @products -%>
<div class="entry" >
<img src="<%= product.image_url %>" />
<%= h(product.title) %>
<%= product.description %>
<%= number_to_currency(product.price) %>
<%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %>
</div>
<% end %>


คำสั่ง h() ใช้ถอด HTML Elements ออกจากข้อความ
- ที่อยู่นำหน้า %> ใช้ บอกให้ไม่ต้องขึ้นบรรทัดใหม่หลังคำสั่งนี้

ส่วนเจ้า add_to_cart นี่เราจะไปคุยกันตอนหน้าครับ

อ่าน Agile Web Development with Rails ( 5 )

จากตอนที่แล้ว คำสั่ง scaffold ใน controller มีอิทธิฤทธิ์ยิ่งนัก สามารถสร้างสิ่งมหัศจรรย์จากสูญญากาศ
แต่สุดยอดวิชาย่อมต้องมีจุดอ่อน อะไรที่ดีมากๆ จุดอ่อนก็คือ มันดีเกินไป

คือมันสมบูรณ์แบบเกินไปครับ สมบูรณ์แบบจนไม่รู้จะไปแก้ไขตรงไหนดี เพราะไม่มีที่ให้แก้ให้ปรับเลย

แต่ทางออกย่อมมีเสมอ เมื่อมี dynamic scaffold ก็ย่อมต้องมี static scaffold อยู่คู่กัน เป็นอีกทางเลือกหนึ่งซึ่งยุ่งยากกว่านิดหน่อย แต่ก็สามารถพลิกแพลงได้หลากหลายกว่ามากครับ

ruby script/generate scaffold product admin
product บอก model ที่ใช้ ในขณะที่
admin ระบุ controller ครับ

สิ่งสำคัญที่เราได้จากการนี้คือ rhtml หนึ่งพวงใหญ่อยู่ใน /app/views/admin/
ทีนี้อยากแก้ตรงไหนก็ตามสบายเลยครับ

เมื่อส่วนที่ rhtml พวกนี้จัดการคือ html ย่อมต้องมีส่วนของ css อยู่ที่ไหนสักที่
นั่นคือ public/stylesheets/ ครับ โดยปกติถ้าไม่ระบุ css file ที่ใช้ public/stylesheets/scaffold.css จะถูกเรียกใช้ by default ครับ

หากเราต้องการเปลี่ยนไปใช้ css file อื่น ก็ควรสร้างและเก็บไว้ที่ public/stylesheets/ นี้เช่นเดียวกันครับ

ส่วนที่ระบุเรื่อง css นี้จะเก็บแยกอยู่ใน app/views/layouts/con_name.rhtml ครับ ไฟล์นี้จะถูกสร้างตอนที่เราใช้คำสั่ง ruby script/generate scaffold model_name con_name ครับ

เปิดไฟล์ layout นี้ดูแล้วมองหาส่วนที่กำหนด css ครับ
<%= stylesheet_link_tag 'scaffold' %>
สมมติว่าเราอยากให้ใช้ depot.css ด้วยก็แก้เป็น
<%= stylesheet_link_tag 'scaffold' , 'depot' %>

แค่นี้เองครับ

อ่าน Agile Web Development with Rails ( 4 )

ทีนี้ลองปรับเปลี่ยน product ดู
ruby script/generate migration add_price
จะได้ไฟล์สำคัญที่ชื่อ db/migrate/002_add_price.rb
ยังจำได้ไหมว่าครั้งที่แล้วเรา generate model product แล้วได้ db/migrate/001_create_products.rb มา

เลข 001, 002 นี้ Rails สร้างขึ้นเพื่อควมคุมลำดับของการเปลี่ยนแปลง data model

ทีนี้แก้ไข db/migrate/002_add_price.rb ให้เป็นอย่างนี้
class AddPrice < precision =""> 8, :scale => 2, :default => 0
end
def self.down
remove_column :products, :price
end
end

แล้ว rake db:migrate

เรียก http://host_name/admin คงพอเดาได้ไม่ยากนะครับว่าจะเกิดอะไรขึ้น

ทีนี้ลองไปที่ app/models/product.rb แล้วใส่โค้ดเพิ่มเติมเข้าไป

class Product < ActiveRecord::Base
validates_presence_of :title, :description, :image_url
validates_numericality_of :price
validates_uniqueness_of :title
validates_format_of :image_url,
:with => %r{\.(gif|jpg|png)$}i,
:message => "must be a URL for a GIF, JPG, or PNG image"
protected
def validate
errors.add(:price, "should be at least 0.01" ) if price.nil? || price < 0.01
end
end

พระเจ้าจ๊อดมันยอดมากเลยใช่ไหมครับ model มันมีไว้ทำงี้นี่เอง

อ่าน Agile Web Development with Rails ( 3 )

ตอนที่แล้วทำให้เห็นภาพของสององค์ประกอบหลักในสถาปัตยกรรม MVC ใน Rails ยังขาดอยู่อีกตัวหนึ่งคือ M - Model ซึ่งเราจะได้เห็นกันในระหว่างการทดลองสร้าง application ตัวอย่างที่ชื่อ depot นี้ครับ

Rails รองรับการใช้งานฐานข้อมูลหลายตัว เราสามารถกำหนดได้ว่าจะใช้ตัวไหนตั้งแต่ตอนสร้าง application เช่น
rails app_name --database=oracle
หากไม่กำหนดดังนี้ rails จะเลือกใช้ค่า default คือ mysql ครับ

นอกจากนี้เรายังสามารถแก้ไขโดยตรงในไฟล์ config/database.yml พร้อมกับการกำหนดชื่อฐานข้อมูล และ username/password ก็ได้
Rails ไม่ได้บังคับเรื่องชื่อของฐานข้อมูลที่ใช้ แต่ตามข้อตกลงแล้ว ควรจะเป็นชื่อเดียวกับ application_*
เช่น application ชื่อ depot ฐานข้อมูลที่ใช้ระหว่างพัฒนาก็ควรเป็น depot_development

เมื่อกำหนดข้อมูลใน config/database.yml แล้ว สามารถทดสอบ config ได้โดย
rake db:migrate
เจ้า rake นี่ก็คือ make ของ ruby นั่นเองครับ

อ้อ... อย่าลืม create database และ user พร้อมกำหนดสิทธิ์ให้เรียบร้อยก่อน rake นะครับ ไม่งั้นไม่ผ่านแน่ๆครับ

เอาเป็นว่าตอนนี้เราสร้าง app ชื่อ depot และอยู่ใน working directory แล้ว โดยมีฐานข้อมูลพร้อมแล้วด้วยนะครับ

ทีนี้ก็กำหนด data model สำหรับสินค้าใน depot ชื่อโมเดล (และตาราง) คือ product ครับ
ruby script/generate model product
จะได้ไฟล์มากองนึง แต่ที่น่าสนใจมี 2 ไฟล์คือ app/models/product.rb และ db/migrate/001_create_products.rb (โปรดสังเกตว่าอันหลังมี s แถมท้ายชื่อ model มาให้ด้วย)

ไฟล์ app/models/product.rb คือตัว model ซึ่งเราจะมาดูทีหลังครับ
ตอนนี้ดูที่ db/migrate/001_create_products.rb กันก่อน เราจะแก้ไขไฟล์นี้ให้เป็นอย่างนี้ครับ

class CreateProducts < ActiveRecord::Migration
def self.up
create_table :products do |t|
t.column :title, :string
t.column :description, :text
t.column :image_url, :string
end
end

def self.down
drop_table :products
end
end

method ชื่อ up จะถูกเรียกให้ทำงานเมื่อเราสั่ง rake db:migrate
จะจัดการสร้าง table ชื่อ productsให้เราครับ

วิธีนี้ทำให้การพัฒนา application สะดวกขึ้น เพราะสามารถควบคุม version ได้
กรณีนี้ ถ้าเรียก rake db:migrate -VERSION=0 เจ้า method ชื่อ down ก็จะถูกเรียก tabel ชื่อ products ก็จะหายไป
การ rake db:migrate โดยไม่ระบุ VERSION ก็จะสร้าง VERSION ปัจจุบัน ทั้งนี้ Rails จะรู้ได้ว่า VERSION ในฐานข้อมูลคือ VERSION ไหนได้โดยสร้าง table ชื่อ schema info มาเก็บค่า VERSION ไว้ครับ

ทีนี้มาสร้าง controller ที่ใช้จัดการ products
ruby script/generate controller admin
เช่นเดิม เราจะสนใจเฉพาะ app/controllers/admin_controller.rb โดยเข้าไปเพิ่มเพียงหนึ่งบรรทัดให้เป็นอย่างนี้
class AdminController < ApplicationController
scaffold :product
end
คำสั่ง scaffold ใช้กำหนดให้ Rails สร้างโค้ดสำหรับจัดการ ข้อมูลใน model product ระหว่าง runtime

ไม่เชื่อก็ต้องเชื่อ เรียก http://host_name/admin จะเห็นได้ว่าเราสามารถจัดการกับข้อมูลใน product ได้แล้ว ทั้ง add, edit, remove ได้หมดเลย

คำสั่งเดียวแท้ๆ

อ่าน Agile Web Development with Rails ( 2 )

เราสร้าง application โดย Rails โดย
rails app_name
ซึ่งจะสร้าง directory ชื่อ app_name และไฟล์อะไรกระจุกกระจิกจำนวนหนึ่งซึ่งเราจะยังไม่สนใจตอนนี้
cd app_name

ทีนี้สร้าง controller โดยใช้คำสั่ง
ruby script/generate controller con_name
ซึ่งจะสร้างไฟล์หลายไฟล์เหมือนกัน แต่เราจะสนใจแค่อันเดียวก่อนคือ app/controllers/con_name_controllers.rb ซึ่งเป็น class กลวงๆอันนึง หากเราสร้าง method ขึ้นมาใน class นี้ จะเรียกว่าเป็น action

action นี้จะทำงานเมื่อเราเรียก http://host_name/con_name/action_name

แต่เราต้องกำหนดรูปแบบการแสดงผลให้ด้วยโดยการสร้าง view ขึ้นมา โดย view ที่จะตอบสนองกับ action นี้จะเป็นไฟล์ app/views/con_name/action_name.rhtml

ไฟล์ rhtml นี้ก็คือไฟล์ html ที่อนุญาตให้แทรกโค้ด ruby เข้าไปได้ ระหว่างแท็ก <% %> เรียกว่า ERb (Embeded Ruby) เหมือนกับ php หรือ asp นั่นเอง

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

ตัวอย่างดังนี้ครับ
ฝั่ง controller (apt/controllers/say_controller.rb)
class SayController < ApplicationController
def hello
@time = Time.now
end
def goodbye
end
end

ที่ฝั่ง view (apt/views/say/hello.rhtml)
แทรกโค้ดนี้เข้าไปเพื่อแสดงเวลา
<%= @time %>
แทรกโค้ดนี้เข้าไปเพื่อแสดงลิงก์ไปยัง action goodbye
<%= link_to "Goodbye!" , :action => "goodbye" %>

เป็นตัวอย่างง่ายๆของการใช้งาน Rails ครับ

วันพุธ, มิถุนายน 20, 2550

อ่าน Agile Web Development with Rails ( 1 )

// นี่คือชอร์ตโน้ตระหว่างอ่านเพื่อทบทวนความเข้าใจของตัวเอง
หากอ่านไม่รู้เรื่องขอให้ทำใจ ขออภัยในความไม่สะดวกไว้ ณ ที่นี้

สถาปัตยกรรมของ Rails อิงแนวคิด MVC ของลุง Trygve Reenskaug
คือ Model-View-Controller

Model จัดการข้อมูลและ Business Rules
View จัดการเรื่องการแสดงผล
Controller รับคำสั่งจากผู้ใช้ เพื่อไปประมวลผล

สำหรับ Rails คำสั่งจากผู้ใช้จะมาที่ Router ก่อน โดย Router จะส่งต่อคำสั่งไปยัง action ใน Controller ที่ใช้จัดการคำสั่งนั้น

หากมีส่วนที่เกี่ยวข้องกับข้อมูลก็จะติดต่อกับส่วน Model ซึ่งใน Rails นี้คือ Active Record Model

ผลลัพธ์จะถูกนำเสนอสู่ผู้ใช้ทาง View ครับ

Active Record ของ Rails จะยึดตาม ORM (Object Relational Mapping) Layer การดีไซน์ฐานข้อมูลโดยเริ่มจาก Active Record Model ของ Rails เป็นความคิดที่ดีมาก เพราะสะดวกกับการเลือกใช้ DB Engine ที่หลากหลายในภายหลัง

View ใน Rails, dynamic content ที่สร้างจาก templating scheme มีอยู่ 3 แนวด้วยกัน
- rhtml ซึ่งเป็นวิธีพื้นฐานที่สุด แทรก ruby code ลงใน html เรียกว่า ERb (Embeded Ruby)
- rmxl ใช้ ruby code สร้าง xml
- rjs สร้าง javascipt code เพื่อให้ไปรันที่ฝั่ง browser เหมาะสำหรับ dynamic AJAX

Controller เป็นหัวใจของ application รับงานจาก user, ติดต่อกับ model, ส่งต่อไปให้ view แสดงผล, จัดการ session รับงานสารพัดสารเพทุกอย่างที่เหลือทั้งหมดแม้กระทั่งการจัดการ cache เพื่อเพิ่ม performance

วันอังคาร, มิถุนายน 19, 2550

วิกฤติมาร

อันเนื่องมาแต่โคลงห้าพัฒนาของนายทิวาในกระทู้นี้

http://www.pantip.com/cafe/writer/topic/W5279514/W5279514.html

เขียนเป็นโคลงห้าด้อยพัฒนา เขียนแล้วรู้สึกว่าหนักเกินไป ไม่อยากลงในกระทู้หนังสือครูหนอน ขอหลบมาลงที่นี่แทน

วิกฤติมาร

ทุกหย่อมหญ้า วิกฤติ
มารสุมไฟ ท่วมฟ้า
หวังให้พัง ทับโลก
โฉดช้าบ้า สารเลว

อำนาจทั้ง เงินตรา
กอปรอัตตา แก่กล้า
คุณธรรม ลืมหมด
ขีดเส้นฟ้า กาหมาย

หวังว่ายเวิ้ง กลางหาว
กอบดวงดาว กลับบ้าน
ทับถมกอง สมบัติ
กี่ล้านล้าน จะพอ

ดับด่าวดิ้น แดดาย
ที่ฝังกาย อาจไร้
เพียงชื่อยัง ปรากฏ
คือผู้ใต้ ต่ำตีน ทุกตีน ฯ

วันจันทร์, มิถุนายน 18, 2550

บทวิพากษ์งานแปลบันทึกโจวต้ากวานในเมืองโบราณ

เมืองโบราณฉบับล่าสุดมีบทวิพากษ์งานแปลบันทึกของโจวต้ากวาน

ผู้วิพากษ์เปรียบเทียบคุณภาพงานแปลของเฉลิมยงบุญเกิดโดยเปรียบเทียบกับฉบับแปลภาษาอังกฤษและฝรั่งเศส!

แต่ผมว่าดูเป็นวิธีที่ไม่เข้าท่า ทำไมไม่เทียบกับฉบับจีนโดยตรง

เพราะการสรุปว่าเฉลิม ยงบุญเกิดแปลผิดเพราะเนื้อความไม่ตรงกับฉบับแปลภาษาอื่นๆ ดูจะเป็นตรรกะที่ไม่ถูกต้อง

ยกตัวอย่างบางข้อที่ชัดเจน เรื่องระดับน้ำที่เปลี่ยนแปลง เฉลิมแปลว่า 7-8 จ้าง ฉบับภาษาอังกฤษและฝรั่งเศสแปลตรงกันว่า 7-8 ฟาธอม ผู้วิพากษ์สรุปว่าเฉลิมแปลผิด

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

แล้วทำไมจีนถึงต้องเอาหน่วยวัดตัวเองไปผูกกับฟาธอมของฝรั่งด้วย

ควรทบทวนครับ

วันพุธ, มิถุนายน 13, 2550

แปลงฐานข้อมูล tis-620 เป็น utf8 (ภาค ๒)

จากเรื่องเดิม



http://crazyhorse-th.blogspot.com/2007/03/tis-620-utf-8.html



คราวนี้ต้องย้ายฐานข้อมูลเก่าที่เป็น tis-620 โดยรหัสดันเป็น latin1 ไปลง utf8 ใน MySQL5



มึนอยู่นาน สุดท้ายจัดการได้ง่ายๆ



1. dump ฐานข้อมูลเก่าออกมา

2. แปลงข้อมูลเป็น utf8 โดย
iconv -f iso8859-11 -t utf8 -o dump_utf.sql dump.sql

3. เข้าไปแก้ dump file จาก latin1 ให้เป็น utf8 ให้หมด

4. import เข้าไปโดยกำหนดรหัสเป็น utf8



เรียบร้อยครับ








Powered by ScribeFire.

วันพุธ, มีนาคม 28, 2550

กระทู้แปลกๆในห้องสมุด

หมู่นี้มีกระทู้แปลกๆในห้องสมุดพันทิพ



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



แนวทางรวมๆคือชี้นำเรื่องที่เป็นความไม่เข้าใจของสังคมไทยเพื่อมุ่งดิสเครดิตราชวงศ์และระบอบกษัตริย์แบบอ้อมๆ



ถ้าเป็นปกติ เรื่องแบบนี้คุยกันให้เข้าใจได้อย่างบริสุทธิ์ใจ

แต่นี่ดูมีเจตนาแอบแฝงเป็นกระบวนการยังไงไม่รู้



เล่นกันแบบนี้ท่าทางจะจบยากนะ

Web Usability

Alertbox: Jakob Nielsen's Newsletter on Web Usability

แปะไว้ก่อน ว่างแล้วจะมาอ่าน

วันอังคาร, มีนาคม 27, 2550

ข่าวลือ อาวุธการเมืองที่ไม่เคยเก่า

ในขณะที่มีกระทู้ในห้องสมุดที่ดูแล้วเป็นขบวนการดิสเครดิตสถาบันอย่างผิดปกติ (ล่าสุดมาอีกอันหนึ่งแล้ว)

ยังมีข่าวลือที่ว่ากันว่าถูกแพร่ในกลุ่มทหาร(จริงหรือเปล่าไม่รู้) มีนัยกลับกัน คือกล่าวหาคมช.ว่าทำปฏิวัติโดย... เอาเป็นว่าจี้สถาบันว่างั้น

ดูแล้วก็เป็นข่าวที่แปลก และมีจุดมุ่งหมายที่ชัดเจนอีกเช่นกัน

ถ้าเป็นนักการตลาดก็เรียกว่าแยกแบรนด์ทำตลาดตาม market segmentation

คุ้นๆนะ

GotoKnow ถูกปิดกั้นโดยสำนักงานตำรวจแห่งชาติ

http://gotoknow.org/blog/tutorial/85179



เห็นข่าวนี้แล้วก็แปลกใจ ยิ่งอ่านรายละเอียดต่อไปถึง



บล็อกนี้



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



ปัญหาเดียวกันนี้เกิดขึ้นกับระบบของ ICT ซึ่งเคยมีคนมือบอนไป submit แจ้งปิดมั่วๆ ทั้ง google.com และเว็บไซต์ของ ICT เองก็ยังเคยโดน



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



ที่น่าคิดยิ่งกว่านั้น คือมองในมุมตรงกันข้าม ตัวป่วนอาจจะไม่ได้แค่มือบอน แต่จงใจสร้างสถานการณ์



น่าเสียดายว่าหลายๆคนมีความรู้พอจะเข้าใจได้ว่าอะไรเกิดขึ้น แต่อคติมันบังตาจนรีบลงความเห็นเกินไป



แต่ที่น่าคิดกว่านั้น รัฐเองอาจจะต้องทบทวนแนวคิดในการบล็อกความคิดเห็นใหม่ครับ



หมดยุครัฐตำรวจแล้ว!

วันจันทร์, มีนาคม 19, 2550

ธุรกิจตามกระแสกล้องดิจิทัล

ทุกวันนี้กล้องดิจิทัลขายระเบิด โอกาสธุรกิจก็เปิดสำหรับคนที่มองเห็น
ดูดดี ดอทคอม
อย่างอื่นไม่รู้ แต่้ Silica Gel ที่เป็นสารดูดความชื้นขายดีแน่ๆ เพราะไม่มีขายในร้านสะดวกซื้อหรือดิสเคานท์สโตร์

วันอังคาร, มีนาคม 13, 2550

ความเข้าใจ(ผิดๆ)เรื่องวรรณยุกต์

สมัยเด็กไม่รู้เหมือนกันว่าถูกปลูกฝังไว้ตอนไหนว่าภาษาไทยมีเอกลักษณ์ที่มีการใช้วรรณยุกต์เป็นเสียงดนตรี โดดเด่นจากภาษาไทยๆในโลก

ที่ว่าเด็กนี่จำไม่ได้ว่าเด็กขนาดไหน เอาเป็นว่าตั้งแต่จำความได้ก็ฝังหัวอย่างนี้แ้ล้ว(ถึงแม้ผมจะจำความได้ค่อนข้างช้าสักหน่อยก็ตาม)

เรื่องนี้สอดคล้องกับสมมติฐานของผมว่า เด็กพร้อมจะรับความเชื่อที่มีคนสอนอย่างง่ายดาย โดยไม่สนใจข้อเท็จจริงหรือตรรกะใดๆ

ที่ว่าอย่างนี้ก็เพราะว่าผมเรียนโรงเรียนจีนมาแต่เด็ก เรียนภาษาจีนกลาง ส่วนที่บ้านก็พูดจีนแต้จิ๋วด้วย

แต่กลับไม่เคยเอะใจเลยว่าทั้งจีนกลางและจีนแต้จิ๋วนี้ก็มีวรรณยุกต์ใช้ด้วยกันทั้งสิ้น

จีนกลางมีวรรณยุกต์ 4 เสียง อิง หยาง ส่าง ชวี่

จีนแต้จิ๋วมีกี่เสียงไม่แน่ใจ เพราะสำเนียงจีนแต้จิ๋วในไทยมันกลายจนฟังไม่ออก แต่เขาว่ามี 9 เสียง

เท่ากับจีนกวางตุ้งพอดี

และไม่น่าแปลกใจเลยว่าจีนสำเนียงอื่นๆย่อมต้องมีวรรณยุกต์ใช้ด้วยแน่นอน

วันหนึ่งเมื่อนานมาแล้ว จู่ๆผมก็เอะใจขึ้นมา เอ๊ะ วรรณยุกต์จีนก็มีนี่นา ทำไมถึงว่าไทยเรามีชาติเดียว

ลองค้นดูคร่าวๆยังพบว่า เวียดนามก็มี เอ... มันชักจะยังไงอยู่

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

เข้าใจละ ที่ต่างกันก็เพราะภาษาไทยเป็นเสียงดนตรีนี่เอง เราถึงไม่เหมือนเขา มีวรรณยุกต์เหมือนกัน แต่ของเราเป็นโน้ต เท่กว่ากันแยะ

ย้อนกลับไปทำความเข้าใจกันหน่อย
เสียงวรรณยุกต์ของจีนกลาง มี 4 เสียง
อิง เป็นเสียงเรียบแบบ -
หยาง เป็นเสียงที่ไล่สูงขึ้นแบบ /
ส่าง เป็นเสียงลดต่ำลงแล้วกลับไล่สูงขึ้นแบบ V
ชวี่ เป็นเสียงลดต่ำลงแบบ \

วันก่อนลอนนึกครึ้มใจลองไล่ดูเสียงวรรณยุกต์ไทยว่าตรงกับโน้ตตัวไหน
สามัญ นี่ เร หรือเปล่านะ
เอก นี่ คงเป็น โด
เอ๊ะ มันยังไง ทำไม เอก ต่ำกว่าสามัญหรือ?
โท เฮ้ย ไล่ยังไงก็ไม่ถูก มันโน้ตอะไรกันแน่

ชักข้องใจ เลย search หาใน google.com ดู

ผ่าง!

เสียงวรรณยุกต์ไทยไม่ใช่เสียงดนตรีจ้าาาาาาาาา

ทางสัทศาสตร์จะเป็นอย่างนี้
สามัญ คือ เสียงกลาง (middle)
เอก คือ เสียงต่ำ (low)
โท คือ เสียงไล่ลง (falling)
ตรี คือ เสียงสูง (high)
จัตวา คือ เสียงไล่ขึ้น (rising)

พอมองเห็นความจริงแล้ว

ถึงต้องปรับโลกทัศน์บ้าง

แต่คิดว่าจะมีความคิดในแนวทางที่ถูกต้องมากขึ้น

(เขียน 2006-07-30)

วันจันทร์, มีนาคม 12, 2550

มโนมอบให้ท่านทักษิณ

กวีอังคาร กัลยาณพงศ์เคยโคลงเขียน "เหน็บ" พวกซ้ายจัดในยุคหนึ่งว่า


มโนมอบแด่มาร์กซ เลนิน
แขนมอบสตาลิน เทอดหล้า
ดวงใจมอบโฮจิมินห์ นาพ่อ
เกียรติศักดิ์รักข้า มอบให้เหมาเจ๋อตง

มาถึงยุึคนี้ ขอแก้ใหม่เป็น

มโนมอบให้ท่าน ทักษิณ
แขนมอบให้กลุ่มชิน เทอดหล้า
ดวงใจมอบเนวิน นาพ่อ
เกียรติศักดิ์รักข้า มอบให้ไทยรักไทย

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

ราชดำเนินเปลี๊ยนไป๋

ค้น google.com หลงไปเจอกระทู้เก่าราชดำเนินพันทิพในลิงก์นี้

P2587090 จิตร ภูมิศักดิ์ ฮีโร่ที่ไม่ฮิต สำหรับหนุ่มสาว ยุคนี้ [สังคม]

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

ยังไม่รู้ว่าประเทศไทยจะหลุดจากสภาพแบบนี้ไปได้ยังไง

วันอาทิตย์, มีนาคม 11, 2550

แปลงฐานข้อมูล TIS-620 เป็น UTF-8

Download ได้จากที่นี่ชื่อ UTF-8 Converter
AppServNetwork
ใช้ง่ายและเรียบร้อยดีทีเดียว อย่าลืม backup ไปใส่ database อื่นก่อนทำด้วยนะ เพราะเขาลุยทั้ง database เลย

วันเสาร์, มีนาคม 10, 2550

Sunrise, Sunset Calendars and Local Time

Sunrise, Sunset Calendars and Local Time

เวลามืด/สว่างในแต่ละวันของเมืองต่างๆทั่่วโลก เป็นประโยชน์มากสำหรับการวางแผนท่องเที่ยว

ภาษาเวียดนาม ต้มยำภาษา

ภาษาเวียดนามเป็นภาษาที่แปลก

โดยคำพื้นฐานทำให้ถูกจัดอยู่ในกลุ่มเดียวกับมอญ-เขมร

ในขณะเดียวกันก็มีความแตกต่างจากภาษากลุ่มมอญเขมรหลายประการ

- เป็นภาษาที่มีวรรณยุกต์ เหมือนภาษาไทยและภาษาจีน ในขณะที่มอญ-เขมรไม่มีวรรณยุกต์

- ไวยากรณ์มอญ-เขมรเป็น ประธาน-กรรม-กริยา แต่เวียดนามเป็น ประธาน-กริยา-กรรม เหมือนจีนและไทย แต่มีความแตกต่างกับจีนอยู่ที่เอาคำวิเศษณ์ตามหลังคำนาม ซึ่งเหมือนกับภาษาไทย นอกจากนั้นยังมีไวยากรณ์กระจุกกระจิกอีกหลายอย่างที่เหมือนภาษาไทย มองในแง่ไวยากรณ์แล้ว เวียดนามถือเป็นฝาแฝดของภาษาไทยได้เลย

- คำในภาษาเวียดนาม ถ้าไม่ใช่คำพื้นฐานแล้ว รับคำจากจีนไปเยอะมาก ทำนองเดียวกับที่ไทยรับคำบาลี-สันสกฤตและเขมรเข้ามาเยอะมาก แต่คุยกันไม่รู้เรื่องเพราะคำพื้นฐานต่างกัน



น่าสนใจทีเดียว







powered by performancing firefox

วันพุธ, กุมภาพันธ์ 28, 2550

HDR น่าคิดเหมือนกันว่าอนาคตจะเป็นอย่างไร

การถ่ายภาพภายใต้สภาพที่แสงมีความแตกต่างกันมากจนเกินขอบเขตของ Dynamic Range ของกล้องจะรับมือได้ด้วยการถ่ายเพียงครั้งเดียว



แต่ถ้าถ่ายมากกว่าหนึ่งครั้งภายใต้การปรับตั้งที่เหมาะสม ทุกอย่างก็เป็นไปได้



นี่แหละ HDR - High Dynamic Range Photography



ค้นเอาเอง google มีเพียบ





powered by performancing firefox

WYSIWYG HTML text editor

WYSIWYG HTML text editor 2 ตัวที่น่าสนใจ

FCKEditor กับ TinyMCE