<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Thai Ruby On Rails</title><link>http://www.thairor.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/thairor" /><description></description><language>en</language><managingEditor>noreply@blogger.com (Apirak)</managingEditor><lastBuildDate>Wed, 15 Feb 2012 22:23:15 PST</lastBuildDate><generator>Blogger http://www.blogger.com</generator><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">26</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">25</openSearch:itemsPerPage><feedburner:info uri="thairor" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><itunes:explicit>no</itunes:explicit><itunes:subtitle></itunes:subtitle><item><title>การติดตั้ง RVM บน Ubuntu (แถมการติดตั้ง Passenger)</title><link>http://feedproxy.google.com/~r/thairor/~3/wt0JuqJaAYY/rvm-ubuntu-passenger.html</link><category>rvm</category><category>ubuntu</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Sun, 12 Jun 2011 03:00:35 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-537140845784662360</guid><description>RVM คือคำสั่ง/สภาพแวดล้อม ที่ทำให้เราสามารถติดตั้งและเรียกใช้ Ruby หลายเวอร์ชั่นได้อย่างสะดวกสบาย ลำบากแค่กดคีย์บอร์ดไม่กี่ที&lt;br /&gt;
&lt;br /&gt;
คราวก่อน คุณ Neokain เขียนวิธี&lt;a href="http://www.thairor.com/2011/05/rvm-mac-os-x-snow-leopard.html"&gt;การติดตั้ง RVM บน Mac&lt;/a&gt; ไปแล้ว คราวนี้ผมจะเขียนในส่วนของ Ubuntu ดูบ้าง ซึ่งขั้นตอนต่างๆ เกือบจะเหมือนกันทั้งหมด มีรายละเอียดที่แตกต่างไปบ้างเล็กน้อย&lt;br /&gt;
&lt;br /&gt;
จุดเด่นของ Ubuntu (และลินุกซ์ดิสโทรตระกูล Debian) คือเรื่องระบบการจัดการแพ็คเกจ APT ไม่ว่าจะเป็น apt-get หรือ aptitude ก็ตาม ที่สามารถติดตั้งไบนารีแพ็คเกจได้อย่างรวดเร็วและประสิทธิภาพก็ไม่ได้ต่างไปจากการคอมไพล์ซอร์สโค้ดเองเท่าไหร่นัก โดยเฉพาะเครื่องสำหรับใช้พัฒนา การใช้ *nix ที่ต้องคอมไพล์แพ็คเกจจากซอร์สโค้ดเอง ไม่ว่าจะเป็น *BSD, Gentoo หรือ MacPorts ดูจะเป็นการเสียเวลาและเปลืองไฟฟ้าโดยใช่เหตุ&lt;br /&gt;
&lt;br /&gt;
ขั้นตอนแรกที่สำคัญมาก คือต้องติดตั้งไลบรารีพื้นฐานให้ครบก่อน ไม่อย่างนั้นจะต้องคอมไพล์ซ้ำหลายรอบ (ครั้งแรกผมโดนไป 5)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ sudo aptitude install build-essential libssl-dev libreadline6-dev zlib1g-dev&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ต่อไปเป็นการติดตั้งสคริปท์ RVM โดยเลือกติดตั้งได้สองแบบคือ single-user กับ multi-user โดยทั่วไปแนะนำให้ติดตั้งแบบ single-user ดีกว่า เนื่องจากซอร์สโค้ดทั้งหมดจะถูกเก็บไว้อยู่ในพาธ $HOME ของเราเอง ทำให้การติดตั้งแพ็คเกจผ่าน RubyGems ในอนาคตไม่ต้องใช้สิทธิ์ root แต่หากต้องการติดตั้งแบบ multi-user ก็ให้เติม sudo ลงไปข้างหน้าคำสั่ง แล้ว RVM ก็จะถูกนำไปติดตั้งอยู่ที่ /usr/local/rvm ให้แทน&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ bash &amp;lt; &amp;lt;(curl -s https://rvm.beginrescueend.com/install/rvm)&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
จากนั้นให้นำโค้ดข้างล่างนี้ไปแปะไว้ในไฟล์ ~/.bashrc สำหรับ single-user และ /etc/profile สำหรับ multi-user ตามลำดับ&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;amp;&amp;amp; . "$HOME/.rvm/scripts/rvm"&lt;/pre&gt;&lt;br /&gt;
&lt;pre class="brush: bash"&gt;[[ -s "/home/YOURNAME/.rvm/scripts/rvm" ]] &amp;amp;&amp;amp; source "/home/YOURNAME/.rvm/scripts/rvm"&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
เสร็จแล้วให้สั่งเริ่มการทำงานของเชลล์ใหม่ เพื่อให้คำสั่ง rvm ไปอยู่ใน $PATH ของระบบให้เราเรียกใช้ได้สะดวกๆ&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ source ~/.bashrc&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ดู Ruby เวอร์ชั่นต่างๆ ที่สามารถติดตั้งได้&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ rvm list known | less&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ปกติผมใช้ Matz's Ruby แต่ถ้าจะใช้ JRuby ก็ให้ติดตั้ง JDK (openjdk-6-jdk) ก่อน&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ rvm install 1.9.2&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ดูรายการ Ruby ที่ติดตั้งไว้แล้ว&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ rvm list&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
เลือก Ruby ที่จะใช้เป็นค่าปริยาย (default)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ rvm use 1.9.2 --default&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
จากนั้นจะมีคำสั่ง "ruby" ให้เราเรียกใช้ได้&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ ruby -v&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ส่วนการติดตั้ง Passenger ผ่าน RubyGems ก็ไม่มีอะไรยาก&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ gem install passenger --no-ri --no-rdoc&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
เสร็จแล้วเลือกว่าจะให้มันทำงานกับ Apache หรือ Nginx ถ้าเป็น Apache ก็สั่งคำสั่งข้างล่างนี้ได้เลย แล้วทำตามคำแนะนำที่ปรากฎ ซึ่งเป็นคำแนะนำการติดตั้งแพ็คเกจที่ดีที่สุดตั้งแต่ผมเคยใช้ลินุกซ์มา&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ passenger-install-apache2-module&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
โดยทั่วไปมันจะบอกให้เราติดตั้งแพ็คเกจเหล่านี้ก่อน&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ sudo aptitude install libcurl4-openssl-dev apache2-prefork-dev libapr1-dev libaprutil1-dev&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
เสร็จแล้วก็ทำตามคำแนะนำในขั้นตอนสุดท้าย โดยเอาโค้ดไปใส่ไว้ในไฟล์ /etc/apache2/mods-available/passenger.load แล้วสั่งให้ Apache เริ่มทำงานใหม่&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ sudo a2enmod passenger
 $ sudo apache2ctl restart&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ส่วนการติดตั้งใช้กับ Nginx นั้นแตกต่างออกไป เนื่องจากจะต้องผูก Passenger เข้าไปตั้งแต่ตอนคอมไพล์ ซึ่งต้องใช้สิทธิ์ root โดยเราจะทำการติดตั้งผ่านคำสั่ง rvmsudo จากนั้น Passenger จะให้เราเลือกว่าจะคอมไพล์ Nginx วิธีไหน ระหว่างให้มันไปดาวน์โหลดซอร์สโค้ดมาให้ กับให้เราไปเลือกดาวน์โหลดเอง โดยทั่วไปวิธีแรกจะได้ Nginx เวอร์ชั่นที่เก่ากว่านิดหน่อย&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ rvmsudo passenger-install-nginx-module&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ที่เหลือเป็นวิธีการตั้งค่า virtual host ศึกษาได้คู่มือของ Apache หรือ Nginx&lt;br /&gt;
&lt;br /&gt;
ในกรณีปกติ Nginx จะใช้หน่วยความจำน้อยกว่า Apache และจากผลการทดสอบของนักพัฒนาท่านอื่นๆ ได้ผลลัพธ์ว่า Apache ทำงานได้ดีกับ dynamic content ส่วน Nginx ทำงานได้ดีกับ static content แต่ก็เห็นหลายๆ ท่านใช้ Nginx เป็น reverse proxy รับ request แล้วส่งต่อไปให้ Apache ทำงาน ซึ่งก็ได้ผลลัพธ์เป็นที่น่าพอใจ&lt;br /&gt;
&lt;br /&gt;
ขอพลังแห่ง Ruby จงสถิตย์แก่ท่าน&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-537140845784662360?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/wt0JuqJaAYY" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-12T17:00:35.586+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/05/rvm-ubuntu-passenger.html</feedburner:origLink></item><item><title>มาเล่น Cloud Foundry กันเถอะ</title><link>http://feedproxy.google.com/~r/thairor/~3/y-DAH70BQWw/cloud-foundry.html</link><author>noreply@blogger.com (Ritwan)</author><pubDate>Sun, 29 May 2011 00:50:03 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-3862998567030626426</guid><description>&lt;div&gt;บทความนี้เป็นบทความแรกของผม ถ้ามีอะไรผิดพลาดก็ขออภัยด้วยครับ :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Cloud Foundry คือแพลตฟอร์มสำหรับการประมวลผลแบบกลุ่มเมฆซึ่งให้บริการโดยVMware Cloud Foundry มีความแตกต่างจากGoogle App Engineตรงที่รองรับภาษาและเฟรมเวิร์คได้หลากหลายกว่า(Spring, Rails and Node.js) อีกทั้งยังเป็นโอเพ่นซอร์สที่ทำให้เราสามารถเข้าถึงซอร์สโค้ดของCloud Foundry ด้วยสัญญาอนุญาติแบบMITครับ รายละเอียดภาษาไทยเพิ่มเติมอ่านได้จาก &lt;a href="http://www.blognone.com/news/23035"&gt;Blognone&lt;/a&gt; ครับ&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ก่อนอื่นเราต้องลงทะเบียนเพื่อขอinviteที่ &lt;a href="http://cloudfoundry.com/signup"&gt;http://cloudfoundry.com/signup&lt;/a&gt; หลังจากนั้นก็รอให้ทีมงานapproved ขั้นตอนนี้อาจจะใช้เวลาหน่อยน่ะครับ(ของผมใช้เวลาประมาณสัปดาห์)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;สำหรับคนที่มีaccountแล้วก็มาเริ่มกันเลยครับ เริ่มจากการติดตั้ง vmc command line tool ด้วยคำสั่ง&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ sudo gem install vmc&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;สำหรับท่านใดที่ใช้บริการอินเตอร์เน็ตของ3BB อาจจะเจอerrorแบบนี้&lt;/div&gt;&lt;pre class="brush: bash"&gt;ERROR:  Could not find a valid gem 'vmc' (&amp;gt;= 0) in any repository&lt;br /&gt;ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)&lt;br /&gt;   too many connection resets (http://rubygems.org/latest_specs.4.8.gz)&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;ให้แก้ไขโดยการติดตั้งผ่านproxyครับ&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ sudo gem install --http-proxy http://123.456.7.89:1234 vmc&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;เมื่อติดตั้งเสร็จแล้วให้ทำการทดสอบว่าใช้งานได้หรือไม่ด้วยคำสั่ง&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ vmc target api.cloudfoundry.com&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;ทำการloginด้วยอีเมล์และรหัสผ่านชั่วคราวที่ได้มา&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ vmc login&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;อย่าลืมเปลี่ยนรหัสผ่านให้เป็นของเราเองตามคำแนะนำในอีเมล์ครับ&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ vmc passwd&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;ผมเริ่มต้นด้วยการสร้างแอพใหม่ชื่อว่า esper-blog&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ rails new esper-blog&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;สำหรับการใช้railsบนCloud Foundry ยังมีข้อจำกัดและสิ่งที่ต้องระวังอยู่ครับ สามารถอ่านได้จาก &lt;span class="Apple-style-span" style="color: rgb(68, 68, 68); font-family: Arial, Helvetica, sans-serif; "&gt;&lt;span class="Apple-style-span"&gt;&lt;a href="http://support.cloudfoundry.com/entries/20019747-ruby-and-cloudfoundry-things-to-know"&gt;Ruby and CloudFoundry: Things to know&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;ต่อไปให้เราเพิ่มthin, rakeและbundlerเข้าไปใน Gemfile ครับ (ข้อควรระวัง: ให้ใช้rake 0.8.7น่ะครับ เพราะ0.9.0ไม่สามารถใช้งานได้ครับ)&lt;/div&gt;&lt;pre class="brush: bash"&gt;source 'http://rubygems.org'&lt;br /&gt;gem 'rails', '3.0.7'&lt;br /&gt;gem 'bundler'&lt;br /&gt;gem 'sqlite3'&lt;br /&gt;gem 'rake', '0.8.7'&lt;br /&gt;gem 'thin'&lt;/pre&gt;&lt;br /&gt;ก่อนจะdeploy อย่าลืมสั่ง bundle package, bundle install ก่อนน่ะครับ สำหรับการdeployก็ง่ายแสนง่าย เพียงสั่ง&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ vmc push&lt;br /&gt;Would you like to deploy from the current directory? [Yn]: กดEnter&lt;br /&gt;Application Name: esper-blog ใส่ชื่อแอพพลิเคชั่น&lt;br /&gt;Application Deployed URL: 'esper-blog.cloudfoundry.com'? กดEnter&lt;br /&gt;Detected a Rails Application, is this correct? [Yn]: กดEnter&lt;br /&gt;Memory Reservation [Default:256M] (64M, 128M, 256M, 512M, 1G or 2G) ผมกดEnterเพื่อใช้แค่ 256M&lt;br /&gt;Creating Application: OK&lt;br /&gt;Would you like to bind any services to 'esper-blog'? [yN]: กดEnter&lt;br /&gt;Uploading Application:&lt;br /&gt; Checking for available resources: OK&lt;br /&gt; Processing resources: OK&lt;br /&gt; Packing application: OK&lt;br /&gt; Uploading (13K): OK  &lt;br /&gt;Push Status: OK&lt;br /&gt;Staging Application: OK                                                        &lt;br /&gt;Starting Application: OK&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;สุดท้ายลองเปิดWeb Browserขึ้นมาแล้วใส่URLของเราลงไปครับ&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;หลังจากมีการแก้ไขแอพพลิเคชั่น สามารถdeployโดยใช้คำสั่ง&lt;/div&gt;&lt;div&gt;&lt;pre class="brush: bash"&gt;$ vmc update&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;สามารถอ่านข้อมูลเพิ่มเติมได้ที่นี่ครับ &lt;a href="http://support.cloudfoundry.com/"&gt;support.cloudfoundry.com&lt;/a&gt; บทความอาจจะสั้นไปนิดน่ะครับ ขอให้สนุกน่ะครับ&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-3862998567030626426?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/y-DAH70BQWw" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-29T14:50:03.603+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/05/cloud-foundry.html</feedburner:origLink></item><item><title>ปัญหา RubyGems Warning หลังจากอัพเกรด</title><link>http://feedproxy.google.com/~r/thairor/~3/uQzChMvFDJ4/rubygems-warning.html</link><category>Ruby</category><author>noreply@blogger.com (Phuwanart Larpmark)</author><pubDate>Fri, 13 May 2011 19:29:43 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-4702314927104830959</guid><description>&lt;p&gt;หลังจากที่อัพเกรด ruby gem เป็นเวอร์ชั่นล่าสุด (1.8.2) ปรากฎว่ารันโปรเจ็กต์จะมีแจ้งเตือนว่า&lt;/p&gt;
&lt;pre class="brush: bash"&gt;NOTE: Gem::Specification#default_executable= is deprecated with no replacement. It will be removed on or after 2011-10-01.
Gem::Specification#default_executable= called from /Users/phuwanart/.rvm/gems/ruby-1.9.2-p180@global/specifications/rake-0.8.7.gemspec:10.
&lt;/pre&gt;
&lt;p&gt;ซึ่งมันจะยาวมาก วิธีการแก้ไขก็คือให้กลับไปใช้ gem รุ่นเก่าก่อน&lt;/p&gt;
&lt;pre class="brush: bash"&gt;$ gem update --system 1.7.2
&lt;/pre&gt;
&lt;p&gt;แต่เราไม่ต้องตกใจไป เราสามารถอัพเกรด gem ของเราได้ แต่เพียงว่าตอนนี้ยังไม่แนะนำ&lt;/p&gt;
&lt;p&gt;ที่มา: &lt;a href="http://pivotallabs.com/users/alex/blog/articles/1687-rubygems-warningitis-outbreak"&gt;RubyGems Warningitis Outbreak&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-4702314927104830959?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/uQzChMvFDJ4" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-14T09:29:43.719+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/05/rubygems-warning.html</feedburner:origLink></item><item><title>ลง RVM บน Mac OS X Snow Leopard</title><link>http://feedproxy.google.com/~r/thairor/~3/eCaeTTmM7Us/rvm-mac-os-x-snow-leopard.html</link><category>Ruby</category><author>noreply@blogger.com (Phuwanart Larpmark)</author><pubDate>Tue, 03 May 2011 03:20:37 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-7178420937453369008</guid><description>&lt;p&gt;เนื่องด้วยว่า rails2 และ rails3 ใช้ ruby คนละ version และถึงแม้ว่า rails3 จะยังใช้ได้กับ ruby 1.8.x แต่ก็มี gem บางตัวที่ต้องการ ruby 1.9.x เป็นผลว่าทำให้ต้องมี ruby หลาย version ในเครื่องเดียวกัน ซึ่งในที่นี้เราจะใช้ &lt;a href="https://rvm.beginrescueend.com/"&gt;RMV&lt;/a&gt; ช่วยจัดการ ruby ที่อยู่ในเครื่องของเรา&lt;/p&gt;
&lt;h4&gt;ติดตั้ง RVM&lt;/h4&gt;
&lt;p&gt;เปิด Terminal แล้วพิมพ์คำสั่งนี้&lt;/p&gt;&lt;pre class="brush: bash"&gt;$ bash &lt; &lt;(curl -s https://rvm.beginrescueend.com/install/rvm)&lt;/pre&gt;
&lt;p&gt;จากนั้นให้เพิ่มบรรทัดนี้ลงไปใน .bash_profile&lt;/p&gt;&lt;pre class="brush: bash"&gt;[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;&amp; source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.&lt;/pre&gt;
&lt;p&gt;ทดสอบว่าลง RVM สำเร็จโดยสั่ง&lt;/p&gt;&lt;pre class="brush: bash"&gt;$ type rvm | head -1&lt;/pre&gt;
&lt;p&gt;ซึ่งจะได้ผลออกมาดังนี้&lt;/p&gt;&lt;pre class="brush: bash"&gt;rvm is a function&lt;/pre&gt;
&lt;h4&gt;ติดตั้ง Ruby&lt;/h4&gt;
&lt;p&gt;ติดตั้ง ruby 1.8.7 โดยพิมพ์คำสั่งนี้ลงบน terminal&lt;/p&gt;&lt;pre class="brush: bash"&gt;$ rvm install 1.8.7&lt;/pre&gt;
&lt;p&gt;ติดตั้ง ruby 1.9.2 ก็ทำเช่นเดียวกัน&lt;/p&gt;&lt;pre class="brush: bash"&gt;$rvm install 1.9.2&lt;/pre&gt;
&lt;h4&gt;ใช้งาน Ruby&lt;/h4&gt;
&lt;p&gt;เมื่อต้องการจะใช้ ruby 1.8.7 ก็ให้พิมพ์คำสั่งนี้ลง terminal&lt;/p&gt;&lt;pre class="brush: bash"&gt;$ rvm use 1.8.7&lt;/pre&gt;
&lt;p&gt;หากต้องการใช้อีก ruby อีก version ก็ทำเช่นเดิม&lt;/p&gt;&lt;pre class="brush: bash"&gt;$ rvm use 1.9.2&lt;/pre&gt;
&lt;p&gt;หากต้องการให้ version เป็น default ก็ใช้ --default ตามลงไป&lt;/p&gt;&lt;pre class="brush: bash"&gt;$ rvm use 1.9.2 --default&lt;/pre&gt;
&lt;p&gt;เมื่อสลับ ruby ในแต่ละ version แล้ว gem ก็จะเปลี่ยนไปด้วย ทั้งหมดจะถูกแยกตามการลงในแต่ละ version&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-7178420937453369008?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/eCaeTTmM7Us" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-03T17:20:37.981+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/05/rvm-mac-os-x-snow-leopard.html</feedburner:origLink></item><item><title>[PR] ประชาสัมพันธ์ชาว Thai Ruby On Rails</title><link>http://feedproxy.google.com/~r/thairor/~3/RvirmPRUDVs/pr-thai-ruby-on-rails.html</link><category>PR</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Tue, 26 Apr 2011 21:24:21 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-1192298591306109959</guid><description>&lt;p&gt;My name is Parinaya, I work as a Project Manager at MGB Software Company (www.mgb-software.com) which work for software industry, mobile, web/windows applications, and consultancy, and we are leading software house in Bangkok, with an international clients base. We are a partner of Nuxos (http://www.nuxos.fr) Company in Asia. I'm searching for Rails developers to work full time on Rails project for our European partner.&lt;/p&gt;

&lt;p&gt;ผมชื่อปริญญาทำงานตำแน่ง Project Manager อยู่ที่บริษัท MGB Software (www.mgb-software.com) ซึ่งธุรกิจบริษัทเกี่ยวกับซอฟท์แวร์ หรือ software house โดยบริษัทเราพัฒนาด้าน mobile, web หรือ windows applications และเป็นที่ปรึกษาทางด้านซอฟท์แวร์ รายละเอียดเพิ่มเติมอ่านได้ในเวปบริษัทนะครับ (www.mgb-software.com). และบริษัทเรายังเป็นเป็น partner ของบริษัท Nuxos (http://www.nuxos.fr) ทางโซนเอเชีย ตอนนี้ผมกำหลังหา Rails Programmer หลายคนเพื่อมาร่วมงานกันพัฒนาซอฟท์แวร์ให้กับ Partner ของบริษัทผมครับด้วย Rails&lt;/p&gt;

&lt;p&gt;Introduce my partner, His name is Richard Piacentini, he is a Associate Director at Nuxos company (http://www.nuxos.fr) which is one of the most known company doing Ruby &amp;amp; Rails in France. He has been one of the evangelist of Ruby and Rails in France since 2004, and his partner Laurent Julliard are considered as European's Ruby &amp;amp; Rails experts, that He has created the Railsfrance.org (http://www.railsfrance.org) portal, and He is the organiser of the biggest Rails event in France, called Paris on Rails Rails (http://paris.onrails.info/) where the creator of Rails (DHH aka David Heinemeier Hansson) has been speaking in video since the first edition.&lt;/p&gt;

&lt;p&gt;ก่อนอื่นผมต้องขอแนะนำ partner ของบริษัทผมก่อนคือ Richard Piacentini เป็น Associate Director ที่บริษัท Nuxos (http://www.nuxos.fr) เขาเป็นคนสอนและเผยแพร่ Ruby &amp;amp; Rails ในฝรั่งเศสตั้งแต่ปี 2004 และมีหุ้นส่วนอีกคนชื่อ Laurent Julliard โดยทั้งสองคนเป็นผู้เชี่ยวชาญ European's Ruby &amp;amp; Rails Richard เคยเขียนโปรแกรมสร้าง Railfrance Portal (http://www.railsfrance.org) และยังเป็นคนจัด event ที่ใหญ่ที่สุดสำหรับ Rails ในฝรั่งเศสเรียกว่า Paris on Rails Rails (http://paris.onrails.info/) และทำ VDO เกี่ยวกับการสอน Rail ตั้งแต่เวอร์ชันแรกชื่อ DHH aka David Heinemeier Hansson This is his profile on the working with Rails website : http://workingwithrails.com/person/4817-richard-piacentini. And they have translated and adapted 3 of the major Rails &amp;amp; Ruby Book: - Dave Thomas's "Agile Web Development with Rails" - Russ Olsen's "Design Patterns in Ruby" - Chad Fowler's "Rails Recipes"&lt;/p&gt;

&lt;p&gt;เพื่อนๆใน Blog สามารถเข้าไปดูผลงานของ Richard ได้ที่ http://workingwithrails.com/person/4817-richard-piacentini. และผลงานทางด้านหนังสืออีก 3 เล่ม Dave Thomas's "Agile Web Development with Rails", Russ Olsen's "Design Patterns in Ruby", Chad Fowler's "Rails Recipes" I have looked through "Thai Ruby On Rails" Blog that make me interested in your articles, topic, and online community.&lt;/p&gt;

&lt;p&gt;ผมได้อ่านบทความและหัวข้อที่คุยกันใน community นี้แล้วรู้สึกสนใจครับ&lt;/p&gt;

&lt;p&gt;This is a opportunity to know everybody in this community Blog, Richard will be in BKK until the end of next week, He and I are happy to meet some people in "Thai Ruby On Rails", have a drink and exchange about Ruby, Rails and how it's perceived in Thailand.&lt;/p&gt;

&lt;p&gt;ตอนนี้เป็นโอกาสดีที่เพื่อนทุกคนใน Blog จะได้พูดคุยแลกเปลี่ยนความคิดเกี่ยวกับ Ruby on Rails กับ Richard เพราะคนจะกลับฝรั่งเศสวันที่ 22 เดือนนี้ และเค้าสนใจมากที่เจอทุกคนที่อยู่ใน Thai Ruby on Rails นี้ทุกคนเพื่อ หาโปรแกรมเมอเพื่อมาทำงาน Full Time และ แลกเปลี่ยนความรู้กับ Rails ในประเทศไทย&lt;/p&gt;

&lt;p&gt;โดยกลุ่ม Thai Ruby on Rails อาจจะรวบรวมคนที่สนใจและส่ง รายชื่อ, เบอร์โทร, และอีเมล์ ให้ผม หรือติดต่อผมโดยตรงตาม contact ด้านล่างครับ&lt;/p&gt;

&lt;p&gt;ใครสนใจติดต่อผมด่วนนะครับ&lt;/p&gt;

&lt;p&gt;If there is any questions you can contact me below: email : parinya.k@mgb-software.com&lt;/p&gt;

&lt;p&gt;ปล. ผมต้องขออภัยคุณปริญญาด้วยนะครับ ที่ลงประกาศให้ช้าไป&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-1192298591306109959?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/RvirmPRUDVs" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T11:24:21.937+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/04/pr-thai-ruby-on-rails.html</feedburner:origLink></item><item><title>สร้างไฟล์ PDF แบบชิวๆ จาก HTML และ CSS ด้วยภาษา Ruby</title><link>http://feedproxy.google.com/~r/thairor/~3/WHFwHOQ1PjM/pdf-html-css-ruby.html</link><category>PDF</category><category>Ruby</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Sun, 15 May 2011 19:03:39 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-5090178742099016163</guid><description>&lt;p&gt;การสร้างไฟล์ PDF ด้วยภาษา Ruby ในวันนี้เป็นเรื่องง่ายดายมาก เนื่องจากมีไลบรารีให้เลือกใช้มากถึง 2 ตัว (เป็นอย่างน้อย) คือ &lt;a href="https://github.com/sandal/prawn"&gt;Prawn&lt;/a&gt; และ &lt;a href="https://github.com/jdpace/PDFKit"&gt;PDFKit&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/sandal/prawn"&gt;Prawn&lt;/a&gt; สร้าง PDF ด้วยท่ายาก อยากได้อะไรก็เขียนโค้ดเอา ความสามารถล้นเหลือ เหมาะกับ PDF ที่มีความซับซ้อน แถมมีตัวอย่างให้ดูเยอะมาก ซอร์สโค้ดอยู่ในโฟลเดอร์ &lt;em&gt;examples&lt;/em&gt; ส่วน PDF ผลลัพธ์อยู่ในโฟลเดอร์ &lt;em&gt;reference_pdfs&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jdpace/PDFKit"&gt;PDFKit&lt;/a&gt; สร้าง PDF ง่ายๆ จากวัสดุที่หาได้ตามธรรมชาติ คือ HTML+CSS ธรรมดาๆ โดยตัวมันทำหน้าที่เป็นเพียง Ruby binding ของไลบรารี่ &lt;a href="http://code.google.com/p/wkhtmltopdf/"&gt;wkhtmltopdf&lt;/a&gt; อีกที&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt; งานของผมเหมาะกับ PDFKit มากกว่า ส่วนการได้มาซึ่ง HTML และ CSS นั้นหรูหราเล็กน้อย กล่าวคือ สร้าง HTML จาก Slim และสร้าง CSS จาก Sass (SCSS)&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/stonean/slim"&gt;Slim&lt;/a&gt; คือเครื่องมือสำหรับสร้าง HTML โดยไม่ต้องเขียนโค้ด HTML แต่เขียนด้วยโค้ดที่สั้นกระชับและสะอาดตากว่ามาก ได้แรงบันดาลใจมาจาก Haml + Jade แต่ทำงานได้เร็วกว่า&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sass-lang.com/"&gt;Sass&lt;/a&gt; คือเครื่องมือสำหรับสร้าง CSS ที่เพิ่มความสามารถเข้าไปในโค้ด CSS ธรรมดา เช่น มีตัวแปร มีฟังก์ชัน สามารถ import/include ส่วนของโค้ดได้ เรียกว่า DRY - Don't Repeat Yourself กันสุดลิ่มทิ่มประตู โดยผมใช้มันผ่าน &lt;a href="http://compass-style.org/"&gt;Compass&lt;/a&gt; อีกที&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h4&gt;สร้าง HTML จาก Slim&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt; โดยปกติเราใช้ Slim กันในฐานะเป็น Views ของ Rails ซึ่งไม่มีปัญหาอะไรน่าตื่นเต้น แต่กรณีนี้เราเรียกใช้ Slim template โดยตรง ซึ่งในเอกสารเขาเขียนวิธีเรียกใช้สั้นๆ แค่ว่า&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;Tilt.new['template.slim'].render(scope)
Slim::Template.new(filename, optional_option_hash).render(scope)
Slim::Template.new(optional_option_hash) { source }.render(scope)&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; คำที่ไม่เข้าใจคือ "scope" - what's a scope? เดาได้เบื้องต้นว่ามันน่าจะเป็นออปเจ็คอะไรสักอย่าง แต่การทดลองเบื้องต้นพบว่า ส่งอะไรไปมันก็ไม่รู้จักท่าเดียว ไม่ว่าจะเป็น Model object หรือ Hash&lt;br /&gt; &lt;br /&gt; เนื่องจากมัน based on Tilt เราก็ไปเปิดเอกสารของ &lt;a href="https://github.com/rtomayko/tilt"&gt;Tilt&lt;/a&gt; อ่านต่อ จากตัวอย่างจะเห็นชัดเจนว่า scope เป็นได้ทั้ง Model object และ Hash ซึ่งเราก็ทำเหมือนมันเป๊ะๆ แต่ทำไมยังคอมไพล์ไม่ผ่านสักที บอกแต่ว่าไม่รู้จักตัวแปรที่เราเรียกใช้ใน template&lt;br /&gt; &lt;br /&gt; โชคดีได้พี่ป๊อก (&lt;a href="http://twitter.com/pphetra"&gt;@pphetra&lt;/a&gt;) มาช่วยดู ท่าไม้ตายของพี่แกคือไปแกะซอร์สโค้ดแม่งเลย แล้วก็พบว่า error อยู่ตรงคำสั่ง instance_evl() ซึ่งเมธอดนี้จะทำงานได้ก็ต่อเมื่อถูกเรียกใช้ในรูปแบบนี้&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;{:say =&amp;gt; 'Hello'}.instance_eval('puts fetch(:say)', '', 0)&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; สรุปแบบง่ายๆ คือถ้าเราส่ง object อะไรเข้าใน template ตอนเรียกใช้ก็ให้เสมือนว่าเราเป็น object นั้นเสียเอง ตัวอย่าง&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;person = Person.find(:name =&amp;gt; 'Jane')
Slim::Template.new('template.slim').render(person, :say =&amp;gt; 'Hello')&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; #template.slim&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;p = '%s says %s' % [name, fetch(:say)]&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h4&gt;สร้าง PDF จาก HTML+CSS&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt; ก่อนอื่นต้องติดตั้ง wkhtmltopdf ก่อน จะทำผ่าน APT หรือ build source ก็ตามแต่ลำบาก ส่วนวิธีใช้ PDFKit ก็ลอกจากตัวอย่างเลย&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;pdf = PDFKit.new('template.html')
pdf.stylesheets &amp;lt;&amp;lt; 'template.css'
pdf.to_file('output.pdf')&lt;/pre&gt;
&lt;p&gt;ปัญหาเดียวที่พบคือ แสดงภาษาไทยไม่ได้ !! โฮลี่ ชิท นี่มันเมกะโพรเบล็มเลยนะเว้ย สันนิษฐานว่าน่าจะเป็นที่ encoding ของไลบรารี่สักตัว ไม่ PDFKit ก็ wkhtmltopdf งมโข่งอยู่นานมาก ทั้งอ่าน manual และค้นหาจาก Google ซึ่งก็ไม่เจอเบาะแสใดๆ ในเอกสารของ PDFKit บอกเพียงว่า encoding เป็น UTF-8 โดยปริยายอยู่แล้ว ... แล้วปัญหาอยู่ตรงไหนล่ะ?&lt;/p&gt;
&lt;p&gt;โชคยังดีอยู่ ตรงที่เราไปลองสร้าง PDF ด้วยการใส่ URL ของเว็บไซต์เข้าไป แล้วมันดันแสดงภาษาไทยได้สวยงาม&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;PDFKit.new('http://google.co.th').to_file('output.pdf')&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; แล้วปัญญาก็เกิดปิ๊งทันที ปัญหานี้แก้ได้ด้วยโค้ดบรรทัดเดียว ... ไม่เฉลยด้วย ปล่อยให้เป็นเส้นผมบังภูเขาของท่านอื่นต่อไป ฮ่าๆ&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-5090178742099016163?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/WHFwHOQ1PjM" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-16T09:03:39.432+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/03/pdf-html-css-ruby.html</feedburner:origLink></item><item><title>ปัญหาการแสดงผล form error message บน Rails 3</title><link>http://feedproxy.google.com/~r/thairor/~3/DigCxqrkz2c/form-error-message-rails-3.html</link><category>form</category><category>rails3</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Wed, 27 Apr 2011 21:18:33 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-1689819961971810625</guid><description>&lt;p&gt;เป็นที่ทราบกันดีอยู่แล้วว่า Rails 3 มีความแตกต่างจาก Rails 2 อยู่มากพอสมควร ฟังก์ชันหลายๆ อย่างถูกตัดออกไป โดยเฉพาะส่วนที่เกี่ยวข้องกับการแสดงผล เนื่องจากทีมพัฒนาเห็นว่าโค้ดส่วนนี้ไม่ควรจะอยู่ใน Rails core ควรจะปล่อยให้เป็นเรื่องของ application ไปจัดการกันเอง ตัวแรกที่ผมเพิ่งเจอคือ form.error_messages ปัญหามันเกิดแบบ combo ดังรายละเอียดต่อไปนี้&lt;br /&gt;
&lt;br /&gt;
อย่างแรกคือ form.error_messages ถูกตัดออกจาก core ไปแล้ว ทำให้เราไม่สามารถแสดง error ด้วยวิธีเดิมได้ Rails developer ทุกคนเจอปัญหานี้เหมือนกันหมด จึงมีคนสร้าง &lt;a href="https://github.com/rails/dynamic_form"&gt;dynamic_form&lt;/a&gt; ขึ้นมาทดแทน (copyrighted by DHH) คุณ &lt;a href="http://twitter.com/sikachu"&gt;@sikachu&lt;/a&gt; ก็เป็น contributor กับโปรเจ็คนี้ด้วย ใช้งานได้ค่อนข้างดีทีเดียว แต่ยังไม่ถูกใจกับ HTML ที่มันสร้างมาให้ นอกจากนี้ยังมีคนเสนอแนวทางอื่นด้วย เช่น &lt;a href="http://www.emersonlackey.com/article/rails3-error-messages-for-replacement"&gt;คนนี้&lt;/a&gt; และ &lt;a href="http://www.andrewtheis.net/blog/rails-3-and-form-errors.php"&gt;คนนี้&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
ปัญหาต่อมาคือผมใช้ routing แบบ resources (&lt;a href="http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default"&gt;RESTful&lt;/a&gt;)&lt;br /&gt;
&lt;pre class="brush: rails"&gt;def create
  @project = Project.new(params[:project])
  if @project.save
    redirect_to @project, :notice =&gt; 'The project has been saved.'
  else
    flash[:alert] = "Can't save the project."
    redirect_to :action =&gt; :new
    # render :action =&gt; :new
  end
end

def new
  @project = Project.new
end
&lt;/pre&gt;โดยปกติเมื่อ @project.save ไม่ผ่านการ validate มันควรจะ redirect ไปหา :action =&gt; :new แต่จะมีปัญหาว่า error message ที่ผูกอยู่กับ model จะหายไป เนื่องจาก object ถูกสร้างใหม่โดยเมธอด new แล้ว ครั้นจะเปลี่ยน redirect เป็น render ซึ่งสามารถแสดง error message ได้ แต่มันก็จะแปลกๆ ตรงที่ URL จะยังเป็นของ create ('/projects' - path นี้ใช้ร่วมกัน 2 เมธอด คือ index#GET กับ create#POST) ทั้งๆ ที่มันควรจะเป็นของ new มากกว่า ('/projects/new' - new#GET) คนที่ไม่เคยใช้ routing แบบ resources อาจจะงงๆ หน่อยนะครับ : )&lt;br /&gt;
&lt;br /&gt;
ตอนนี้สรุปว่าแก้ปัญหาเรื่อง form.error_messages ได้แล้วล่ะ ปัญหาที่เหลือคือจะจัดการกับ state ของ object อย่างไรดี (หรือผมเข้าใจอะไรผิดไปวะ)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-1689819961971810625?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/DigCxqrkz2c" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-28T11:18:33.706+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/02/form-error-message-rails-3.html</feedburner:origLink></item><item><title>HandlerSocket - ปลั๊กอิน NoSQL สำหรับ MySQL</title><link>http://feedproxy.google.com/~r/thairor/~3/sEEUb-jbXHI/handlersocket-nosql-mysql.html</link><category>mysql</category><category>nosql</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Sun, 15 May 2011 19:07:23 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-8066380860641634699</guid><description>&lt;p&gt;ข่าวอัพเดทที่ตื่นเต้นที่สุดสำหรับผมในช่วงนี้ เห็นจะไม่มีอะไรน่าสนใจไปกว่า "HandlerSocket" ปลั๊กอิน NoSQL แบบ key-value สำหรับ MySQL โดยผลการทดสอบที่ดีที่สุดที่ทีมงานพัฒนานำมายืนยันคือ 750,000 qps (queries per second) เร็วกว่า memcached 1.78 เท่า (memcached ได้ผลลัพธ์ 420,000 qps) และเร็วกว่าการค้นหาแบบ SQL ธรรมดาถึง 7.5 เท่า (SQL ได้ผลลัพธ์ 105,000 qps)&lt;br /&gt; &lt;br /&gt; &lt;a href="http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html"&gt;HandlerSocket&lt;/a&gt; พัฒนาโดยบริษัทชื่อ DeNA ของญี่ปุ่น คนพัฒนาบอกว่าได้มีการนำ HandlerSocket มาใช้งานจริงในระดับ production สำหรับผลิตภัณฑ์ของบริษัทตัวเอง และให้ผลลัพธ์เป็นที่น่าพอใจมาก เขาให้เหตุผลของการพัฒนานวัตกรรมชิ้นนี้ว่า ไม่มีเหตุผลอื่นใดที่เราจะต้องไปคิดค้นพัฒนา ติดตั้งหรือเรียนรู้วิธีการใช้งาน NoSQL ตัวอื่นๆ ในเมื่อ MySQL มันก็สุดยอดอยู่แล้ว เราเพียงแค่ทำช่องทางให้สามารถเข้าถึงข้อมูลผ่านทาง index ได้โดยตรงง่ายๆ เหมือนกับพวก NoSQL แบบ key-value ก็น่าจะช่วยแก้ปัญหาเรื่องความเร็วของการเข้าถึงข้อมูลได้แล้ว&lt;br /&gt; &lt;br /&gt; ทีมพัฒนายังบอกต่ออีกว่า แม้ HandlerSocket จะให้ประสิทธิภาพเทพขนาดนี้ แต่เขาก็ยังใช้งาน memcached อยู่ โดยใช้สำหรับแคชข้อมูลในระดับ front-end จำพวกการแสดงผล HTML และสำหรับ SQL ปกติของ MySQL ก็ยังใช้อยู่เช่นกัน คือใช้ตอนที่จำเป็นต้องใช้คำสั่งที่ซับซ้อนจำพวก join, group by เป็นต้น&lt;br /&gt; &lt;br /&gt; HandlerSocket เขียนด้วย C++ สามารถนำไปติดตั้งเป็นปลั๊กอินสำหรับ MySQL ที่กำลังใช้งานอยู่ได้เลย โดยมันจะทำงานในโหมด daemon จึงรับรองได้ว่าจะไม่มีปัญหากับโปรเจ็คอื่นๆ ที่กำลังทำงานอยู่ในโหมด SQL ปกติอย่างแน่นอน&lt;br /&gt; &lt;br /&gt; เห็นฝรั่งหลายคนบอกว่า HandlerSocket คือตัวเปลี่ยนเกมในสนามรบอันดุเดือดระหว่าง RDBMS และ NoSQL จะจริงเท็จแค่ไหนคงต้องทดสอบด้วยตัวของคุณเองวันนี้ &lt;a href="https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/"&gt;ดาวน์โหลด&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; แล้วเกี่ยวกับ Ruby ตรงไหน? เกี่ยวสิครับ ก็มีคนทำ Ruby binding สำหรับ HandlerSocket ออกมาให้เราได้ใช้งานกันแล้วน่ะสิ&lt;br /&gt; &lt;br /&gt; * &lt;a href="https://bitbucket.org/winebarrel/ruby-handlersocket/src"&gt;https://bitbucket.org/winebarrel/ruby-handlersocket/src&lt;/a&gt;&lt;br /&gt; * &lt;a href="https://github.com/miyucy/handlersocket"&gt;https://github.com/miyucy/handlersocket&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; มีทั้งตัวอย่างการใช้งานและซอร์สโค้ดสำหรับนำไปติดตั้ง&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
require 'handlersocket'

h = HandlerSocket.new(:host =&gt; '127.0.0.1', :port =&gt; '9998')

# open PRIMARY index on widgets.user table, assign it ID #1
h.open_index(1, 'widgets', 'user', 'PRIMARY', 'user_name,user_email,created')

# fetch record from index ID 1, where PRIMARY key is equal to 1
p h.execute_single(1, '=', [1])
# &gt; [0, [["Ilya", "ilya@igvita.com", "2010-01-01 00:00:00"]]]

# open 'id_created' index on widgets.user table, assign it ID #2
p h.open_index(2, 'widgets', 'user', 'id_created', 'user_name,user_email,created')

# fetch record from index ID 2, where id &gt;= 2, and date &gt;= 2010-01-03
p h.execute_single(2, '&gt;=', [2, '2010-01-03'], 10)
# &gt; [0, [["Bob", "bob@example.com", "2010-01-03 00:00:00"]]]
&lt;/pre&gt;

&lt;p&gt;ขอบคุณ &lt;a href="http://www.igvita.com/2011/01/14/handlersocket-the-nosql-mysql-ruby/"&gt;Igvita&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-8066380860641634699?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/sEEUb-jbXHI" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-16T09:07:23.385+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2011/01/handlersocket-nosql-mysql.html</feedburner:origLink></item><item><title>Ruby กลายพันธุ์</title><link>http://feedproxy.google.com/~r/thairor/~3/i_pZb2KFPC4/ruby.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:36:50 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-6273653577049472036</guid><description>&lt;p&gt;ภาษาดีดีจะสร้างแรงบรรดาลใจให้เกิดภาษาใหม่ๆ เหมือนกับที่ Perl Smalltalk และ Lisp เป็นต้นแบบให้กับ Matz ในการพัฒนาภาษา Ruby&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5261953283/" title="ruby_generation by apirakpanatkool, on Flickr"&gt;&lt;img alt="ruby_generation" height="500" src="http://farm6.static.flickr.com/5122/5261953283_749512ef2e.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
แน่นอนว่าภาษาที่มีปรัชญาฉีกกรอบ ไปเน้นความสนุกเวลาพัฒนามากกว่าตอนใช้งาน ย่อมเป็นแรงผลักดันให้เกิดภาษาใหม่ๆ อีกหลายภาษา&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;Mirah: a simpler java&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
ผู้พัฒนาคือ &lt;a href="http://twitter.com/headius"&gt;Charles Nutter&lt;/a&gt; หนึ่งในผู้พัฒนาหลักของ JRuby ทำให้เจ้า &lt;a href="http://www.mirah.org/"&gt;Mirah&lt;/a&gt; หน้าตาเหมือน Ruby แต่มีจุดต่างแบบสุดขั้วคือมันเป็น statically types (with type inference) และมีจุดเด่นคือ compiles เป็น Bytecode โดยตรง (แต่ถ้าอยากให้เป็น Java ก่อนก็ได้)&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;"&gt;fib&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby constant_other_symbol_ruby_19syntax" style="color: #aa6600; font-weight: normal;"&gt;a:&lt;/span&gt;fixnum&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;if&lt;/span&gt; a &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;2&lt;/span&gt;
     a
  &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;else&lt;/span&gt;
     fib(a &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;-&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;1&lt;/span&gt;) &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;+&lt;/span&gt; fib(a &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;-&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;2&lt;/span&gt;)
  &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;
&lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;

puts fib(&lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;10&lt;/span&gt;) &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby" style="color: #888888;"&gt;# =&amp;gt; 55&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ดังนั้นในเชิง engineer แล้วสิ่งที่เหมือนกับ Ruby ก็คือหน้าตาของ code แต่ในเชิงปรัชญาผมคิดว่า Mirah คือ Java ที่เน้นความสนุกในการพัฒนา ที่ได้รับอิทธิพลมาจาก Ruby เต็มๆ&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;&lt;b&gt;Reia: scripting the Erlang VM&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href="http://reia-lang.org/"&gt;Reia&lt;/a&gt; เป็นภาษาที่ได้รับอิทธิพลมาจาก Ruby และ Python แต่ทำงานบน Erlang VM นั่นทำให้ภาษานี้ได้รับข้อดีจาก Ruby คือ code อ่านง่าย เป็น meta-programming ใช้ blocks ได้ และได้ข้อดีของ Erlang คือความ concurrency, distribution และ fault tolerance&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="meta meta_module meta_module_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_module keyword_control_module_ruby" style="color: #008800; font-weight: bold;"&gt;module&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_module entity_name_type_module_ruby" style="color: #003366; font-weight: bold;"&gt;Fibonacci&lt;/span&gt;&lt;/span&gt;
  &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;"&gt;compute&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;a&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;if&lt;/span&gt; a &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;2&lt;/span&gt;
      a
    &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;else&lt;/span&gt;
      compute(a &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;-&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;1&lt;/span&gt;) &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;+&lt;/span&gt; compute(a &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;-&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;2&lt;/span&gt;)
    &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;
&lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;

&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby" style="background-color: #fff0f0; color: #dd2200;"&gt;"Fibonacci: &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source" style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: black;"&gt;#{&lt;span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;"&gt;Fibonacci&lt;/span&gt;.compute(&lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;10&lt;/span&gt;)}&lt;/span&gt;"&lt;/span&gt;.puts() &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby" style="color: #888888;"&gt;# =&amp;gt; 55&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ถ้ามองหาภาษาที่ทรงพลังเหมือน Erlang และสามารถสนุกกับการพัฒนาแบบ Ruby ภาษา Reia คือคำตอบครับ&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;RubyGoLightly: simple concurrency with Go&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://golang.org/"&gt;Go&lt;/a&gt; ถูกพัฒนาโดย Google โดยมีเป้าหมายให้เป็นภาษาตรงกลางที่เบากว่า Java และปลอดภัยกว่า C ส่วนเจ้า &lt;a href="https://github.com/feyeleanor/RubyGoLightly/"&gt;RubyGoLightly&lt;/a&gt; จะเน้นพัฒนาให้ Ruby 1.8 มาอยู่บน &lt;a href="https://github.com/feyeleanor/GoLightly"&gt;GoLightly VM&lt;/a&gt;&amp;nbsp;ดังนั้น ถ้าใครสนใจภาษาที่พัฒนาสนุก และไม่หนักเหมือน Java แต่ปลอดภัยกว่า C ก็ลองเล่น RubyGoLighty ดูนะครับ หรือลองดูตัวอย่างผลงานได้ที่ &lt;a href="https://github.com/feyeleanor/RubyGoLightly/"&gt;relatively small footprint&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;Rite: embeddable Ruby by Matz&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
สุดท้ายคือภาษา Rite ที่ถูกพัฒนาโดย Matz เองเพื่อให้เป็น Ruby ที่เหมาะกับอุปกรณ์เล็กๆ &amp;nbsp;หรืองานประเภท digital appliances หรือ เกมส์ แบบเดียวกับแนวคิดของ Lua&lt;br /&gt;
โครงการ Rite ได้รับการสนับสนุนโดยรัฐบาลญี่ปุ่นโดย Matz สัญญาว่าผลงานจะมีสัญญาการใช้งานเป็น MIT หรือ GPL แต่ตามสัญญามีระยะเวลาในช่วง 2010-2011 ครับ ดังนั้นถ้าสนใจให้ลองเข้าไปดู presentation ที่ &lt;a href="http://www.slideshare.net/yukihiro_matz/rubyconf-2010-keynote-by-matz/64"&gt;RubyConfX&lt;/a&gt; ไปพลางๆ ก่อนครับ&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;&lt;b&gt;Beyound Ruby&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
จะเห็นว่าภาษามีวิวัฒนาการให้เหมาะกับงานมากขึ้นเรื่อยๆ ไม่เหมือนเมื่อก่อนที่มีตัวเลือกค่อนข้างจำกัด ดังนั้นปัจจุบัน&amp;nbsp;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;การเลือกเครื่องมือให้ถูกกับงานจะเป็นเรื่องที่เปลี่ยนผลลัพธ์จากหน้ามือเป็นหลังมือเลยทีเดียว&lt;/span&gt;&lt;/b&gt; สำหรับนักพัฒนารุ่นใหม่ ถ้าคุณคิดจะศึกษาเครื่องมือแค่ตัวเดียว คุณได้เสียความสามารถในการแข่งขันไปแล้วครับ&lt;br /&gt;
&lt;br /&gt;
ที่มา &lt;a href="http://www.igvita.com/2010/12/14/beyond-ruby-mirah-reia-rite/"&gt;www.igvita.com&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-6273653577049472036?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/i_pZb2KFPC4" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:36:50.163+07:00</app:edited><media:thumbnail url="http://farm6.static.flickr.com/5122/5261953283_749512ef2e_t.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/12/ruby.html</feedburner:origLink></item><item><title>ลบช่องว่างหลังบรรทัด ป้องกันปัญหากับ Version Control</title><link>http://feedproxy.google.com/~r/thairor/~3/lgfkuTgQvPE/version-control.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:36:19 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-5804870026478804746</guid><description>&lt;p&gt;โปรแกรม Version Control จะคอยบอกเราว่า Code ของเรามีอะไรเปลี่ยนไปบ้างในแต่ละ Version แต่บางความเปลี่ยนแปลงก็ไม่ควรจะเกิดขึ้น เช่นการมีช่องวางหลังบรรทัดเพิ่มเข้ามา คนแก้ก็ไม่รู้ตัว ส่วนคนอื่นก็สับสนเพราะมันจะไปปนกับบรรทัดที่มีการแก้ไขจริงๆ&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/92185242@N00/5229963237/" title="alt text by apirakpanatkool, on Flickr"&gt;&lt;img alt="alt text" height="87" src="http://farm6.static.flickr.com/5006/5229963237_01e5769f58.jpg" width="471" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
นั่นคือเหตุผลที่เราควรกำจัดช่องว่างหลังบรรทัดก่อนที่จะ commit หรือกำจัดมันทุกครั้งที่ save ซะเลย ตรงนี้ IDE ช่วยเราได้ครับ&lt;br /&gt;
&lt;br /&gt;
สำหรับ TextMate ให้ลง plugin ตัวนี้ &lt;a href="https://github.com/glennr/uber-glory-tmbundle"&gt;uber-glory-tmbundle&lt;/a&gt; ตัว plugin จะแปลง tab ทั้งหมดเป็นช่องว่าง และกำจัดช่องว่างหลังบรรทัดให้เรา&lt;br /&gt;
&lt;br /&gt;
สำหรับ vi ให้เพิ่ม code ชุดนี้ลงในไฟล์ ~/.vimrv ครับ&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em; white-space: pre;"&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_shell" style="background-color: #fff0f0; color: #dd2200;"&gt;" Strip trailing whitespace
function! &amp;lt;SID&amp;gt;StripTrailingWhitespaces()
        "&lt;/span&gt; Preparation: save last search, and cursor position.
        let _s=@/
        let l = line&lt;span class="meta meta_scope meta_scope_subshell meta_scope_subshell_shell"&gt;(&lt;span class="string string_quoted string_quoted_double string_quoted_double_shell" style="background-color: #fff0f0; color: #dd2200;"&gt;"."&lt;/span&gt;)&lt;/span&gt;
        let c = col&lt;span class="meta meta_scope meta_scope_subshell meta_scope_subshell_shell"&gt;(&lt;span class="string string_quoted string_quoted_double string_quoted_double_shell" style="background-color: #fff0f0; color: #dd2200;"&gt;"."&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="string string_quoted string_quoted_double string_quoted_double_shell" style="background-color: #fff0f0; color: #dd2200;"&gt;" Do the business:
        %s/\s\+$//e
        "&lt;/span&gt; Clean up: restore previous search history, and cursor position
        let @/=_s
        call cursor&lt;span class="meta meta_scope meta_scope_subshell meta_scope_subshell_shell"&gt;(l, c)&lt;/span&gt;
endfunction
autocmd BufWritePre * :call &lt;span class="keyword keyword_operator keyword_operator_redirect keyword_operator_redirect_shell" style="color: black; font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span class="meta meta_function meta_function_shell"&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_shell"&gt;SID&amp;gt;StripTrailingWhitespaces&lt;/span&gt;()&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
สำหรับ Netbean ผมค้นเจอ plugin Stripwhitespace ครับ&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.nbm"&gt;http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.nbm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.jar"&gt;http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.jar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;ตอนนี้ยัง Download ได้อยู่แต่ดู Domain แล้วอาจจะอยู่ได้ไม่นาน&lt;br /&gt;
&lt;br /&gt;
ที่มา - &lt;a href="http://rails-bestpractices.com/posts/60-remove-trailing-whitespace"&gt;rails-bestpractices&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-5804870026478804746?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/lgfkuTgQvPE" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:36:19.122+07:00</app:edited><media:thumbnail url="http://farm6.static.flickr.com/5006/5229963237_01e5769f58_t.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><media:content url="http://feedproxy.google.com/~r/thairor/~5/brGTjKSTRk4/org-netbeans-modules-stripwhitespace.jar" fileSize="55321" type="application/x-java-archive" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> โปรแกรม Version Control จะคอยบอกเราว่า Code ของเรามีอะไรเปลี่ยนไปบ้างในแต่ละ Version แต่บางความเปลี่ยนแปลงก็ไม่ควรจะเกิดขึ้น เช่นการมีช่องวางหลังบรรทัดเพิ่มเข้ามา คนแก้ก็ไม่รู้ตัว ส่วนคนอื่นก็สับสนเพราะมันจะไปปนกับบรรทัดที่มีการแก้ไขจริงๆ นั่นคือเหตุผลที</itunes:subtitle><itunes:author>noreply@blogger.com (Apirak)</itunes:author><itunes:summary> โปรแกรม Version Control จะคอยบอกเราว่า Code ของเรามีอะไรเปลี่ยนไปบ้างในแต่ละ Version แต่บางความเปลี่ยนแปลงก็ไม่ควรจะเกิดขึ้น เช่นการมีช่องวางหลังบรรทัดเพิ่มเข้ามา คนแก้ก็ไม่รู้ตัว ส่วนคนอื่นก็สับสนเพราะมันจะไปปนกับบรรทัดที่มีการแก้ไขจริงๆ นั่นคือเหตุผลที่เราควรกำจัดช่องว่างหลังบรรทัดก่อนที่จะ commit หรือกำจัดมันทุกครั้งที่ save ซะเลย ตรงนี้ IDE ช่วยเราได้ครับ สำหรับ TextMate ให้ลง plugin ตัวนี้ uber-glory-tmbundle ตัว plugin จะแปลง tab ทั้งหมดเป็นช่องว่าง และกำจัดช่องว่างหลังบรรทัดให้เรา สำหรับ vi ให้เพิ่ม code ชุดนี้ลงในไฟล์ ~/.vimrv ครับ " Strip trailing whitespace function! &amp;lt;SID&amp;gt;StripTrailingWhitespaces() " Preparation: save last search, and cursor position. let _s=@/ let l = line(".") let c = col(".") " Do the business: %s/\s\+$//e " Clean up: restore previous search history, and cursor position let @/=_s call cursor(l, c) endfunction autocmd BufWritePre * :call &amp;lt;SID&amp;gt;StripTrailingWhitespaces() สำหรับ Netbean ผมค้นเจอ plugin Stripwhitespace ครับ http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.nbm http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.jar ตอนนี้ยัง Download ได้อยู่แต่ดู Domain แล้วอาจจะอยู่ได้ไม่นาน ที่มา - rails-bestpractices</itunes:summary><feedburner:origLink>http://www.thairor.com/2010/12/version-control.html</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/thairor/~5/brGTjKSTRk4/org-netbeans-modules-stripwhitespace.jar" length="55321" type="application/x-java-archive" /><feedburner:origEnclosureLink>http://blogs.sun.com/wangwj/resource/org-netbeans-modules-stripwhitespace.jar</feedburner:origEnclosureLink></item><item><title>เว็บสร้างบน Rails</title><link>http://feedproxy.google.com/~r/thairor/~3/NFyUQcYrQ0w/rails.html</link><category>applicaiton</category><category>rails</category><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:36:06 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-6401021497088290076</guid><description>&lt;p&gt;มีคนให้ช่วยยกตัวอย่างเว็บที่สร้างบน Rails วันนี้เลยจัดไป 3 เว็บ โดยทั้งหมด Host อยู่บน &lt;a href="http://www.heroku.com/"&gt;Heroku&lt;/a&gt; ครับ&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5227372995/" title="hooppps by apirakpanatkool, on Flickr"&gt;&lt;img alt="hooppps" height="240" src="http://farm6.static.flickr.com/5290/5227372995_1b1476cd9e_m.jpg" width="132" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;a href="http://hooppps.com/"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Hooppps.com&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
ถ้ารู้จักเว็บ &lt;a href="http://dribbble.com/"&gt;Dribbble.com&lt;/a&gt; จะรู้ว่ามันเป็นเว็บสำหรับนักออกแบบเข้ามาแลกเปลี่ยนผลงานกัน ปัญหาคือ Dribbble ไม่ได้ออกแบบมาสำหรับมือถือ นี่เป็นที่มาของ &lt;a href="http://hooppps.com/"&gt;Hooppps.com&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5227970008/" title="mercuryapp by apirakpanatkool, on Flickr"&gt;&lt;img alt="mercuryapp" height="230" src="http://farm5.static.flickr.com/4144/5227970008_9fd20e7011_m.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;a href="http://mercuryapp.com/"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Mercuryapp.com&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
เว็บที่ช่วยติดตามความรู้สึกของเรา ที่มีต่องาน ทีม คนรอบข้าง หรือความรู้สึกทั่วๆ ไป ส่วนมันจะติดตามได้อย่างไร ตอนนี้ยังเปิด invitation beta อยู่ครับ เข้าไปทดลองได้&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5227373273/" title="eatdrink by apirakpanatkool, on Flickr"&gt;&lt;img alt="eatdrink" height="240" src="http://farm5.static.flickr.com/4145/5227373273_52a941f6a7_m.jpg" width="125" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;&lt;a href="http://eatdrink.it/"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;EatDrink.it&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
เว็บบนมือถือสำหรับให้คะแนนร้านอาหารที่เราไปทาน และสามารถแนะนำร้านอาหารตามที่อยู่ของเราได้ด้วย&lt;br /&gt;
&lt;br /&gt;
ที่มา Heroku-mail&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-6401021497088290076?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/NFyUQcYrQ0w" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:36:06.187+07:00</app:edited><media:thumbnail url="http://farm6.static.flickr.com/5290/5227372995_1b1476cd9e_t.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/12/rails.html</feedburner:origLink></item><item><title>เปิดตัว RubyMine 3 - Rails 3 IDE ในราคา 69$</title><link>http://feedproxy.google.com/~r/thairor/~3/VDhBNtFvteQ/rubymine-3-rails-3-ide-69.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:35:46 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-412632231669666078</guid><description>&lt;p&gt;ค่าย &lt;a href="http://www.jetbrains.com/index.html"&gt;JetBrain&lt;/a&gt; ผู้พัฒนา &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; เปิดตัว IDE &lt;a href="http://www.jetbrains.com/ruby/"&gt;RubyMine3&lt;/a&gt; โดยมี Feature หลักคือการรองรับ Rails 3&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5218815035/" title="Screen shot 2010-11-30 at 6.12.38 AM by apirakpanatkool, on Flickr"&gt;&lt;img alt="Screen shot 2010-11-30 at 6.12.38 AM" height="234" src="http://farm5.static.flickr.com/4087/5218815035_51a9279ec6.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;หน้าตา RubyMine 3&lt;/div&gt;&lt;br /&gt;
ความสามารถใหม่ของ RubyMine 3 มีหลายอย่างครับ ที่น่าสนใจเช่น&amp;nbsp;สามารถทำงานรวมกับ Gem ใหม่ๆ เช่น RSpec 2.0, Bundler 1.0, Cucumber 0.9.x และ RVM&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5218835287/" title="RSpec 2 by apirakpanatkool, on Flickr"&gt;&lt;img alt="RSpec 2" height="159" src="http://farm6.static.flickr.com/5205/5218835287_a93949fdc1.jpg" width="500" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
รองรับระบบ Tasks Management ตัวหลักๆ อย่าง JIRA, YouTrack, Lighhouse, Pivotal, GitHub, Redmine แต่ไม่มี Trac เฮะ&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5218812357/" title="rubymine3 by apirakpanatkool, on Flickr"&gt;&lt;img alt="rubymine3" height="173" src="http://farm5.static.flickr.com/4132/5218812357_bbfc984c57.jpg" width="500" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
สามารถสร้าง ER ให้ได้ด้วย&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/92185242@N00/5219724724/" title="Power Save mode by apirakpanatkool, on Flickr"&gt;&lt;img alt="Power Save mode" height="212" src="http://farm6.static.flickr.com/5168/5219724724_a6519a9621.jpg" width="500" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;ผมทดลองใช้บน Mac ดู พบว่าถ้าไม่มีความสามารถไหนโดนใจจริงๆ ก็ใช้ &lt;a href="http://netbeans.org/"&gt;Netbean&lt;/a&gt; ต่อไปดีกว่าเพราะความเร็วไม่ต่างกัน แต่ถ้าต้องการความเร็วในการเปิด/ปิดสูงสุด ก็ไปใช้ &lt;a href="http://macromates.com/"&gt;Textmate&lt;/a&gt; หรือ &lt;a href="http://macvim.org/OSX/index.php"&gt;vim&lt;/a&gt;&amp;nbsp;เลยครับ&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;ที่มา &lt;a href="http://www.rubyflow.com/items/4859"&gt;rubyflow&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-412632231669666078?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/VDhBNtFvteQ" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:35:46.610+07:00</app:edited><media:thumbnail url="http://farm5.static.flickr.com/4087/5218815035_51a9279ec6_t.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/rubymine-3-rails-3-ide-69.html</feedburner:origLink></item><item><title>มาทำ Dropbox ด้วย RubyDrop</title><link>http://feedproxy.google.com/~r/thairor/~3/93QPz5svoXc/dropbox-rubydrop.html</link><category>Ruby</category><author>noreply@blogger.com (Phuwanart Larpmark)</author><pubDate>Sat, 27 Nov 2010 21:42:19 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-6879293688371274958</guid><description>&lt;p&gt;ถ้าใครเคยใช้ Dropbox จะู้ดีว่ามันเจ๋งขนาดไหน แล้วก็มีคนทำ clone ของ Dropbox มาให้ใช้กันแล้ว ชื่อว่า ﻿&lt;a href="https://github.com/meltingice/RubyDrop"&gt;RubyDrop&lt;/a&gt; ซึ่งข้างหลังของการ sync ไฟล์นั้น จะใช้ Git เป็นตัวช่วย&lt;/p&gt;&lt;p&gt;ผมว่าเดี๋ยวจะลองหาเครื่องลองเล่นดูหน่อย น่าสนุกดี แต่หากใครลองได้ก่อนก็เอามาบอกกันด้วยนะว่าดีอ่ะเปล่า :P&lt;/p&gt;&lt;p&gt;ที่มา &lt;a href="http://www.rubyinside.com/rubydrop-a-dropbox-clone-in-ruby-3968.html"&gt;Rubu Inside&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-6879293688371274958?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/93QPz5svoXc" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-28T12:42:19.311+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/dropbox-rubydrop.html</feedburner:origLink></item><item><title>ทำ blog ง่ายๆ (อีกแล้ว) ด้วย Blogcast</title><link>http://feedproxy.google.com/~r/thairor/~3/su_30ixt_GY/blog-blogcast.html</link><category>rails</category><author>noreply@blogger.com (Phuwanart Larpmark)</author><pubDate>Sat, 27 Nov 2010 21:32:10 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-4245337887142473995</guid><description>&lt;p&gt;&lt;span style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse;"&gt;&lt;a style="color: #2244bb;" href="http://techoctave.com/c7/posts/38-blogcast-is-a-better-way-to-blog" target="_blank"&gt;Blogcast&lt;/a&gt; ก็เป็นอีกหนึ่ง blog app เห็นมีทำกันเยอะแล้วล่ะ และนี่ก็เป็นอีกตัวที่ง่ายดีเหมือนกัน &lt;/span&gt;&lt;/p&gt;&lt;p&gt;ที่มา &lt;a href="http://www.rubyflow.com/items/4845"&gt;rubyflow&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-4245337887142473995?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/su_30ixt_GY" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-28T12:32:10.400+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/blog-blogcast.html</feedburner:origLink></item><item><title>ใช้ Rails รัก Command line มาใช้ Ruby shell กันดีกว่า</title><link>http://feedproxy.google.com/~r/thairor/~3/4pXuQprUhQA/rails-command-line-ruby-shell.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:35:21 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-8650865308642385796</guid><description>&lt;p&gt;ปกติผมจะใช้ irb เพื่อทดลองคำสั่ง ruby หรือคำนวนทั่วไป แต่พอเข้าๆ ออกๆ บ่อยเข้า ก็เริ่มหาตัวช่วย วันนี้มีเว็บ &lt;a href="http://rbjl.net/43-use-fresh-ruby-as-your-shell"&gt;rbjl.net&lt;/a&gt; แนะนำ &lt;a href="https://github.com/janlelis/fresh"&gt;Gem Fresh&lt;/a&gt; ให้รู้จัก มันสามารถใช้งาน shell ไปพร้อมๆ กับคำสั่ง ruby ได้เลยครับ&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;_kit&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;css&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;3&lt;/span&gt;.times {|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;i&lt;/span&gt;| puts(&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby" style="background-color: #fff0f0; color: #dd2200;"&gt;"Ruby &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source" style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; color: black;"&gt;#{i}&lt;/span&gt;"&lt;/span&gt;)}
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;"&gt;Ruby&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;0&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;"&gt;Ruby&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;1&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;"&gt;Ruby&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;2&lt;/span&gt;
=&amp;gt; &lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;3&lt;/span&gt;
&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;_kit&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;css&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt; ls
style.css  style2.css
&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;_kit&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;css&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;_kit&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;css&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt; vi .&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;style.css&lt;/pre&gt;&lt;br /&gt;
สามารถใช้ปุ่ม [tab] สำหรับ autocomplete ได้&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;_kit&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;sme&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;res&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt; vim .&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: small; line-height: normal; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;style [tab]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;.&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;style2.css  .&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;style.css&lt;/pre&gt;&lt;br /&gt;
ถ้าอยากรู้ว่าเราใช้คำสั่งอะไรได้บ้างก็ให้เรียก&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;_kit&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;css&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;"&gt;Ripl&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;.config[&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:fresh_system_words&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
หรือใช้ร่วมกับ grep เพื่อหาแบบ&amp;nbsp;regular expression&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_other keyword_operator_other_ruby" style="color: black; font-weight: normal;"&gt;~&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;workspace&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/sme&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;_kit&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;css&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby" style="color: black; font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;"&gt;Ripl&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;.config[&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:fresh_system_words&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;].grep(&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;xf&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby" style="background-color: #fff0ff; color: #880088;"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
ปัญหาที่ผมเห็นคือยังแสดงผลภาษาไทยไม่ได้ ใช้คำสั่ง ruby ปนกับ unix ไม่ได้ และที่ผมสงสัยคือทำไมใช้คำสั่ง cd ไม่ได้แต่ในตัวอย่างมันทำได้นะ เท่าที่อ่านดูคาดว่าเป็นที่การกำหนด default แต่ยังไม่ได้ทดลองแก้ (ใครทำแล้วก็บอกด้วยนะครับ)&lt;br /&gt;
&lt;br /&gt;
การติดตั้งก็ง่าย&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;"&gt;gem&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt; install ripl&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby" style="color: black; font-weight: normal;"&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;fresh&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
จากนั้นก็เริ่มทำงานด้วยคำสั่ง&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;ripl fresh&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
สำหรับ Gem อื่นๆ ที่ทำได้คล้ายๆ กัน ก็มี&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://rush.heroku.com/"&gt;rush&lt;/a&gt; - เป็น Ruby shell เหมือนกันแต่แนวทางต่างกัน&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cldwalker/ripl"&gt;ripl&lt;/a&gt;&amp;nbsp;- เป็น rib alternative ครับ เรียก unix commands ตรงๆ ไม่ได้ เจ้า fresh ก็ทำงานอยู่บนตัวนี้&lt;/li&gt;
&lt;/ul&gt;ที่มา &lt;a href="http://www.rubyflow.com/items/4839"&gt;rubyflow&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-8650865308642385796?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/4pXuQprUhQA" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:35:21.922+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/rails-command-line-ruby-shell.html</feedburner:origLink></item><item><title>Rails 3.0.3: ActiveRecord ที่เร็วขึ้น รวมทั้งแก้บั๊กอีกมากมาย</title><link>http://feedproxy.google.com/~r/thairor/~3/gWAmgUBnwrI/rails-303-activerecord.html</link><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Tue, 26 Apr 2011 19:35:01 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-1199311677831550163</guid><description>&lt;p&gt;Rails 3.0.3 ออกได้นานนับสัปดาห์แล้ว เวอร์ชันนี้ควบรวม 3.0.2 ด้วย เนื่องจากตอนจะปล่อย 3.0.2 ดันพบบั๊ก ก็เลยแก้แล้วออก 3.0.3 มันทีเดียว&lt;br /&gt;
&lt;br /&gt;
การแก้ไขหลักๆ ในรุ่น 3.0.3 ก็เห็นจะเป็นเรื่องการเพิ่มความเร็วให้กับ ActiveRecord ด้วยการใช้ &lt;a href="http://engineering.attinteractive.com/2010/10/arel-two-point-ohhhhh-yaaaaaa/"&gt;ARel 2.0&lt;/a&gt;&amp;nbsp;มาเป็นตัวช่วยสร้างโค้ด SQL จนทำให้ ActiveRecord ใน Rails 3.0.3 ทำความเร็วได้เหนือกว่า Rails 2.3.x จากที่ก่อนหน้านี้ในรุ่น 3.0.0 นั้น ยังช้ากว่า 2.3.0 อยู่ถึง 5 เท่าตัว (กราฟเปรียบเทียบอยู่ในลิงก์)&lt;br /&gt;
&lt;br /&gt;
เบื้องหลัง ARel ดูน่าสนุกเอาการ เพียงแต่ผมเป็นโรคภูมิแพ้คณิตศาสตร์ เจอคำว่า Algebra ก็ไข้ขึ้นแล้ว อ่านๆ ดูก็เลยไม่ค่อยเข้าใจเท่าไหร่&lt;br /&gt;
&lt;br /&gt;
อีกส่วนหนึ่่งที่เป็นการเปลี่ยนแปลงในรุ่นนี้คือการแก้ไขบั๊กจำนวนมาก ใครที่ใช้ 3.0.1 อยู่ ก็น่าจะถึงเวลาอัพเกรด&lt;br /&gt;
&lt;br /&gt;
ใช้ Ruby on Rails ต้องทำใจเรื่องความนิ่งของ framework และ library(ies) กันสักหน่อย : )&lt;br /&gt;
&lt;br /&gt;
ต้นฉบับ: &lt;a href="http://weblog.rubyonrails.org/2010/11/15/rails-3-0-3-faster-active-record-plus-plenty-of-fixes"&gt;Rails 3.0.3: Faster Active Record plus fixes&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-1199311677831550163?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/gWAmgUBnwrI" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:35:01.988+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/rails-303-activerecord.html</feedburner:origLink></item><item><title>เรียน Rails แนวผีดิบ</title><link>http://feedproxy.google.com/~r/thairor/~3/Y1dxfYf3TUk/rails.html</link><category>rails</category><category>tutorial</category><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:34:50 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-8830291973677624883</guid><description>&lt;p&gt;แนะนำเว็บ Rails Tutorial แบบ Interactive&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://twitpic.com/3820sk" title="Share photos on twitter with Twitpic"&gt;&lt;img alt="Share photos on twitter with Twitpic" height="150" src="http://twitpic.com/show/thumb/3820sk.png" width="150" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
เหมาะเป็นอย่างยิ่งสำหรับเด็กน้อย หรือคนที่ต้องการเรียน Rails แบบประหยัดพลังงานครับ&amp;nbsp;ตามไปเรียนกันได้ที่ &lt;a href="http://railsforzombies.org/"&gt;Railsforzombies&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-8830291973677624883?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/Y1dxfYf3TUk" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:34:50.738+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/rails.html</feedburner:origLink></item><item><title>Thanks for Thailand RailsCamp 2010</title><link>http://feedproxy.google.com/~r/thairor/~3/elVzhE8lu9U/thanks-for-thailand-railscamp-2010.html</link><category>railscamp</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Tue, 26 Apr 2011 19:34:37 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-8602574593054145899</guid><description>&lt;p&gt;เสร็จสิ้นไปแล้วกับการสัมมนากลุ่มย่อยผู้ใช้ Ruby on Rails แห่งประเทศไทย (อู้ววว ยิ่งใหญ่) มีผู้เข้าร่วมสัมมนาประมาณ 15 คน ซึ่งก็ต้องขอบคุณทุกท่านที่มาร่วมพบปะพูดคุยกันในครั้งนี้ครับ&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;เปิดงานด้วย Jedi Master &lt;a href="http://twitter.com/rawitat"&gt;@rawitat&lt;/a&gt; ในฐานะศิษย์น้องร่วมสถาบันของ&amp;nbsp;"Yukihiro Matsumoto"&amp;nbsp;มาเล่าให้เราฟังว่าบิดาแห่ง Ruby&amp;nbsp;เขาคิดอะไร ทำไมเขาถึงสร้างภาษานี้ขึ้นมา สนุกสนานชวนฟังตามสไตล์ผู้เชี่ยวชาญในการนำเสนอ เล่นเอาคนฟังอยากเปิดโน๊ตบุ๊คขึ้นมาเขียน Ruby มันเดี๋ยวนั้น&lt;br /&gt;
&lt;br /&gt;
จากนั้น Padawan &lt;a href="http://twitter.com/neokain"&gt;@neokain&lt;/a&gt; ก็มาแนะนำ Rails 3 ต่อ มีของใหม่ๆ เพิ่มเข้ามามากมาย เน้นเขียนสั้น เข้าใจง่าย สวยงาม และประสิทธิภาพเพิ่มมากขึ้น น่าลองว่า Active Model โดยเฉพาะ Active Relation นั้น จะเจ๋งสมคำโฆษณาแค่ไหน&lt;br /&gt;
&lt;br /&gt;
ตามติดมาด้วย &lt;a href="http://twitter.com/apirak"&gt;@apirak&lt;/a&gt; มาแนะนำ &lt;a href="http://netzke.org/"&gt;Netzke&lt;/a&gt; (Sencha on Rails) เครื่องมือที่ทำให้เราสร้างเว็บ CRUD ได้เร็วและสมบูรณ์ที่สุดตั้งแต่มี Rails เกิดขึ้นมาบนโลกนี้ ซึ่งถ้าปรับแต่งดีๆ สามารถใช้เป็นหลังบ้านที่เทียบเท่ากับ Django Admin ได้อย่างสบาย&lt;br /&gt;
&lt;br /&gt;
... พักเที่ยง ฉุกละหุกเรื่องอาหารกลางวันเล็กน้อย (ต้องขออภัยมา ณ ที่นี้) เลยจัด KFC 2 ถัง + Pizza 1 ถาด (ขอขอบคุณ &lt;a href="http://twitter.com/pphetra"&gt;@pphetra&lt;/a&gt;, &lt;a href="http://twitter.com/apirak"&gt;@apirak&lt;/a&gt;, &lt;a href="http://twitter.com/kengggg"&gt;@kengggg&lt;/a&gt; ในฐานะเจ้ามือมื้อนี้ครับ) ...&lt;br /&gt;
&lt;br /&gt;
เปิด session ภาคบ่าย ด้วย &lt;a href="http://twitter.com/scomma"&gt;@scomma&lt;/a&gt; มาแนะนำ Haml &amp;amp; Sass ให้เรารู้จักคำว่า elegance โดยไม่ต้องเปิดพจนานุกรม หมดยุคที่นักพัฒนาต้องมาปวดหัวกับการเปิด/ปิดแท็ก และมึนกับโค้ด HTML ที่รกรุงรังแล้ว&lt;br /&gt;
&lt;br /&gt;
จากนั้น &lt;a href="http://twitter.com/shinejikids"&gt;@shinejikids&lt;/a&gt; มาแนะนำ &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; ช่องทางการ deploy Rails application ที่ง่ายและสะดวกที่สุดในปัจจุบัน อีกทั้งยังเพรียบพร้อมด้วย ecosystem ที่หลากหลายและทันสมัย มีทั้งแบบฟรีที่เหมาะสำหรับนักพัฒนา และแบบเสียเงินสำหรับโปรดักชัน&lt;br /&gt;
&lt;br /&gt;
ต่อด้วย &lt;a href="http://twitter.com/tonkla"&gt;@tonkla&lt;/a&gt; มาเปรียบเทียบ Rails 2.2 กับ Django 1.2 ให้ฟังกันแบบคร่าวๆ ปิดท้ายด้วยข้อสรุปว่า ใครใช้ Rails 2 ก็ให้รีบอัพเกรดมาเป็น 3 เถิด ของเจ๋งๆ รอคุณอยู่ ส่วนใครที่ใช้ Django ก็จงใช้ต่อไป เวอร์ชัน 1.3 เริ่มปล่อยรุ่น alpha แล้ว ของดีทั้งคู่ ใครชอบอันไหนจงใช้อันนั้น&lt;br /&gt;
&lt;br /&gt;
ปิดท้ายด้วยการซักถามปัญหาและพูดคุยกันอีกเล็กน้อย ก่อนแยกย้ายกันกลับบ้าน ถือว่า Thailand RailsCamp 2010 ก็ได้ปิดฉากลงอย่างสมบูรณ์ ขอขอบคุณทุกๆ ท่านที่มาร่วมเป็นส่วนหนึ่งของงานนี้อีกครั้งหนึ่งครับ&lt;br /&gt;
&lt;br /&gt;
ปล. Ruby กูช้า กูยอม&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
เอกสารประกอบการนำเสนอ:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://dl.elf.in.th/2010/11/what_matz_thinks.pdf"&gt;What Matz Thinks?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dl.elf.in.th/2010/11/rails3.pdf"&gt;Introduction to Rails 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dl.elf.in.th/2010/11/haml.pdf"&gt;Haml &amp;amp; Sass&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dl.elf.in.th/2010/11/rails22_vs_django12.pdf"&gt;Rails 2.2 vs. Django 1.2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dl.elf.in.th/2010/11/netzke.pdf"&gt;Netzke&amp;nbsp;(Sencha on Rails)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-8602574593054145899?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/elVzhE8lu9U" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:34:37.910+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><media:content url="http://feedproxy.google.com/~r/thairor/~5/o24nG1L8Fek/what_matz_thinks.pdf" fileSize="2789613" type="application/pdf" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> เสร็จสิ้นไปแล้วกับการสัมมนากลุ่มย่อยผู้ใช้ Ruby on Rails แห่งประเทศไทย (อู้ววว ยิ่งใหญ่) มีผู้เข้าร่วมสัมมนาประมาณ 15 คน ซึ่งก็ต้องขอบคุณทุกท่านที่มาร่วมพบปะพูดคุยกันในครั้งนี้ครับ เปิดงานด้วย Jedi Master @rawitat ในฐานะศิษย์น้องร่วมสถาบันของ&amp;nbsp;"Yukih</itunes:subtitle><itunes:author>noreply@blogger.com (Surakarn Samkaew)</itunes:author><itunes:summary> เสร็จสิ้นไปแล้วกับการสัมมนากลุ่มย่อยผู้ใช้ Ruby on Rails แห่งประเทศไทย (อู้ววว ยิ่งใหญ่) มีผู้เข้าร่วมสัมมนาประมาณ 15 คน ซึ่งก็ต้องขอบคุณทุกท่านที่มาร่วมพบปะพูดคุยกันในครั้งนี้ครับ เปิดงานด้วย Jedi Master @rawitat ในฐานะศิษย์น้องร่วมสถาบันของ&amp;nbsp;"Yukihiro Matsumoto"&amp;nbsp;มาเล่าให้เราฟังว่าบิดาแห่ง Ruby&amp;nbsp;เขาคิดอะไร ทำไมเขาถึงสร้างภาษานี้ขึ้นมา สนุกสนานชวนฟังตามสไตล์ผู้เชี่ยวชาญในการนำเสนอ เล่นเอาคนฟังอยากเปิดโน๊ตบุ๊คขึ้นมาเขียน Ruby มันเดี๋ยวนั้น จากนั้น Padawan @neokain ก็มาแนะนำ Rails 3 ต่อ มีของใหม่ๆ เพิ่มเข้ามามากมาย เน้นเขียนสั้น เข้าใจง่าย สวยงาม และประสิทธิภาพเพิ่มมากขึ้น น่าลองว่า Active Model โดยเฉพาะ Active Relation นั้น จะเจ๋งสมคำโฆษณาแค่ไหน ตามติดมาด้วย @apirak มาแนะนำ Netzke (Sencha on Rails) เครื่องมือที่ทำให้เราสร้างเว็บ CRUD ได้เร็วและสมบูรณ์ที่สุดตั้งแต่มี Rails เกิดขึ้นมาบนโลกนี้ ซึ่งถ้าปรับแต่งดีๆ สามารถใช้เป็นหลังบ้านที่เทียบเท่ากับ Django Admin ได้อย่างสบาย ... พักเที่ยง ฉุกละหุกเรื่องอาหารกลางวันเล็กน้อย (ต้องขออภัยมา ณ ที่นี้) เลยจัด KFC 2 ถัง + Pizza 1 ถาด (ขอขอบคุณ @pphetra, @apirak, @kengggg ในฐานะเจ้ามือมื้อนี้ครับ) ... เปิด session ภาคบ่าย ด้วย @scomma มาแนะนำ Haml &amp;amp; Sass ให้เรารู้จักคำว่า elegance โดยไม่ต้องเปิดพจนานุกรม หมดยุคที่นักพัฒนาต้องมาปวดหัวกับการเปิด/ปิดแท็ก และมึนกับโค้ด HTML ที่รกรุงรังแล้ว จากนั้น @shinejikids มาแนะนำ Heroku ช่องทางการ deploy Rails application ที่ง่ายและสะดวกที่สุดในปัจจุบัน อีกทั้งยังเพรียบพร้อมด้วย ecosystem ที่หลากหลายและทันสมัย มีทั้งแบบฟรีที่เหมาะสำหรับนักพัฒนา และแบบเสียเงินสำหรับโปรดักชัน ต่อด้วย @tonkla มาเปรียบเทียบ Rails 2.2 กับ Django 1.2 ให้ฟังกันแบบคร่าวๆ ปิดท้ายด้วยข้อสรุปว่า ใครใช้ Rails 2 ก็ให้รีบอัพเกรดมาเป็น 3 เถิด ของเจ๋งๆ รอคุณอยู่ ส่วนใครที่ใช้ Django ก็จงใช้ต่อไป เวอร์ชัน 1.3 เริ่มปล่อยรุ่น alpha แล้ว ของดีทั้งคู่ ใครชอบอันไหนจงใช้อันนั้น ปิดท้ายด้วยการซักถามปัญหาและพูดคุยกันอีกเล็กน้อย ก่อนแยกย้ายกันกลับบ้าน ถือว่า Thailand RailsCamp 2010 ก็ได้ปิดฉากลงอย่างสมบูรณ์ ขอขอบคุณทุกๆ ท่านที่มาร่วมเป็นส่วนหนึ่งของงานนี้อีกครั้งหนึ่งครับ ปล. Ruby กูช้า กูยอม เอกสารประกอบการนำเสนอ: What Matz Thinks? Introduction to Rails 3 Haml &amp;amp; Sass Rails 2.2 vs. Django 1.2 Netzke&amp;nbsp;(Sencha on Rails) </itunes:summary><itunes:keywords>railscamp</itunes:keywords><feedburner:origLink>http://www.thairor.com/2010/11/thanks-for-thailand-railscamp-2010.html</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/thairor/~5/o24nG1L8Fek/what_matz_thinks.pdf" length="2789613" type="application/pdf" /><feedburner:origEnclosureLink>http://dl.elf.in.th/2010/11/what_matz_thinks.pdf</feedburner:origEnclosureLink></item><item><title>Plugin Authentasaurus สำหรับระบบ Single sign-in</title><link>http://feedproxy.google.com/~r/thairor/~3/NLcDe3EzrFg/plugin-authentasaurus-single-sign-in.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:34:24 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-3264740513815807409</guid><description>&lt;p&gt;ตัว &lt;a href="https://github.com/cousine/Authentasuarus-2"&gt;Authentasaurus&lt;/a&gt; ทำหน้าที่เป็น Authentication plugin โดยมีจุดเด่นที่ระบบ Single sign-in ช่วยให้เราไม่ต้องเก็บข้อมูลผู้ใช้ไว้หลายที่&amp;nbsp;ถ้าเราพัฒนาเว็บอยู่ตัวเดียวก็ไม่จำเป็นต้องใช้ครับ แต่ถ้าเมื่อไหรที่พัฒนาบริการมากกว่าหนึ่งที่ก็ถึงเวลาของ Plugin Authentasaurus ครับ&lt;br /&gt;
&lt;br /&gt;
สนใจอ่านวิธีการติดตั้งได้ตามที่มาครับ&lt;br /&gt;
&lt;br /&gt;
ที่มา &lt;a href="http://rubylearning.com/blog/2010/11/16/why-use-single-sign-in-solutions-in-rails/"&gt;rubylearning&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-3264740513815807409?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/NLcDe3EzrFg" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:34:24.462+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/plugin-authentasaurus-single-sign-in.html</feedburner:origLink></item><item><title>Enum column โดยไม่ใช้ Database</title><link>http://feedproxy.google.com/~r/thairor/~3/nBKB1g2xaIw/enum-column-database.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:34:07 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-2843316933795816562</guid><description>&lt;p&gt;การแก้ปัญหา Enumerate column มีหลายวิธีครับ ทางหนึ่งที่ใช้กันบ่อยๆ คือการสร้างตารางขึ้นมาใหม่&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;Table "Member"
id &amp;nbsp; | &amp;nbsp;name &amp;nbsp; | relationship_status_id
-----+---------+------------------------
1 &amp;nbsp; &amp;nbsp;| Sompon &amp;nbsp;| 1
2 &amp;nbsp; &amp;nbsp;| Somsuk &amp;nbsp;| 2

Table "relationship_status"
id &amp;nbsp; | &amp;nbsp;name
-----+--------------
1 &amp;nbsp; &amp;nbsp;| Single
2 &amp;nbsp; &amp;nbsp;| Married
3 &amp;nbsp; &amp;nbsp;| Widow
4 &amp;nbsp; &amp;nbsp;| Divorced
&lt;/pre&gt;&lt;br /&gt;
ผมคิดว่าวิธีนี้เป็นวิธีที่ตรงไปตรงมาดีโดยเฉพาะกับฐานข้อมูลที่ไม่รองรับ Enumerate แต่ก็มีปัญหาของมันเอง เช่น ทุกครั้งที่ต้องการ query เพื่อให้ได้ชื่อของ relationship_status จะต้องใช้ join ทุกครั้ง ทำให้ query ที่ซับซ้อนอยู่แล้วต้องซับซ้อนไปอีก เป็นต้น&lt;br /&gt;
&lt;br /&gt;
ทางออกอีกทางคือแทนที่จะเก็บ relationship_status ในรูปของ Table &amp;nbsp;เราเปลี่ยนไปเก็บในรูปของ Model แทนไม่ต้องมี Table จริง ไม่ต้อง Query ไม่ต้อง CPU เพื่อทำ ORMapping เมื่อ query Member ก็สามารถเรียก member.relationshipStatus ได้เลย แต่ ปัญหาของวิธีการการนี้คือเราต้องสร้าง method ให้กับ RelationshipStatus ด้วย ไม่งั้นจะเสียดาย method ที่ Activerecord จะสร้างให้ถ้าเราใช้วิธีสร้าง Table&lt;br /&gt;
&lt;br /&gt;
นี่เป็นที่มาของ &lt;a href="https://github.com/cassiomarques/enumerate_it"&gt;plugin EnumerateIt&lt;/a&gt;&amp;nbsp;ครับ ตัว plugin เลือกวิธีแก้ปัญหาโดยการสร้าง Model แทนการสร้าง &amp;nbsp;Table จากนั้น Plugin จะช่วยสร้าง method ที่จำเป็นให้เรา&lt;br /&gt;
&lt;br /&gt;
หน้าตาการสร้าง Model เป็นแบบนี้ครับ&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;"&gt;RelationshipStatus&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366; font-weight: bold;"&gt; &amp;lt; EnumerateIt::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
   associate_values(
     &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:single&lt;/span&gt;   =&amp;gt; [&lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;1&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="background-color: #fff0f0; color: #dd2200;"&gt;'Single'&lt;/span&gt;],
     &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:married&lt;/span&gt;  =&amp;gt; [&lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;2&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="background-color: #fff0f0; color: #dd2200;"&gt;'Married'&lt;/span&gt;],
     &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:widow&lt;/span&gt;    =&amp;gt; [&lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;3&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="background-color: #fff0f0; color: #dd2200;"&gt;'Widow'&lt;/span&gt;],
     &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:divorced&lt;/span&gt; =&amp;gt; [&lt;span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;"&gt;4&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="background-color: #fff0f0; color: #dd2200;"&gt;'Divorced'&lt;/span&gt;]
   )
&lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="color: black; font-weight: normal;"&gt;&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;"&gt;Member&lt;/span&gt;&lt;/span&gt;
  &lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;"&gt;include&lt;/span&gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;"&gt;EnumerateIt&lt;/span&gt;
  &lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;"&gt;attr_accessor&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:relationship_status&lt;/span&gt;

  has_enumeration_for &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:relationship_status&lt;/span&gt;, &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600; font-weight: normal;"&gt;:with&lt;/span&gt; =&amp;gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;"&gt;RelationshipStatus&lt;/span&gt;
&lt;span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
ส่วนเวลาเอาไปใช้&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 15px; white-space: pre;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="sunburst" style="font-family: 'Bitstream Vera Sans Mono', Monaco, Consolas, 'Courier New', monospace; font-size: 9pt; line-height: 1.3em; margin-top: 0em;"&gt;p &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby" style="color: black; font-weight: normal;"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;"&gt;Member&lt;/span&gt;.&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;"&gt;new&lt;/span&gt;
p.relationship_status &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby" style="color: black; font-weight: normal;"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;"&gt;RelationshipStatus&lt;/span&gt;::&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;"&gt;DIVORCED&lt;/span&gt;
p.relationsip_status_humanize &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby" style="color: #888888;"&gt;# =&amp;gt; 'Divorced&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
สำหรับใครที่สนใจ สามารถทดลองเอาไปใช้ได้ที่ &lt;a href="https://github.com/cassiomarques/enumerate_it"&gt;https://github.com/cassiomarques/enumerate_it&lt;/a&gt;&amp;nbsp;ครับ&lt;br /&gt;
&lt;br /&gt;
ที่มา &lt;a href="http://www.rubyflow.com/items/4782?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed:+Rubyflow+(RubyFlow)"&gt;rubyflow&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-2843316933795816562?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/nBKB1g2xaIw" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:34:07.716+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/enum-column-database.html</feedburner:origLink></item><item><title>Opensource Network Monitoring Tool นาม Snorby</title><link>http://feedproxy.google.com/~r/thairor/~3/RJPhwRall_A/opensource-network-monitoring-tool.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:33:54 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-7685675270201759776</guid><description>&lt;p&gt;แนะนำโปรแกรม &lt;a href="http://www.snorby.org/"&gt;Snorby 2.0&lt;/a&gt; สำหรับใครก็ตามที่ทำงานด้าน Network Monitoring&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_F2rZXyRWz5I/TNjnkK38UuI/AAAAAAABocw/q6DTITE-TTM/s1600/snorby.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="247" src="http://3.bp.blogspot.com/_F2rZXyRWz5I/TNjnkK38UuI/AAAAAAABocw/q6DTITE-TTM/s400/snorby.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://vimeo.com/16597187"&gt;ดู video สาธิตการใช้งานที่ vimeo&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
โปรแกรม Snorby ทำตัวเป็นหน้ากากให้กับโปรแกรม &lt;a href="http://www.snort.org/"&gt;Snort&lt;/a&gt; อีกทีนึง ดูจาก code แล้วน่าจะพัฒนาบน Rails ครับ ใครสนใจสามารถเอา code ที่ &lt;a href="https://github.com/mephux/Snorby"&gt;github&lt;/a&gt; ได้เลย&lt;br /&gt;
&lt;br /&gt;
พัฒนาโดยทีม &lt;a href="https://www.lookycode.com/"&gt;Lookycode&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-7685675270201759776?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/RJPhwRall_A" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:33:54.622+07:00</app:edited><media:thumbnail url="http://3.bp.blogspot.com/_F2rZXyRWz5I/TNjnkK38UuI/AAAAAAABocw/q6DTITE-TTM/s72-c/snorby.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/opensource-network-monitoring-tool.html</feedburner:origLink></item><item><title>Ruby conference in Singapore</title><link>http://feedproxy.google.com/~r/thairor/~3/0qcfr5B6t9I/ruby-conference-in-singapore.html</link><category>conference</category><author>noreply@blogger.com (Surakarn Samkaew)</author><pubDate>Tue, 26 Apr 2011 19:33:29 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-7194703974266265059</guid><description>&lt;p&gt;Email from Jason Ong from Singapore Ruby Brigade. FYI.&lt;br /&gt;
&lt;br /&gt;
-----------&lt;br /&gt;
&lt;br /&gt;
Hi guys&lt;br /&gt;
&lt;br /&gt;
I'm Jason Ong from Singapore Ruby Brigade. Thanks Keith Bennett for&lt;br /&gt;
indirectly pointed me to this group. :)&lt;br /&gt;
&lt;br /&gt;
Some of us are organizing a regional ruby conference in Singapore. So&lt;br /&gt;
far we've garnered the interests of prominent ruby folks to come&lt;br /&gt;
attend/give talks.&lt;br /&gt;
&lt;br /&gt;
Matz - creator of ruby language&lt;br /&gt;
Dave Thomas - Pragmatic Programmer&lt;br /&gt;
Chad Fowler - Pragmatic Programmer&lt;br /&gt;
Tom Preston-Werner - Github&lt;br /&gt;
Geoffrey Grosenbach - Peepcode&lt;br /&gt;
Greg Pollack - EnvyLabs&lt;br /&gt;
Some folks from Pivotal Labs&lt;br /&gt;
&lt;br /&gt;
Details are still being ironed out. Target date is somewhere in April/&lt;br /&gt;
May.&lt;br /&gt;
&lt;br /&gt;
As I'm unaware of any ruby groups in Thailand, thought it a good idea&lt;br /&gt;
to gather feedback from folks hanging out here.&lt;br /&gt;
&lt;br /&gt;
- Who's interested in attending?&lt;br /&gt;
- Ideally we would like Thai rubyists to give talks. Anybody&lt;br /&gt;
interested?&lt;br /&gt;
- Who are the ruby folks in Thailand?&lt;br /&gt;
&lt;br /&gt;
You can just give a shoutout here else ping my gmail. Thanks folks! :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-7194703974266265059?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/0qcfr5B6t9I" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:33:29.346+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/11/ruby-conference-in-singapore.html</feedburner:origLink></item><item><title>Redmine 1.0.3 Stable release</title><link>http://feedproxy.google.com/~r/thairor/~3/ll7F1KN8VOA/redmine-103-stable-release.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Tue, 26 Apr 2011 19:33:16 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-605784344621123226</guid><description>&lt;p&gt;&lt;a href="http://www.redmine.org/"&gt;Redmine&lt;/a&gt; เป็นโครงการ Opensource สำหรับงาน Software Project Management ลักษณะเดียวกับ &lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt; แต่พัฒนาบน Rails ปัจจุบันมีความสามารถหลักๆ ดังนี้ครับ&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Multiple projects support&lt;/li&gt;
&lt;li&gt;Flexible role based access control&lt;/li&gt;
&lt;li&gt;Flexible issue tracking system&lt;/li&gt;
&lt;li&gt;Gantt chart and calendar&lt;/li&gt;
&lt;li&gt;News, documents &amp;amp; files management&lt;/li&gt;
&lt;li&gt;Feeds &amp;amp; email notifications&lt;/li&gt;
&lt;li&gt;Per project wiki&lt;/li&gt;
&lt;li&gt;Per project forums&lt;/li&gt;
&lt;li&gt;Time tracking&lt;/li&gt;
&lt;li&gt;Custom fields for issues, time-entries, projects and users&lt;/li&gt;
&lt;li&gt;SCM integration (SVN, CVS, Git, Mercurial, Bazaar and Darcs)&lt;/li&gt;
&lt;li&gt;Issue creation via email&lt;/li&gt;
&lt;li&gt;Multiple LDAP authentication support&lt;/li&gt;
&lt;li&gt;User self-registration support&lt;/li&gt;
&lt;li&gt;Multilanguage support&lt;/li&gt;
&lt;li&gt;Multiple databases support&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
สำหรับ release ล่าสุด (1.0.3) จะเน้นการแก้บั๊กเป็นหลักครับ ทางโครงการแนะนำให้ทุกคนที่ใช้เวอร์ชัน 0.9.0 และ 1.0.0 ทำการ upgrade ได้เลย&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_F2rZXyRWz5I/TM4lV4EOplI/AAAAAAABobo/q5al08ojCxw/s1600/Screen+shot+2010-11-01+at+9.23.16+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="http://2.bp.blogspot.com/_F2rZXyRWz5I/TM4lV4EOplI/AAAAAAABobo/q5al08ojCxw/s320/Screen+shot+2010-11-01+at+9.23.16+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;หน้าจอ Issue Detail&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_F2rZXyRWz5I/TM4lQewsiqI/AAAAAAABobk/4UZ5eXx8A7o/s1600/Screen+shot+2010-11-01+at+9.25.24+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="215" src="http://1.bp.blogspot.com/_F2rZXyRWz5I/TM4lQewsiqI/AAAAAAABobk/4UZ5eXx8A7o/s320/Screen+shot+2010-11-01+at+9.25.24+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;หน้าจอ Roadmap&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;ที่มา&amp;nbsp;&lt;a href="http://www.rubyflow.com/items/4743"&gt;rubyflow&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-605784344621123226?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/ll7F1KN8VOA" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T09:33:16.119+07:00</app:edited><media:thumbnail url="http://2.bp.blogspot.com/_F2rZXyRWz5I/TM4lV4EOplI/AAAAAAABobo/q5al08ojCxw/s72-c/Screen+shot+2010-11-01+at+9.23.16+AM.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/10/redmine-103-stable-release.html</feedburner:origLink></item><item><title>Slim (template engine) ออกเวอร์ชัน 0.7.0</title><link>http://feedproxy.google.com/~r/thairor/~3/Og_hiX6QCVs/slim-template-engine-version-070.html</link><author>noreply@blogger.com (Apirak)</author><pubDate>Sun, 15 May 2011 19:12:31 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-3725988185525511869</guid><description>&lt;p&gt;ใน Rails community มี Template Engline ดีๆ สองตัวคือ &lt;a href="http://corelib.rubyonrails.org/classes/ERB.html"&gt;Erb&lt;/a&gt; กับ &lt;a href="http://haml-lang.com/"&gt;Haml&lt;/a&gt; แต่ยังไม่สะใจทีม Slim เพราะทีมงานคิดว่า Erb ยังไม่เรียบง่ายพอ และ Haml ก็ไม่ได้เร็วมากนัก จึงเป็นที่มาของโครงการ &lt;a href="http://github.com/stonean/slim"&gt;Slim&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;ทีม Slim จับความเรียบง่ายของ HAML มาเพิ่มความเร็ว โดย Slim นั้นเร็วกว่า Haml 15 เท่า และเร็วกว่า Erb 5 เท่า สำหรับเวอร์ชันใหม่ (0.7.0) ทีมงานลงมือเขียน core ขึ้นมาใหม่โดยใช้ความสามารถของ Temple และ Tilt เพื่อเพิ่ม functionality และ flexibility ส่วนมันจะดีแค่ไหนต้องลองเอาเองครับ&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;ตัวอย่าง code ที่เขียนด้วย Slim&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre class="brush: ruby"&gt;! doctype html
html
  head
    title Slim Examples
    meta name="keywords" content="template language"

  body
    h1 Markup examples
    #content.example1
      p Nest by indentation

    = yield

    - unless items.empty?
      table
        - for item in items do
          tr
            td = item.name
            td = item.price
    - else
      p No items found

    #footer
      | Copyright © 2010 Andrew Stone

    = render partial: 'tracking_code'

    script
      | $(content).do_something();

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; สำหรับ benchmarks ดูได้ที่ &lt;a href="http://github.com/stonean/slim"&gt;github.com&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; ที่มา &lt;a href="http://www.rubyflow.com/items/4712"&gt;rubyflow.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-3725988185525511869?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/Og_hiX6QCVs" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-16T09:12:31.341+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/10/slim-template-engine-version-070.html</feedburner:origLink></item><item><title>อักษรพิเศษในภาษา C++, Java, Perl, Python, Ruby และ Io</title><link>http://feedproxy.google.com/~r/thairor/~3/rqc1nOkI1QQ/c-java-perl-python-ruby-io.html</link><category>c++</category><category>Java</category><category>Perl</category><category>Ruby</category><category>Io</category><category>Python</category><author>noreply@blogger.com (Apirak)</author><pubDate>Sun, 15 May 2011 19:11:56 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5584161789534672434.post-5795776243703131269</guid><description>&lt;p&gt;วันนี้ไปอ่าน blog ที่ |one, step, back| นาย @jimweirich เค้าลองเปรียบเทียบ อักขระพิเศษที่แต่ละภาษาสร้างขึ้นมา เช่น &amp;lt; &amp;gt; , : ; { } [ ] ( ) โดยเค้าบอกว่าอักขระเหล่านี้ เป็นสิ่งน่ารำคาญ (Line Noise) &lt;br /&gt; &lt;br /&gt; จุดที่น่าสนใจคือเค้าตั้งโจทย์ง่ายๆ แล้วลองแก้ด้วยภาษาต่างๆ 5 ภาษา (มีคน comment เพิ่มอีก 1) ทำให้เรามองเห็นจุดดีจุดด้อยของภาษาต่างๆ ได้ชัดขึ้นมาก&lt;br /&gt; &lt;br /&gt; โจทย์มีอยู่ว่า "ให้วน loop เรียก method talk() ใน Array ที่มี Object 2 ตัว โดย Object ทั้งสองนั้นไม่เป็นคนละ Class"&lt;br /&gt; &lt;br /&gt; อ่านโจทย์แล้วอาจจะงง ดู code ในภาษาที่ตัวเองถนัดง่ายกว่า&lt;br /&gt; &lt;br /&gt; Language: C++&lt;/p&gt;
&lt;pre class="brush: cpp"&gt;#include &amp;lt;iostream&amp;gt;

  class Animal {
  public:
      virtual void talk() = 0;
  };

  class Dog : public Animal {
  public:
      virtual void talk();
  };

  void Dog::talk() {
      std::cout &amp;lt;&amp;lt; "WOOF\n";
  }

  class Cat : public Animal {
  public:
      virtual void talk();
  };

  void Cat::talk() {
      std::cout &amp;lt;&amp;lt; "MEOW\n";
  }

  int main() {
      Animal * (a[]) = { new Dog, new Cat };
      for (int i=0; i&amp;lt;2; i++)
          a[i]-&amp;gt;talk();
      return 0;
  }
&lt;/pre&gt;
&lt;p&gt;Language: Java&lt;/p&gt;
&lt;pre class="brush: java"&gt;public class Animal {
      interface IAnimal {
          void talk();
      }

      static class Dog implements IAnimal {
          public void talk () {
              System.out.println("WOOF");
          }
      }

      static class Cat implements IAnimal {
          public void talk() {
              System.out.println ("MEOW");
          }
      }

      public static void main (String args[]) {
          IAnimal[] zoo = new IAnimal[] { new Dog(), new Cat() };
          for (int i=0; i&amp;lt;zoo.length; i++)
             zoo[i].talk();
      }
  }
&lt;/pre&gt;
&lt;p&gt;Language: Perl&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;package Dog;

  sub new {
      bless {};
  }

  sub talk {
      print "WOOF\n";
  }

  package Cat;

  sub new {
      bless {};
  }

  sub talk {
      print "MEOW\n";
  }

  package main;

  for $a (Dog-&amp;gt;new, Cat-&amp;gt;new) {
      $a-&amp;gt;talk();
  }
&lt;/pre&gt;
&lt;p&gt;Language: Python&lt;/p&gt;
&lt;pre class="brush: python"&gt;class Dog:
      def talk(self):
          print "WOOF"

  class Cat:
      def talk(self):
          print "MEOW"

  for a in [Dog(), Cat()]:
      a.talk()
&lt;/pre&gt;
&lt;p&gt;Language: Ruby&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;class Dog
    def talk
      puts "WOOF"
    end
  end

  class Cat
    def talk
      puts "MEOW"
    end
  end

  for a in [Dog.new, Cat.new]
    a.talk
  end
&lt;/pre&gt;
&lt;p&gt;Language: Io&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;Io version: Dog := Object clone do(talk := method("WOOF" print))
  Cat := Object clone do(talk := method("MEOW" print))
  do(talk := method("MEOW" print)) list(Dog, Cat) foreach(talk)
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; จากการทดลองนับจำนวนอัขระพิเศษได้ผลดังนี้ครับ&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;animal.cc   (83):  #&amp;lt;&amp;gt;{:()=;};:{:();};::(){::&amp;lt;&amp;lt;"\";}:{:();};::(){::
                     &amp;lt;&amp;lt;"\";}(){*[]={,};(=;&amp;lt;;++)[]-&amp;gt;();;}
  Animal.java (67):  {{();}{(){..("");}}{(){..("");}}([]){[]=[]{(),()}
                     ;(=;&amp;lt;.;++)[].();}}
  animal.pl   (41):  ;{{};}{"\";};{{};}{"\";};$(-&amp;gt;,-&amp;gt;){$-&amp;gt;();}
  animal.py   (23):  :():"":():""[(),()]:.()
  animal.rb   (10):  """"[.,.].
  animal.io   (25): :=(:=("")):=(:=(""))(,)()
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; สรุปว่าภาษา ruby มีอักขระพิเศษน้อยที่สุด(Yo!) ทิ้งห่างภาษา python เท่าตัว และทิ้งห่างภาษา c++ ถึง 8 เท่า ส่วนหนึ่งเพราะ โจทย์ค่อนข้างอวยให้ Dynamic language มากๆ เพราะถ้าต้องการเทียบอักขระพิเศษ อาจจะเพิ่มโจทย์ให้มีการเรียก method ของ super class ไว้ด้วย ซึ่งจะทำให้ dynamic language ต้องเพิ่ม class ไปอีกหนึ่ง class&lt;br /&gt; &lt;br /&gt; ในบทความของ @jimweirich เค้าเขียน code ที่เอาไว้นับจำนวนอักขระพิเศษไว้เป็นภาษา ruby แบบนี้&lt;br /&gt; &lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;#!/usr/bin/env ruby
ARGV.each { |fn|
    noise = open(fn) { |file| file.read }.gsub(/[A-Za-z0-9_ \t\n]/m, "")
    puts "#{fn} (#{noise.size}): #{noise}"
}
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; เห็นแบบนี้แล้ว ลองมาหัดเขียน Ruby on Rails กันบ้างนะครับ&lt;br /&gt; &lt;br /&gt; inspire by &lt;a href="http://onestepback.org/index.cgi/Tech/Ruby/LineNoise.rdoc"&gt;|one, step, back|&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5584161789534672434-5795776243703131269?l=www.thairor.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/thairor/~4/rqc1nOkI1QQ" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-16T09:11:56.612+07:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.thairor.com/2010/10/c-java-perl-python-ruby-io.html</feedburner:origLink></item><media:rating>nonadult</media:rating></channel></rss>

