Ruby Float ?

irb(main):001:0> 1.005 - 1.000 => 0.00499999999999989 จำได้ว่าเป็น bug มานานแล้ว

Posted by Revolution Fri, 10 Sep 2010 08:04:57 GMT

Posted in  | Tags ,  | no comments | no trackbacks

จัดการ log สำหรับ production ใน Rails

ขั้นแรกคือกำหนดว่าใน production mode นี่เราจะใช้ log level ไหน ควรใช้ตั้งแต่ warn ขึ้นไป
config.log_level = :warn
แต่ว่าทั้งนี้ถ้า app นั้นเป็นแบบ internet อาจจะมีพวก bot หรือผู้ใช้อื่นๆ ที่เข้า url ผิทำให้เกิด error 404 หรือ routing error ควรจะกำหนดให้ logger นั้นไม่ได้ทำการ log ส่วนที่ error 404 หรือ routing error โดนเขียนลง ApplicationController
EXCEPTIONS_NOT_LOGGED = ['ActionController::UnknownAction',
                         'ActionController::RoutingError']

protected
  def log_error(exc)
    super unless EXCEPTIONS_NOT_LOGGED.include?(exc.class.name)
  end
แค่นี้ก็ไม่ทำให้ log โตเกินขนาดแล้ว ที่มา: http://maintainablesoftware.com/articles/rails_logging_tips

Posted by Revolution Mon, 21 Jun 2010 04:38:49 GMT

Posted in  | Tags , , , ,  | no comments | no trackbacks

rails kick start

ปกติผมเป็นคนขี้เกียจทำอะไรแบบเริ่มต้นมาก เวลาจะ start project ทีก็จะหาพวกที่เขาทำระบบ authenticate มาให้แล้วส่วนหึง อย่างเช่น Bort แต่หลังๆๆเหมือน Bort จะทำท่ารอ Rails 3.0 หรือกะไรไม่ทราบได้ จึงต้องออกแรงเองหน่อย โดยใช้ rails 2.3.8 กับ authenligic_bundle วิธีใช้ก็แสนง่าย
 $ rails <your-app> -m http://github.com/tsechingho/authlogic_bundle/raw/master/templates/remote.rb
หรือถ้ามี app อยู่แล้วแต่ยังไม่มีระบบ authen ก็ให้ใช้
  $ cd <your-app>
  $ git submodule add git://github.com/tsechingho/authlogic_bundle.git vendor/plugins/authlogic_bundle
  $ rake rails:template LOCATION=vendor/plugins/authlogic_bundle/templates/base.rb SCM=g
แล้วก็สั่ง

  $ rake db:seed
เป็นอันพร้อมใช้งาน

Posted by Revolution Thu, 17 Jun 2010 06:14:08 GMT

Posted in  | Tags , , , ,  | no comments | no trackbacks

gedit และ vim เพื่อการทดแทน textmate

ไม่เคยใช้ mac หรือนะ เลยไม่เคยมี textmate แต่คิดว่า gedit นี่ก็โอเคแล้ว Gmate: http://github.com/lexrupy/gmate/ วิธีลงก็

$ git clone git://github.com/lexrupy/gmate.git   
$ cd gmate 
$ sh install.sh
แจ่มสุดๆ ใช้ gedit open file ส่วนบางครั้งมันอยากแก้เร็วๆ เลยใช้ vim vimfile: http://github.com/akitaonrails/vimfiles วิธีลงก็
$ git clone git://github.com/akitaonrails/vimfiles.git .vim
$cd .vim
$ git submodule init
$ git submodule update
$ cp vimrc ~/.vimrc
ของอีตา akita ก็ดีอย่างคือเวลา module อื่นๆ มัน update เราแค่ทำคำสั่ง
git submodule update
มันก็ update

Posted by Revolution Mon, 23 Nov 2009 16:17:16 GMT

Posted in ,  | Tags , , , , ,  | no comments | no trackbacks

Luko Sharpening

ตอนนี้ลองเขียน Luko Sharpening โดยได้ศึกษาระบบการทำงานมาจาก kitty require 'RMagick' include Magick def luko(p) layer1 = p.unsharp_mask(40,1,0.18,0) layer2 = layer1.unsharp_mask(0.3,1,1.5,0) layer1.composite!(layer2,Magick::CenterGravity,DarkenCompositeOp) layer2.opacity=TransparentOpacity*0.5 layer1.composite!(layer2,Magick::CenterGravity,LightenCompositeOp) return layer1 end ตัวอย่างรูปที่ทำกับไม่ทำดูได้จากของ kitty นะครับ แต่บางถาพเช่นภาพคน บางรูปก็ไม่เหมาะทำ luko เพราะหน้าจะคจนเห็นกละ ชัดเจนมาก หุหุ

Posted by Revolution Thu, 01 Jan 2009 15:49:31 GMT

Posted in  | Tags , , , , ,  | no comments | no trackbacks

resize + unsharp-mask little by little

พี่แสนเคยบอกไว้มานานแล้วว่า เวลาย่อรูปเนี่ยเราไม่ควรย่อลงไปให้ได้ขนาดในทันที เช่น จาก 100% ไปเป็น 50% เราคววรจะแบ่งการย่อทีละนิดๆจาก 100% ไปเป็น 75% แล้วค่อยย่อจาก 75% ให้ได้ 50% หลังการย่อแต่ละครั้งให้ทำ unsharp-mask ด้วยจะทำให้ภาพคมขึ้นและดูสวยงาม
My brother SAN told me long time, when I have to resize, I should not resize to aspect ratio immediately such as 100% to 50%. I have to resize little by little from 100% to 75% then resize from 75% to 50 . Then after each resize process, it should be applied unsharp-mask filter. I will make more sharpen.
ผมก็เลยเขียนเพิ่มให้มันเป็นการแบ่งครั้งที่จะทำการ resize ได้ดังนี้
SHARPEN.times do nphoto = photo.resize(NEWSIZE**(1.0/SHARPEN)) photo = nphoto.unsharp_mask end
ดูได้จากภาพตัวอย่าง ได้ที่ multiply

Posted by Revolution Wed, 10 Sep 2008 16:01:23 GMT

Posted in ,  | Tags , , , ,  | no comments | no trackbacks

Ruby Fork

จากครั้งที่แล้วผมอยากจะเขียน ruby สักอันไว้ทำการ stamp ลายเซ็นพร้อมค่า exif ลงในรูป จากการลองเขียนเป็น thread แล้วปรากฏว่าไม่ค่อยมีประโยชน์เท่าไหร่กลับกลายเป็นว่ามี overhead ขึ้นมาเพียบและก็ทำงานไม่ครบได้ทุก core ที่มี งานส่วนใหญ่ในการทำงานเกี่ยวกับภาพนี่จะเป็นในด้านคำนวนซะเยอะ เลยเขียนเป็นลักษณะ fork ออกมาจะดีกว่า
พอลองได้เขียนก็ได้แนวคิดมา 2 แบบ คือ
  • ทำงานแบบเป็น lot คือทำพร้อมกันที่ละเท่าๆกัน แล้วรอให้เสร็จหมด ค่อยเริ่ม lot ต่อไป แบบนี้ถ้ามี process ใน lot เสร็จก่อนเพื่อนก็ต้องรอ
  • แบบที่สองคือเริ่มทำงานให้เต็มตามที่เรากำหนด ถ้า process ไหนเสร็จก่อนก็เอา process ใหม่มา run ได้เลย แบบนี้จะทำให้การทำงานต่อเนื่อง
แบบนี้คือการทำงานแบบเป็น Lot NUMFORK = 2 getImg = Dir['*.jpg','*.JPG','*.Jpg','*.jpeg'].sort.reverse Dir.mkdir("stamped") if !File.exist?("stamped") numFork = 0 while !getImg.empty? numFork = numFork + 1 photo = getImg.pop Process.fork{stampit(photo)} if numFork == NUMFORK Process.waitall numFork = 0 end end Process.waitall ส่วนแบบนี้คือการทำงานแบบต่อเนื่อง NUMFORK = 2 getImg = Dir['*.jpg','*.JPG','*.Jpg','*.jpeg'].sort.reverse Dir.mkdir("stamped") if !File.exist?("stamped") numFork = 0 while !getImg.empty? numFork = numFork + 1 photo = getImg.pop Process.fork{stampit(photo)} if numFork >= NUMFORK Process.wait numFork = numFork - 1 end end Process.waitall อย่างนี้ก็สบายใช้งานคุ้มทุก core

Posted by Revolution Thu, 04 Sep 2008 16:29:53 GMT

Posted in ,  | Tags , , , ,  | no comments | no trackbacks

My Failure with Ruby Multi-Thread

คือว่าผมใช้ debian + ruby + rmagick เขียน script เพื่อที่จะทำการ stamp รูป แต่มาได้ความคิดว่า อย่าง convert เนี่ย ถ้าเราเรียก $ convert -resize 1600 *.jpg มันจะใช้ cpu 1 core เต็มๆ แต่อีก core จะชิวๆ หรือไม่ทำงานยุ่งเกี่ยวกับ convert เลย ก็เลยลองให้มันทำ $ convert -resize 1600 *[02468].jpg & $ convert -resize 1600 *[13579].jpg & ผลลัพท์ที่ได้คือมันใช้ 2 core ทำงาน เป็นเพราะ shell เรียก convert นี่เป็น native ซึ่งมันจะไปทำงานแบบ fork จึงได้ผลลัพทธ์ดังกล่าว จากที่อ่านมา Fork คือ Heavy Weight Process ที่แยก resource กันชัดเจน ส่วน Thread คือ Light Weight Process ที่แบ่งปัน resource ซึ่งกันและกัน แต่ปัญหาอยู่ที่ว่าคือผมเขียน ruby คิดว่าถ้ามันเป็น thread ก็จะน่าได้ผลลัพธ์เช่นเดียวกับการ fork 2 ครั้ง แต่ผลลัพธ์ที่ได้กลับกลายเป็นว่า การทำงานนั้นไม่เต็ม 2 core คือใช้เพียงแค่ 1 core เท่านั้น จากการศึกษาเพิ่มเติมได้ผลออกมาว่า thread นั้นมี 2 แบบคือ user space และ kernel space
  • Kernel space จะเป็น thread แบบ native คือ kernel จะเป็นผู้จัดสรรและสับเปลี่ยน ก็จะได้ประสิทธิภาพตามคุณภาพของ kermel + cpu
  • User space หรือเรียกอีกอย่างว่า Green thread คือ thread ที่ทำงานแบบ time slice โดยผู้รับผิดชอบคือ VM (Virtual Machine) ในกรณีของผมคือ ruby นั่งเอง VM จะทำหน้าที่จัดสรรและสับเปลี่ยน เสหมือนเป็นการจำลอง thread อีกที ผลที่ได้คือ kernel เห็นเป็นเพีบง singel thread จึงทำงานได้เต็มที่แค่ 1 core
สรุปได้ว่า thread บน ruby นั้นป็น green thread จึงได้ผลลัพธ์ดังกล่าว ทางแก้ตอนนี้คือเขียนให้ ruby นั้น fork อีก process ไม่ใช่ว่า ruby thread จะไม่มีประโยชน์ ไว้จะลองเขียน ประโยชน์ของ ruby thread ดู

Posted by Revolution Wed, 03 Sep 2008 16:57:57 GMT

Posted in ,  | Tags , , , , , ,  | no comments | no trackbacks

Make a stamped for a Photo; ทำกรอบรอบรูป

หลังจากที่ได้ D80 มาสมใจอยาก เห็นหลายๆคนเวลาแสดงรูปจะมีการแสดงความเป็นเจ้าของโดยใส่ลายน้ำหรือใส่ข้อมูล exif หรือลายเซ็นไว้ ก็เลยอยากจะทำมั่ง ใน Photoshop ก็สามารถเขียน script(java script) ให้ทำทีละหลายๆรูปได้ หรือจะใช้ ACDSee ก็ทำได้ ส่วนสำหรับบน Linux ไม่ค่อยมีข้อมูลเท่าไหร่ แต่ Tools และ Libs เพียบ เลยตกงว่าจะออกกำลังเขียน ไหนๆก็ไหนๆ แล้วเขียนด้วย ruby ซะเลย นี่เป็น version ใช้เอง แต่ก็สามารถเขียนให้ดีกว่านี้เพื่อเอาไปใช้กับงานอื่นๆได้ code License GPL2


After I got D80, I saw many people show up their photos with a water mark, signature, exif data. I think that I have to do same way. Photoshop can do with a script, ACDSee can do also but Linux have no idea about that ( I may not know). By the way ,Linux come wiht many tools and Libs so I make a decision to write a ruby script for do that. This code is under GPL2 License. This version is for my own purpose, it may not be well design.


Requirement: Ruby 1.8.6, RMagick

Usage: run script at same Photo Directory, script will generate a directory "stamped" and file name is "stamped-.jpg"

Posted by Revolution Wed, 06 Aug 2008 10:18:16 GMT

Posted in ,  | Tags , ,  | no comments | no trackbacks

Passenger with some fcgi

I have a problem that I install passenger 1.0.3 that work fine with low transeaction web but for some web need high transaction , it need fcgi. The question that how can I use fcgi for some web and other run by passenger RailsAllowModRewrite on RailsAutoDetect off

Posted by Revolution Tue, 06 May 2008 15:47:10 GMT

Posted in  | Tags , , , ,  | no comments | no trackbacks