ค้นหาบล็อกนี้

วันอังคารที่ 18 พฤษภาคม พ.ศ. 2553

เพิ่มcommentsในblog

เราจะทำการเำพิ่มcommentsให้กับblogของเราโดยที่ความสัมพันธ์ระหว่างcommentกับarticle
เป็น(Article has many Comments and Comment belongs to Article)

1. ruby script/generate scaffold comment title:string description:string article_id:integer
2.rake db:migrate
3.ใน model/comment.rb
belongs_to :article
4.ในmodel/article.rb
has_many :comments
5.ในconfig/routes.rbให้
map.resources :article ,has_many=>comments
6.rake db:migrate
7.ใช้conceptเดิม เหมือนกับ author กับ article โดยในหน้า่ของshow.html.erb
ของcontroller =>articles ให้เขียนform_for เข้าไปยังaction create ของ controller
=>comments ทำได้ดังนี้

<%form_for :comment, @comment,:url=>article_comments_path(@article) do |f|%>
<%=f.text_field :title%>
<%=f.text_field :description%>
<%=f.submit "send"%>
<%end%>

โดยที่createของcontroller =>comments ให้เขียนโค๊ดดังนี้
@comment=Comment.new(params[:comment])
@article=Article.find_by_id(params[:author_id])
@article.comments<<@comment ใน action=>show ของcontroller=>comments
@comment=Comment.find_by_id(params[:id])
@article_link=Article.find_by_id(@comment.article.id)
redirect_to article_path(@article_link)

วันเสาร์ที่ 15 พฤษภาคม พ.ศ. 2553

render VS redirect_to

พอเริ่ม เล่น rails ไปเรื่อยๆ เหมือนอะไรๆจะเข้ามาเต็มไปหมด บางทีก็เลยมืนๆ เกี่ยวกับบางเรื่อง เช่น
render กับ redirect_to สำหรับ ผู้ที่เล่นจนคล่องแล้ว คงจะบอกว่ามันน่าสับสนตรงไหน แต่สำหรับคนที่เำพิ่งเ้ริ่มเล่น ก็มีงงบ้างว่า ควรจะใช้ 2ตัวนี้ในสถานการณ์ไหน
render คืือการสั่งให้ทำงานในส่วนของ views template ซึ่งหากจัดการเกี่ยวกับ database ก็จะส่งข้อมูลมายังcontroller แล้วเราก็สร้างหน้าตาของส่วนแสดงผลข้อมูล ที่ views template เพื่อ generate ให้ เป็น html ต่อไป
render
render :action=>:hello , :controller => :test

ส่วน การ redirection เป็นการส่ง request ผ่าน url โดย จะส่ง request กลับไป เป็นค่าเดิมที่้รับมาการrequest เดิม หรือส่งค่าใหม่กลับไปยัง action ในweb app เดียวกัน หรือต่างกันก็ได้ ต่างเว็บก็ยังได้
แต่ที่สำคัญเราสามารถส่งrequestที่มาต่อไปได้ (น่าจะเป็นอารมณ์เดีัยวกับ forward mails )
redirect_to :action=> :hell0 ,:controller =>:test , :name=>params[:name]
redirect_to :url=>"http:\\www.google.com"
redirect_to article_comments_path(@instance)

Rails practice I:: ลองเขียน blog โง่ๆ อันนึง

ได้ลอง สร้าง blog กากๆ จาก rails อยาก บอกว่าลักไก่มากๆ เนื่องจากเพิ่งเริ่มทำเป็นอันเแรก มาเริ่มกันเลยดีกว่าิเริ่มจากสิ่งที่จะทำคือ สร้าง blog ขึ้นมา อันนึงให้สร้าง account ของ คนเขียน บทความคือ author โดยคนเขียน หนึ่งคนสามารถสร้าง article ได้หลายarticle ...ดังนั้น ความสัีมพันธ์ระหว่าง author กับ article จึงเป็น แบบ one to many (author has many articles and article belongs_to author)
1. rails -d mysql myblog
2.cd myblog
3.สร้าง database myblog_development ใน mysql //ใช้ภาษาำไทย ไม่ได้เป็นไรไม่รุ ไว้ก่อนแล้วกัน
4.ruby script/generate scaffold author name:string surname:string
5.ruby script/generate scaffold article title:string content:text author_id:integer
6.rake db:migrate
7.ไปที่ models (/app/models)
ใน article.rb
class Article
belong_to:author
ใน author.rb
class Author
has_many :articles
8.ไปที่ routes.rb (/config/routes.rb) ให้เพิ่มดังนี้
map.resources :articles
map.resources :authors ,:has_many=>:articles//เพื่อสร้างsub route

เนื่องจากจะช่วยมากเลยในการเขียนเชื่อมระหว่างauthorกับ articleด้วยhelper tag path
เช่น author_articles_path,:method=>:post//จะลิงค์ไปยัง:action=>:createของ:controller=>:articlesแล้วที่สำคัญสามารถส่งauthor_idผ่านrequestได้อีกด้วยเจ๋งโคตร
ทำให้ได้routeไปarticles/id

จากนั้น ดู routes ทั้งหมด
rake routes >temp.txt //เพื่อจะได้ ใช้ helper tag เพื่อลิงค์ไปยัง :action ,:controllerได้อย่างถูกต้อง
9. ทดสอบความถูกต้อง ruby script/server
http://localhost/articles
http://localhost/authors

10.เนื่องจากเราต้องการให้มีการสร้าง author ก่อน แล้วจึงให้มีการเขียน blog ได้ ให้เราแก้ไขดังนี้

- ไปที่ show.html.erb (/app/views/authors/show.html.erb)ให้เพิ่ม link "write blog" ไว้โดยเราจะส่ง id ไปยัง action "new" ใน articles controller
<%=link_to 'Write Blog',new_author_article_path(@author_id),:method=>:get %>
// new_author_article GET /authors/:author_id/articles/new {:controller=>"articles", :action=>"new"} ดูจาก temp.txt

-ไปที่ articles_controller .rbให้เพิ่ม @author=Author.find(params[:author_id])และ@article=Article.new ใน action new เพื่อ รับ :author_id จากการ link ใน show.html.erb

-ไปที่ new.html.erb เราจะส่งค่าของtitle,contentของinstanceของArticleไปยังaction"create"ผ่านrequest keyที่ชื่อ":article"โดยใช้
form_for ดังนี้

<%form_for :article,@article,:url=>author_articles_path do |f|%>
<%=f.text_field :title%>
<%=f.text_area :content%>
<%=f.submit "create"%>
<%end%>
ด้วยการroutingแบบส่งidไปตามrequestด้วย หากต้องการเพิ่ม article เราจำเป็นต้องเข้าไปยังauthorก่อน เราำไม่อาจเข้าไปยังarticleแล้วเพิ่มarticleได้โดยตรง
คำอธิบาย
เนื่องจากform_forเป็นการส่งข้อมูลผ่านทางrequestเำพื่อเป็นการสร้างinstanceของclassในรูปแบบของformกรอกข้อมูลจากตัวอย่างอธิบายได้คือเราจะสร้างformกรอกข้อมูลให้กับบทความที่จะสร้าง
โดยที่

:articleคือparams[key]คือhashนั่นเองที่เราจะส่งผ่านrequestดังนั้นค่าของ
params[:article]={:title=>".......",:content=>"........."}

@articleเป็นinstanceของclassArticleในmodelโดยที่เราจะต้องสร้า่งinstanceในcontroller articles action"new"ก่อน@article=Article.new

:url=>author_articles_pathเป็นhelper tagในการrouteไปตามpathที่ได้ทำการmap.resourceดูได้จากrake routes>tmp.txt ในที่นี้จะส่งไปยัง createเพื่อสร้างบทความเนื่องจากinstanceยังไม่มีค่าแต่ถ้ามีค่าจะเป็นการupdate

f.text_fieldเป็นการสร้างtext filedในการรับค่าจากuserเพื่อส่งไปยังproperty":title"
ดังนั้นหลังmethods"tex_field" จึงต้องเป็น property ของ instance@articleเท่านั้น

โดยform_forทั้งหมดส่งไปตามurlที่ระบุไปที่actionหรือcontrollerโดยจะส่ง:author_idผ่านrequestไปด้วย
ดังนั้น:actionปลายทางจะรับauthor_idดังกล่าวแล้วเราสามารถนำไปใช้ต่อได้
เ่ช่น @article=Atricle.new(params[:article])
@author=Author.find_by_id(params[:author_id])
@author.articles<<@article //เท่ากับบอกว่าauthorมีarticle@article(บทความที่เพิ่งสร้างใหม่)


วันศุกร์ที่ 14 พฤษภาคม พ.ศ. 2553

Ruby on Rails part IV

การสร้าง CRUD (Create Retrieve Update Delete)

1.ในการสร้างcrud โดยไม่ใ้ช่ scaffold
เราจะต้อง สร้าง model เช่น
ruby script/generate model student name:string surname:string
2.จากนั้นก็สร้าง controller
ruby script/generate controller students index new create update destroy edit show
3.จากนั้น ก็ไำปที่ config /routes.rb ไป map.resources :students

map.resources :students //students is a table name และ controller name ควรที่จะ ตรงกัน เนื่องจากหากมีการ route เกิดขึ้นซึ่งในที่ันี้ จะเป็น /students และ หากทำการ map.resources ดังกล่าว จะำได้ helper tag โดยจะมี path ที่ขึ้นต้นด้วย/students
<%form_for @student do|f |%>
<%=f.submit_tag "create/update"%>
<%end%>


Using Rails HelperTag for Access Resource
เนื่อง Rails มีการทำ resource mapping ซึ่งสามารถจัดการทรัำพยากร เช่น ตาราง students ใน database
โดยที่ ส่วนใหญ่แล้วเราก็ต้องมีบริการ พื้นฐานการจัดการ students เช่น การเพิ่ม จำนวน ลบ แสดงผล รายชื่อนักเรียน เป็นต้น เวลาที่เราจะไปใช้บริการดังกล่าวได้เราก็ต้อง route ให้ตรงกับบริการดังกล่าว(หลักๆแ้ล้วมี 7 ตัว)ซึ่งจะไปยัง controller ,action ต่างๆ ตามแปลความจาก routing path ดังนั้น rails จึงมีการสร้างการmap resources ไว้ใน route.rb ซึี่งเอาไว้สำหรับสร้างกฎการ route ให้กับ การบริการ resources ส่วนเรื่องรายละเอียดการบริการก็ต้องใช้action ใน controller เป็นตัวเชื่อมต่อกับ view เพื่อแสดงผลการบริการ


resources_path สามารถแปลงเป็น route ของ/
เช่น students_path ซึ่งเป็นไปได้ 2 กรณีคือ
ใช้กับ method 'GET' =>/resources
ใช้กับ method 'POST' => create

new__path เปลี่ยนเป็น route เช่น /resource/new

resources_path(instance) มีการรับparameter เป็น instance จะได้route เช่น /students/ 1
ซึ่งเราสามารถเลือก method เป็น DELETE กับ PUT ได้

ถ้าีinstance มีค่า =>/students/id =>show
ถ้า instance ไม่มีค่า => /students =>index

ถ้ามีค่า ตามด้วย method "put" =>put ของ id นั้น//ปกติใช้ form for เนื่องจากต้องส่งค่า
ถ้ามีค่า ตามด้วย method "delete" =>delete ของ id นั้น
<%=link_to "delete" , resource_path(instance) ,:method =>:delete %>


edit_resource_path(instance) => /resource/:id/edit
เช่น edit_student_path(@s1)

ส่วน การสร้าง link ไป ยัง create , update จะต้องใช้ form_for เนื่องจาก มีการ ใช้ method "POST " กับ "PUT"เช่น
<%form_for@student do |f|%>
Name<%=f.text_field :name %>
<%end%>
โดยที่ จะเป็นcreate หรือ update ขึ้นอยู่กับว่า @student มีค่าหรืิอไม่ ถ้ามี ->update ไม่มี ก็ไปที่ create ดังนั้น
หาก @student =Student.new // ไป action =>create
@student =Student.find(1) //ไป aciton=>update
ถ้าไม่มีการสร้าง action create หรือ update ไว้ ก็จะฟ้อง

ปล. <%=link_to %> กับ <%=button_to %> จะต่างกันที่ button_to จะมีไม่มีการ link ไปยัง path ที่ใส่ไว้ แต่เปลี่ยน แค่ URI เท่านั้น
เราต้องทำการ map resource ก่อน จึงจะสามารถใช้ helper tagได้
ถ้าเราำไม้่มีการ map resource ไว้ แต่เราก็สามารถ อ้างอิงได้ แต่เป็นไปตาม กฎของ route ที่มีอยู่้เช่น
<%= link_to "Back" , :controller =>:students,:action=>:index %>


ปล.ถ้าเข้าใจ concept แล้วให้ใช้ generate scaffold ไปเลย ซึ่งจะสามารถสร้างที่กล่าวมาได้ทั้งหมด

Method for managing in database
find(:id) // find(1)
find :all ,:limit,:conditions,:read_only,:order,:form
ex. find :all ,:select=>"id,name",
:limit=>3,
:conditions=>":name='benz' AND :surname='narak' ",
:form
=>"tables WHERE dept='cs' ",
:order=>"name DESC",
:read_only
=>true


find_by_* //find_by_name
find_by_sql "_______"

>>Student.methods
Student.create :name =>" ",:surname=>""
Student.new(params[:students])

Method for instance
student.save
student.delete
student.destroy
student.update_attributes :name , "benz"

วันพฤหัสบดีที่ 13 พฤษภาคม พ.ศ. 2553

Ruby on Rails part III

Helper ใช้ช่วยสร้าง HTML โดยที่ view template สามารถเรียกใช้ได้
รูปแบบการใช้งานhelper
<%= link_to "text" ,:action => :actionname %>
<%=button_to "buttonname" ,:action => :actionname%>
ซึ่งแนะนำให้ใช้ แทน html ทั้ืงหมด

ข้อสังเกต
<%=form_tag ''/test/hello%>



<%form_tag :controller = :test ,:action =:hello do%>

<%end%>
จะสังเกตเห็นว่า แบบแรกใช้ expression ส่วนแบบที่สองใช้ scriptlet ซึ่งส่วนใหญ่แล้ว scriptlet ก็คือ ไม่มี = จะใช้แสดงผล ของค่า ส่วน scriptlet จะใช้กับภาษา ruby ที่ำไม่มีการแสดงผลของ ค่า โดยจะเห็นว่ามีการใช้ <%end%> ครอบด้วย ซึ่งไม่ได้แสดงค่าอะไร ซึ่งหากแบบที่สอง ใส่เครื่องหมายเท่้ากับหน้า form_tag ก็จะcompile error

<%form_tag :action=>:hello do%>
<%=text_field_tag "name" ,"benz" , :size=>6,:maxlength=>5 %>
<%=submit_tag "OK",:disable_with=>"Please wait"%>
<%end%>
อันนี้เจ๋ง กด OK แล้วตรงปุ่มจะเปลี่ยนเป็น Please wait
เจ๋งกว่า เมื่อกี้อีก ใส่รูปให้ปุ่มได้ด้วย

<%form_tag :action => :hello do%>
<%=text_field_tag "name"%>
<%=image_submit_tag "rails.png"%> #\public\images\rails.png
<%end%>

<%form_tag :action=>:hello do%>
<%=hidden_field_tag "name","hey"%>
<%= submit_tag "OK"%>
<%end%>

hidden_field _tag =>เอาไว้ซ่อน เวลาส่ง ค่ามีแต่ปุ่มให้กด
<%form_tag :action=>:hello do%>
<%=password_field_tag "name"%>
<%= submit_tag "OK"%>

What is your name?
<%form_tag :action=>:hello do%>
<%=radio_button_tag "name","benz"%>benz
<%=radio_button_tag "name1", "benznakub"%> benznakub
<%=radio_button_tag "neme2" , "benzs"%>benzs
<%=submit_tag "OK"%>
<%end%>
สังเกตว่า ตรง name หมายถึง group กล่าวคือ กลุ่มเดียวกันเลืิอกได้อันเดียว
ข้อดี อีกอย่างสามารถส่งพารามิเตอร์มาได้ เลย


Implement Model RelationShips
แบบ one to many เช่น ความสัมพันธ์ของ Author กับ Article
-> สร้าง model ของ Author แล้วกำหนด Attribute
-> rake db:migrate
->สร้าง model ของ Article แล้ว กำหนด Attribute โดยหนึ่งในนี้ต้องมี author_id เนื่องจาก ทั้งสองมีความ สัมพันธ์ โดยที่ Author (ผู้แต่ง) สามารถเขียน บทความ ได้ หลาย บทความ แต่ Article (บทความ )
หนึ่งบทความมีำคนแต่งไำด้คนเดียว(bussiness Rule) โดยสรุป แล้ว Article จะต้องเก็บ idของ author
เพื่อใช้ในการหาว่า คนแต่งบทควา่ม นั้น แต่บทความอะีไรไปบ้าง
->rake db:migrate
->จะต้องระบุความสัมพันธ์ในส่วนของ dbmodel (ไปที่ app/model/)ซึ่งจะมี class ของ Author กับ Article อยู่โดยที่
ใน class Author จะต้องมี has_many :articles
ใน class Article จะต้องมี belongs_to :author


วันอังคารที่ 11 พฤษภาคม พ.ศ. 2553

Ruby on Rails part II

Rails helper

Array of Objects
variable
local variable=> อยู่ใน method เป็นชื่อตัวแปร
instance variable =>@ จะมีค่าเมื่อมีการ assign ค่าผ่านทาง instance
class variable => @@

สรุป
ถ้าประกาศ
x เป็น local variable ใช้ ได้เฉพาะใน function หรือ scopeที่ประกาศไว้เท่านั้น
@x เป็น instance variable -> ควรประกาศตอนinitialize
เชื่อมกับ view template
@@x เป็น class variable -> สามารถอ้างอิงได้ทั้ง instance methods และ class method
$x เป็น class variable -> globle ไม่ถูกลบ ใน development จะเคลียร์ได้ ในproduction จะอยู่คงที่

class Ex
def self.___
end
end

Ex.___
Active Record เป็นคลาสที่จัดการเกี่ยวกับ database
Rails จะเชื่ิอมระหว่่าง Data model กับ database โดยคนเขียนโปรแกรมจะยุ่งแค่ data model ส่วนใน
database จะมีmethod จัดการ property ให้ในการติดต่อเพื่อที่จะต้องดึงข้อมูลของ property หรือ เก็บข้อมูลในdatabase จะใช้yml เป็นตัวบอก active record ว่าต้องเก็บไฟล์ไว้ที่ใด มีข้อมูลใดบ้าง

database.yml มีข้อมูลเกี่ยวกับฐานข้อมูลที่จะใช้งานในตอน development test และ production
-adapter
-host
-username
-database
-timeout

เมื่อเราสร้าง model จะมี ไดเรกทอรี \db\migrate โดยจะมีการสร้างไฟล์ 001_create_students.rb
เช่น เมื่อเราสร้าง Model Student จะได้
class createStudents
ชื่อตาราง คือ students
001 คือ version การ migration
ปล.หากเราต้องการแก้ไข migration เช่น เราสร้าง migration 001 หากเราต้องการแก้ไขmigration ดังกล่าวให้เราroll back ไปversion 000 ก่อน จากนั้น แก้ไฟล์.rb version 001แล้ว remigration ใหม่
ชนิดข้อมูลของ column
:binary
:boolean
:date :time :datetime
:decimal
:float
:integer
:string

methods self.up เปลี่ยนแปลงฐานข้อมูล
self.down ถอยกลับมาหนึ่งversion
เราจะใช้ block| t | ในคลาส CreateStudents กำหนด field ใน ตาราง ซึ่งเป็น property ของ class

Syntax
datamodel โครงสร้างสำหรับการเก็บข้อมูลลงในdatabase

ruby script/generate model student name:string dept:string
จะเป็นการสร้าง model testโดย
ชื่อของ class ไว้อ้างอิง class method ในการจัดการเกี่ยวกับ property
ใน /models/ จะมี student.rb


Migration
เป็นการสร้าง โครงสร้างตารางใน database ตามแบบ data model ที่เราได้ออกแบบไว้ โดยสิ่งที่เราจะต้องทำก็คือ
เราต้องสร้าง model ก่อน ด้วยคำสั่ง
ruby script/generate model student //ซึ่งจะเป็นการสร้าง data model ซึ่งโดยปกติแล้วจะมีการสร้าง migration เริ่มต้นมาให้ หากยังไม่มีการสร้าง migration version ของ มัน จะเป็น 000 (ใน /db/migrate/ จะมีำไฟล์ version_create_student.rb อยู่ด้วย)แล้วเมื่้อมีการ migration ครั้ิงแรกก็จะเป็น 001 โดยจะแบ่งเป็น 2ส่วน
-ในส่วนของ datamodel จะมีการสร้าง class studentให้สามารถจัดการ datamodel ได้ด้วยหลักการ oopและ การ relation กันของ datamodel
-ในส่วนของ database จะเป็นส่วนของการสร้างตารางใน database การเปลี่ยนแปลงโครงสร้าง database ตาม โครงสร้าง datamodel นั้น

การ remigration และการ rollback
เนื่องจากในการสร้างตารางในdatabase เราอาจมีการเปลี่ยนแปลง field ต่างๆดังนั้น จึงมีการให้สร้าง version ของ migration ขึ้น หากเราต้องการเพิ่มบาง filed จากโครงสร้างเดิม เราก็แค่สร้่าง version ใหม่
ตามแล้วใช้ method ในการ add_column ซะ (remigration) แต่เราจำเป็นที่ จะต้องสร้าง method ในการย้อนกลับสิ่งที่เรา้้เพิ่มเติมมาด้วยเผื่อเปลี่ยนใจ มั้ง (rollback) อาจเป็นนามธรรมเกิน สิ่งที่เราต้องทำก็คือ
-1.สร้าง migration ขึ้น
ด้วยคำสัั่ง ruby script/generate migration name
-2.จัดการ ไฟล์ ที่อยู่ใน /db/migration/ verrsion_name.rb เช่น เพิ่้ม method add_column ใน self.up และ method remove_column ใน self.down
โดยใช้หลักที่ว่า method self.up ทำอะไร ไปจากversion เดิม ใน self.down จะต้องทำกลับให้เหมือนกับ version เดิม เนื่องจาก
1.remigration self.up จะทำงาน หาก rollback self.down จะทำงาน

2.เราสามารถ remigrate ไปยัง version ข้างหน้า(เช่น จาก 1ไป3) ได้ โดยที่มันจะเริ่มทำงาน self.upจาก 1 ไป2 จาก 2 ไป 3 และในการ rollback ไปยัง version ข้างหลัง (เช่น จาก 3ไป 1 )ได้ โดยที่มันจะเริ่มทำงาน self.down จาก 3 ไป 2 และไป 1

3.ทำการ remigration หรือ rallback ด้วยคำสั่ง
rake db:migrate หรือ
rake db:migrate VERSION=2

4.ตรวจสอบ จากใน database ว่า มีfiled เพิ่มอ่ะป่าว

methods
add_column =>เพิ่ม คอลัมน์
rename_column =>เปลี่ยนชื่อ
change_column =>เปลี่ยน type

Syntax
Student.create(:name => "_____",:dept=>"____")
Student.find(1)
Student.find_by_symbol "___"
Student.find_by_sql "sql_language"
Student.find :all

Model Relation
One to One
One to Many
Many to Many

Validation and Callback
ตรวจสอบข้อมูลของค่าต่างๆ และตรวจสอบความถูกต้องตอน
ไหนก็ได้ เช่น ห้ามใส่ข้อมูลเกิน 10 มีอยู่2วิธี คือ ตรวจสอบเอง กับใช้ื built in
class Student <3 style="font-weight: bold;"><%=error_messeges_for :student%>


Built In
1. validate_presence_of =>
ตรวจสอบว่ามีค่า (ไม่เป็น nil)
2.validates_uniqueness_of =>
ไม่ซ้ำกับค่าที่มีอยู่แล้วในฐานข้อมูล
3.validates_inclusion_of =>
ต้องมีค่าในArray
4.validates_length_of

Callback Methods สามารถกำหนดการทำงาน validate ตอนไหนก็ได้ของ create
before_validation: function
before_create: function
เราต้องประกาศ def ด้วยว่าจะทำอะไรโดย
def dept_map
if self.dept=="cs"
__________
end

callback class ->สร้่างไฟล์.rb อีกไฟล์นึงใน models แล้วสร้าว class
class ______
def self.before_create(model)
if model.dept ==" "
____________
end
end
end




ตรวจสอบ dbModel
rake db:test:prepare
-เข้าไปที่ \test\unit แก้ไฟล์ .rb เพื่อตรวจสอบ
-พิมพ์ ruby test\unit\greet.test.rb ในcommand line
หรือใช้ rake test:units ตรวจสอบไฟล์ทั้งหมด

Make Assertions
หมือนตั้งสมมติฐาน
assert_equal "hello world" g.hello("world")

1 tests , 2 assertion , 0 failures , 0 errors

1 tests จำนวนfuncที่นำมาทดสอบ
2 assertion จำนวนที่ผ่านจากการตรวจสอบ
0 failures มีข้อผิดพลาด(ผิดที่ symantics)ที่ได้ค่าำไม่ตรงกับ assertion
0 errors ผิด syntax

syntax
assert_equal output , instance.f("__")
assert instant.f("___")

setup method ถ้า function ใน assertion จำเป็นต้องการใช้บางอย่างร่วมกัน
เช่น instance เดียวกัน สามารถ ประกาศไว้ใน setup เพื่อ share กันได้โดยsetup จะืำทำ
ก่อนมีการtest แต่ต้องป็นตัวแปร @___



Ruby on Rails part I

Rails
gem->ตัวช่วยติดตั้ง package ของภาษา ruby
irb.bat เป็น interpreter ของภาษา ruby แบบ interactive
เว็บapp ขนาดเล็กจะใช้ mongrel เป็น เว็บ server แต่พอมีขนาดใหญ่จะใช้ apache แทน
rails ถูกออกแบบมาให้ไม่ใช้ xml
controller ของ Rails จะต้องเขียนด้วยภาษา Ruby แต่จะสร้าง html ด้วย การ render views template ซึ่งจะเขียนด้วย ภาษา ruby+helper(เป็นตัวช่วยสำหรับการสร้างviews template เช่น รูปแบบการ link )

action
คือ method โดยที่้เราออกแบบให้ทำหน้าที่หนึ่งๆโดยส่วนใหญ่จะเอา action ที่ใช้ทรัพยากรร่วมกัน ไปไว้ใน controller เดียวกัน

syntax

rails myapp
ruby script\server //run webserver
ruby script\generate -h // ดูว่าเราสามารถสร้างไรได้บ้าง
ruby script\generate controller name action ..
โดยที่ code generator จะสร้างไฟล์
index/html.erb
name_controller.rb
name_helper.rb
name_controller_test.rb

ActionPack(ActionController &ActionView)
View Template ->ไฟล์ที่จะถูก view แปลงเป็น html แล้วส่งกลับไปแสดงผลใน browser โดยเราสามารถเขียนแสดงผลลัพธ์ที่ำจากการคำนวณจาก model ที่ส่งผ่าน controller ซึ่งรูปแบบการเขียน มี2 อย่างคือ
1. Scriptlet <%now =Time.new %>
2.Expression <%=now %>
view template จะถูก render โดย action ใน controller
เมื่อมีการส่ง Parameter แบบ Post จะมีการสร้่าง hash ที่ชื่อ params แล้วเก็บค่า name กับ value ที่อาจจะได้จากการ routing path
Request Parameter "id"
/controller/action/id ? parameter=value
Rais Environment คล้ายกับการจัดสิ่งแวดล้ิอม ให้กับการserver แบบไหน
development ->กำลังพัฒนา
Test -> ตรวจสอบโปรแกรม
Production ->เสร็จ 2 อย่างแรก แล้ว
สามารถเลือก option ได้โดย ruby script\server -e production

Logging the Request
ไฟล์ .log ใน \logs ของทุกเว็บ app
มี logger ให้ controller และ model เขียน logging ใส่ไฟล์
เช่น logger.info // ระดับความสำคัญของข้อมูล(info ,warning ,error)

Raising Exception ให้โปรแกรมที่ถูกเรียกทำงานส่งข้อมูลกลับไปบอกผู้เรียกว่าเกิดข้อผิดพลาด
จะทำให้ การจัดการ request หยุดลงแล้ว ข้อมูลของ raise จะถูกส่งออกไปที่ browser
raise ___

Flash -> hash ที่ถูกสร้างขึ้นอัตโนมัติสำหรับให้ action กำหนดข้อความที่จะถูกนำขึ้นบน view template
โดยที่ action จะสร้าง render เสร็จทำลายทิ้ง
flash[:msg]="____"

เวลา request ถ้าเป็น controller แล้ว action เป็น index ให้เรียก
/controller/?.....
แต่ถ้า action มีชื่ออื่นจะเรียกด้วย
/controller/actionName/?....

interpulation ->กลไกสำหรับแทนค่าตัวแปรลงใน string
เ่ช่น str="World!"
puts "Hello "+str หรือ puts"Hello #{str}" // Hello World!

View Rendering
render{:action =>}
หรือ render :action=>:hello
"hello"
การ render :action จะ render view template ที่อยู่ในcontroller เดียวกันเท่านั้น
ซึ่งโดย default ของการ render เช่น เรา สร้าง action 'index' ไว้ ถ้าำไม่มีการระบุว่า render ที่ใด
ก็จะไป render ที่ View template ที่มีชื่อเดียวกับ action

Render Template

render:template => ใช้กับview template ที่อยู่ใน controller เดียวกัน หรือ ต่างcontroller ก็ำำได้ โดย path จะเทียบกับ app\view โดยpath จะต้องเป็น String เืท่าันั้น

Redirection เรียกกลับมาใหม่ที่actionที่เว็บแอป เดียวกัน ต่างกันก็ได้ ข้ามเว็บก็ได้
redirection_to :action=> :ชื่อ action
เหมือนกลับมาใช้ action เดิม แต่ไม่มีการส่งพารามิเตอร์แล้ว
redirect_to :action=>:actionname,:name => params[:name]
redirect_to :action =>:______ , :controller=>:_____
redirect_to :url=>"______"

Action Call and Rendering
action หนึ่งสามารถ redirect ไำด้ครั้งเดียว เช่น หากมีการใช้ action อื่น แล้ว render View ของ action อื่นก็จะำไม่สามารถ render viewtemplate ของตัวเองได้เนื่องจากป้องกันการเรียกตัวเอง
ซึ่งมี2วิธีในการแก้ไข
1.หลีกเลี่ยงการ render view template ตัวเอง
2.หากต้องการ render view template ตัวเองก็ใช้ action อื่นช่วยทำงานแล้วกลับมา render
view template ตัวเอง
3.redirect action อื่นเทน

Rendering Text
render:text =>
render :inline => "<%script ruby เพื่อเลือก View template Render%>"

Template
เราสามารถ สร้าง template ขึ้นเองได้ โดยเราเิอาไปไว้ใน (app/view)แต่ให้เป็น.html.erb

<%=render

วันจันทร์ที่ 10 พฤษภาคม พ.ศ. 2553

Technique String methods in Ruby

String Method
- insert(index,string)
- tr แทนที่ str ด้วย pattern
// ex. str ="1234512" pattern="123"
str.tr(pattern, "*"); //***45**
-sub
-gsub


Array Method

-> collect จะมีการเรียก blockสำหรับ แต่ละ element โดยจะมีการสร้าง array ใหม่
ที่ประกอบด้วยค่าที่ return มาจาก block
เช่น a=["a","b","c","d"]
a.collect{|x|x+"!"}
ให้นึกว่า เรามี กลุ่้ม ของทหาร แล้ว เราจะออกคำสั่งให้มันทำอะไร ซึ่งทุกตัว จะทำตามคำสั่งทั้งหมด

->select
a=[1,2,3,4,5]
a.select{|x| x%2=0} จะมีการเรียก block ที่ส่งค่าของ Array element
โดยผลลัพท์ที่ได้ คือ อาร์เรย์ที่ประกอบด้วย สมาชิกที่ทำการตรวจสอบเงื่อนไขแล้วเป็นจริง

->replace =>แทนที่ content array เดิม ด้วย array ใหม่
เป็นการเลือก ตามเงื่อนไขธรรมดา
-delete =>จะ returnตัวที่ delete ไป
-delete_if=> จะ return arrayของตัวที่เหลือ
-fill =>ใส่ค่าที่ต้องในช่วงของ Array
-nitem =>return non-nil element
-compact => return copy array เดิม ที่ำไม่มี nil
-reject =>return array ใหม่ ที่ำ block return false


Enumerable method

-> any ? ใช้เหมือน for some x
->all?
ใช้เหมือน for all x
->inject รวมกลุ่มของ elementโดยมีการสะสมค่าเดิมเอาไว้
เช่น
form: s.inject(initial){|x,x_next| ....}
s=[1,2,3,4,5]
s.inject(0){|sum,n| sum+n} //15


วันอาทิตย์ที่ 9 พฤษภาคม พ.ศ. 2553

Threading in Ruby

ได้ลองไปเล่น Thread ใน Ruby มา เป็นเหมือนกับการกระจายงานออกเป็นส่วนต่างกันทำซึ่งจะต้องควบคุมให้ทำงาน ถูกต้อง
Thread
T=Thread.new{ instruction}
instruction เช่น print "a"
method "join" => เมื่อมีการประกาศ thread ที่ไม่ได้มีการประกาศ join ,threads นั้นจะ ถูก ตัดไป ตอนเริ่มMain Program ในการเรียกใช้ Thread จะมีการ ระงับการ execute และจะไม่return ค่าจนกว่า threads นั้นจะสิ้นสุด หรือ เวลาในการเรียกใช้ thread จะหมด หรือ มีการ return ค่า
proof
t=Thread.new{puts "a"} // "a"
t=Thread.new{puts "a";sleep(5) } // "a" หยุดเลย
แต่ถ้า
t=Thread.new{puts "a" sleep(5)} //"a " 5วิ หยุด
t.join

t=Thread.new{puts "a" sleep(5)} //"a " 5วิ หยุด รอจนครบ 10 วิเนื่องจาก มีการ กำหนด เวลาให้ thread
t.join(10)

ex...
t1=Thread.new{5.times{sleep(0.2);print "world"}}
puts "hello" until t1.join(10)
so...

T.join
T.join(limit) //limit คือเวลาหน่วยวินาที

วันศุกร์ที่ 7 พฤษภาคม พ.ศ. 2553

Basic Ruby ::part(IV)

Math && RUBY
นำหน้าด้วย
0b ->for binary number
such as 0b101
0-> for octal
0x ->for hex
** for power
^xor
flt.round => integer
x.floor
x.ceil
สามารถprintf("%6.2f",x) ทำได้เหมือนใน C เลย
x1.divmod(x2) //result =[x1/x2,x1%x2]
q1,q2=x1.divmod(x2)

i1=3
i1[2]=0 i1[1]=1 i1[0]=1

BigDecimal
provides similar support for very large or very accurate floating point numbers.
เนื่องจากการเก็บ ค่า ตัวเลขจะเก็บในรูปของ string ที่เป็นเลข ASCII
แล้วทำการ converse เป็นตัวเลขเมื่อใช้มันอีกที เช่น มีเลข 8 ถ้าเป็นแบบ float ธรรมดา
โดยไม่ใช้ bigDecimal จะแปลงเป็นbinary =>1000 แต่หากเป็น bigDecimal
จะเก็บเป็นASCII ของ 1 0 0 0 ซึ่งอาจทำให้่เสีย performance แ่ต่มัน accuracy กว่ากันเยอะ

require 'bigdecimal'
BigDecimal.new("1.2")

require 'bigdecimal/math'
include BigMath
BigDecimal::PI(number หลัง ทศนิยม)
BigDecimal.sin(BigDecimal.PI(radian), ...)
BigDecimal.sin(BigDecimal.new('1'), ...)
ปกติ

Math::PI =>
Math.sin(radian)
Math.sin(Math::PI)
...

8.to_s(2) => "1000"
8.to_s(8) =>"10"
...

require'mathn'

8.gcd2(120) //
36.lcm(120) //
-----------------------------------
class Prime
Prime.new
Prime.next



rand ->pseudo random =>using statistic sampling random because the natur e source for random is the decay but electron can not predict so you use a large sampling size to random
n=rand //random in range 0.0 -1.0
n=rand(10)


SYMBOL in RUBY
=>class Symbol
เราต้องมองก่ิอนว่าค่า 1 , 2 , 3 นั้นมีค่าเดียวใน ระบบ
เช่นเมื่อลอง พิมพ์ 1.object_id => สมมติว่า ได้ 3
2.object_id =>
สมมติว่า ได้ 5
3.object_id => สมมติ ว่าำได้ 7
ถ้าเราบอกว่า
m=1 //เมื่อ m คือ variable นึกเสียว่า มี setของ ตัวเลขแล้วตัวแปร
m ชี้เลข 1 อยู่
ซึ่งถ้าลอง m.object_id // ได้ 3 จะเห็นว่า m มันชี้ค่า 1 (เนื่องจากมีการอ้างอิง object _id เดียวกันกับ1 ซึ่งเป็นตัวระบุความแตกต่างของสิ่งที่เราประกาศ)
m=2
m.object_id//ได้ 5 เปลี่ยนไปชี้ที่ ค่า 2
(เนื่องจากมีการอ้างอิง object _id เดียวกันกับ2 )
จากส่วนนี้ทำให้เห็นว่า ตัวแปร(variable) สามารถชื้ำไปได้หลายค่า ซึ่งเราสามารถ assign ค่าได้
n=2
n.object_id //ก็ยังได้ 5 เปลี่ยนไปชี้ที่ ค่า 2(มี object_id =5)
m==n //ได้ true รู้ได้อย่างไรว่า เท่ากัน ก็อ้างอิง object_id เดียวกัน
จากส่วนนี้ จะได้ว่า ตัวเลข 2 นี้จะมีค่าเดียวโดยที่ถ้าเราประกาศตัวแปรอะำไรก็ตาม
แล้วassignค่าเท่ากับ 2 มันก็จะชี้มาที่ตัวเลข 2 ตัวเดียวกัน
ดังนั้น symbol ที่ต้องการจะพูดถึงนี้ จึงเป็นเหมือน กับ Literal ทีี่่่่มีได้ค่าเดียว และแน่นอนเราไม่สามารถ assignค่าได้ โดยใน ruby เราจะประกาศดังนี้
:symbol //ก็คือค่า :symbol เหมือนกับเราประกาศ
3 //ผลลัพธ์ ก็คือ ค่า 3

ลองพิสูจน์ดูว่า m=:test
n=:test
m.object_id == n.object_id หรือเปล่า

วิธีดู object _id ของทั้งใน symbol table
Symbol.all_symbols

Range in Ruby
=>class Range
r= 4..8 //shold assign range in variable
r.to_a // [4 ,5,6,7,8]
r.each{|x| print x} //45678

a='4'..'8'
a.to_a // ["4","5","6","7"]
a.each{|x| print x} //45678

f=1.0..2.0
Float Array is not support methods each
f.each{|x| puts x}//error ,it is a infinity loop

t=4...8 //4567
t.include?(8) // no


Getting the Time & Date
=>class Time
Time.mktime(year,month,day)
s=Time.now
puts s.strftime("%A") //print full day

Doing math with Time and Date
now =Time.now
hbd=Time.mktime(1989,02,11) //my birth day
เนื่องจาก class Time มี method +-... เราสามารถใช้ในการ ความแตกต่้างของเวลา
ในหน่วยวินาทีได้ึคือ
diff=now-hbd // return Float that refer to seconds of difference time
diff+=1 // increase time in a second

Formating Date and Time
now=Time.now
now.strftime(string ) // string="your month:: %m" same as c-function

Array/Hashes
Array is holding a data in Ruby you can store a difference data
arr=[1,"hello",102.21]
arr จะเป็นตัวชี้ไปที่
memoryเริ่มต้นในการจองตัวแปรแบบ array

declaration
x=[]
x<<1> x=Array.new //[]
x=Array.new(3) // [nil],[nil],[nil]
x=Array.new(3,"hello") //["hello","hello","hello"]
x.capitalize! //["hello","hello","hello"] change All
x=Array.new(5){"hello"} //use block if you know you willm mo
x[0].
capitalize! //change x[0]
x=[1,"hello","123.45"]

access array
a[0]
a[1]
...
a[n]

methods
x.first
x.last
x.length
x.size

Sorting Array
in the same type data

in difference data
x=['1',5,'3',"2",4]
x.sort {|x,y| x.to_s<=>y.to_s }

Searching Array

find is Synomym of detect =>หาเจอตัวแรกเอาเลย
find_all is Synonym of select =>เอาหมดทุกตัวที่ตรงตามเงื่อนไข
grep(reg_expression) เช่น
reg_expression จับหลักจากการสังเกตได้ว่า

str=[]
str.methods.grep(//) => select all
str.methods.grep(/\bm/) => ขึ้นต้นด้วยตัวm
str.methods.grep(/p\b/) => ลงท้ายด้วย ตัว p
str.methods.grep(/test/) =>["test_1","test_2"]
str.methods.grep(/test/){|v| IO.const_get(v)}
str.min
str.max


num=Array.new
num.each{|x| p x} //iterating Trough an Array

num.each do |x|
if a==2
p "hello"
end
end
you can use
num.reverse_each{|v| p v}


array is a special type of Hash but Hash is not ordered หมายความว่า
เราไม่ทราบลำดับในการ get value เนื่องจากค่า keyไม่จำเป็นต้องเรียงลำดับ
Howto use key to get value
color=Hash.[](:white =>"#FFFFFF", :black=>"#000000")
color[:white] // "#FFFFFF"
color =Hash.[]("white =>"#FFFFFF", "black" =>"#000000")
color["black"] //"#000000"
color=Hash.[](0=>"#FFFFFF",1=>"#0000000")

OR

color=Hash.[](:white,"#FFFFFF", :black,"#000000")
color=Hash.new
color=Hash,new(10)
color.[]=(key,value)
color.delete(key) //delete key and value in Hash

color.each{|key,value| puts "#{key} : #{value}"}
color.each_key{|key| puts key}
color.each_value{|value| puts value}

Sorting in Hash
เมื่อเราทำการ sort Hash แล้ว จะได้ออกมาเป็น Array ของ2ค่าคือ key and value
เนื่องจากในการsort key หาก เราประกาศHash ที่มี Key เป็น symbol เราต้องแปลงมัน
เป็น string ก่อนแล้วจึงจะเปรียบเทียบ Key โดยใช้ block แล้วใช้ operator "<=>"ในการเปรียบเทียบ
ระหว่าง ตัวแรก กับตัวถัดไปซึ่งรับมาในรูปของ iterator variableเช่น
color=Hash.[](:red =>"#FF0000",:green=>"00FF00")
color.sort{|a,b| a<=>b} //a is key , b is next key
ถ้าหากkey เป็น string หรือ ที่ไ่ม่ใช่symbol ก็ sort เลยได้
new has=x.merge(color)
y=[1,2,3,4,5]
y_hash=Hash[*y]


Set is a semilar to an array but It's unordered

require 'set'
a=Set[1,2,3]
b=Set[3,4,5]
b.intersection a
b&a
b-a
a-b
********************
a.union b
a| b
a+b
*********************
a.subset? b
a.delete(element)
y=[1,2,3,4,5]
new_set=Set[y]

Stack and Queue
จะใช้ array ในการ implement แต่มีmethods ให้ใช้คือ
FOR STACK
x.push(1,2,3)
x<<4

Accessing Other Program on the system

system("nodepad.exe")
system("cmd /c dir")

Commandline Arguments
-------------------------------------
->use GetoptLong class
require 'getoptlong'
-parser=GettoptLong.new
parser.set_options(["-h","--help,GetoptLong::NO_ARGUMENT"]
,["-t",'--test',GetoptLong:: REQUIRED_ARGUMENT])
opt,arg=parser.get
puts arg
arg.to_i.times{|x| puts"Hello"}

ถ้ารับหลาย argument แนะนำ
n=ARGV.size
ARGV.each do|arg|
arg.to_i.time{|arg| puts arg}
end


Environment Variable for window
-> ENV (is a hash that content about environment Variable)

Network client
require 'net/http'
content =Net::HTTP.new("http://www.google.co.th",80)
respond,data=
content.get("/index.html",nil)
puts data //so data is a string
you can copy content in the web page in the file
File.open("test.html","w") do |file|
file.puts data
end

require 'resolv'
Resolv::DNS.each_address("www.google.co.th"){|x| puts x} //so you get a DNS server

reference resource ::http://www.ruby-doc.org/stdlib/

วันพุธที่ 5 พฤษภาคม พ.ศ. 2553

Basic::Ruby (part III)

FILE IN RUBY
use file open
-> hava a file class


filename= "test9.cpp"
File.open(filename) do |files|
while line= files.gets
puts line
end
end

files.gets => จะ return แต่ละบรรทัด มาให้

File.writable? filename
File.readable? filename
File.executable? filename
File.exist? filename
do not close file any where

def test2
yield 1
yield 2
end

test2 {|x| if x>0 then puts x else puts "error" end }
หรือ
test2 {|x| if x>0 ; puts x else puts "error" end }
test2 {|x| if x>0 : puts x else puts "error" end }
...
Easy way to read file

filename ="helloworld"
IO.foreach(filename){|line|puts line}
str=IO.read(filename) //read file into the string
puts str
arr=IO.readlines(filename) // read line of file into the Array

How to write a file
File.open(" ......... ","w") do |filecontent|
filecontent.puts "hello world"
end

Binary file vs Text file
Text File โดยทั่ว ๆ ไปโปรแกรมจะต้องมองเรื่องของการ encode/decode ไฟล์ในการ อ่านและเขียน การ encode/decode นี้ก็เช่นวิธีการเก็บไฟล์เป็น ภาษาไทย ภาษาจีน หรือ ภาษาอังกฤษ นั่นเอง ซึ่งแต่ละภาษาจะมีวิธีการเก็บที่แตกต่างกันเช่น ASCII, ISO, Unicode, JIF และอื่น ๆ

Binary File โดยทั่ว ๆ ไปจะหมายถึงการที่โปรแกรมมองเรื่องของการอ่านและเขียนไฟล์ในรูปแบบของ byte-to-byte หรือก็คืออ่านเป็น byte และเขียนเป็น byte โดยไม่สนใจการ encode/decode ต่าง ๆ เลยครับ
ruby ให้เราอ่าน textfile และแก้ไข text file ได้ ส่วน binary file สามารถอ่านได้แต่ จะต้องหาlibrary มาลงจึงจะสามารถ จัดการ กับ binary file ได้

Work with Directory
//use Dir class
Dir.mkdir(path) =>create directory in that path
Dir.pwd
Dir.entries(Dir.pwd)
Dir.entries('.')

FileUtils
-------------------------
require 'fileutils' //you can use file utility to use a Unix - Dos command
such as=> Fileutils.pwd()

Read and Write file(.csv) -> format for holding data

require 'csv'
CSV.open(filename,'w') do|data|
data <<['...','.....','......']
end
CSV.open(filename,'r') do |data|
p data
end
p is a shotcut of "puts"

Regular Expression is a string to match a particular thing that
you're searching for
such as str.gsub(/[a-z]/,"*") output=>


วันอังคารที่ 4 พฤษภาคม พ.ศ. 2553

Basic::Ruby (part II)

Basic Ruby (partII)

constant variable &scope

scope ->where variable has a value (::)
constant -> delare with a capital letter
initialize -> to do when instantiate happen

Expression
multiple expression in one line
a=1; b=2; c=3

command expansion
`date`
`ls`

Assignment

a=11;b=12;;c='e'
puts "a=#{a} b=#{b} c=#{c}" //in double quote แตุ่ถ้าเป็น single quote จะใช้ไม่ไ้ด้
output is a=11 b=12 c=e
parallel -> a=b=c
concatString +
puts 'a'+'b'
print ->print a line and no carriage return
puts ->prints out the carriage return


ri searchcontent ->ดูคำอธิบายการใช้ library







Expression Loop
while ...
end

9.times do |var| //mean start form 0 to 8
print "#{var}" // 9 is number of times
end

puts =>is the same output as Enter

1.upto(9) do |var| // 1 to 9
print "#{var}"
end

1.step(9,3) do |var| //start at 1 to 9 ,step is 3
print "#{var}"
end

Module ->a wayt to encapsulate a bunch of different code ซึ่งเป็น concept
ของ namespace
เนื่องจาก เรามี การประกาศmethod ไว้มากมายอาจซ้ำกันได้ในหลายๆไฟล์
ถ้าเรา ประกาส keyword module ไว้ก็จะทำให้ทราบว่า method นั้น เป็นของ Moduleไหน

module testA
def A.print_name
puts "hello"
end
end
module testB
def B.print_name
puts "hi"
end
end
การอ้างอิง TestA.print_name
TestB.print_name
Mix -ins with module
ก็คล้ายๆกับการประกาศและสร้างnamespace ให้กับ class ซึ่งก่อนอื่นเราจะสร้าง module
ของ method ที่เราต้องการจากนั้น นำไปใช้กับ class เพื่อ

Block

เป็น a bit of code ที่สามารถส่งไปให้กับ iterator เพื่อทำการ executeได้ เช่น
def time
yield
yield
end

time {puts"Hello"}

เมื่อมีการเรียกใช้ method time เมื่อ เจอ yield จะกลับไปexecute ที่ block {puts......} จากนั้นจะกลับมาทำต่อใน time ใหม่ ไปเรื่อยๆจนถึง end โดยเราสามารถส่งพารามิเตอร์ไปให้block ได้
เช่น

def time
yield 1
yield 2
end
time {|x| puts "hello #{x}"} หรือ time {|x| puts x}
หรือ สามารถใช้ อีก รูปแบบหนึ่งก็ได้
time do |x|
puts x
end

Basic Exception
def
func
begin
recue
ZeroDivisionError
.......................
end
end

Basic String::
str="It's a string " is the same as %q/This is a string/ can use #{a} replaced by variable
str='It's a string' is the same as %Q/ This is a string/ use#{a} is string
str.capitalize => the first one is a capital letter.



How to use string in long sentence
<<
END_OF_STROING
"---------------------------------"
END_OF_STROING

str =" hello "
str.downcase
str.upcase
//replace in new string
str.lstrip =>"hello "
str.rstrip => " hello"
str.strip =>"hello"
//use ! to replace in old string
example = > str.strip!

str.length
str.insert(5," world") // "hello world"

Manipulate in basic string
str="It is a book"
str.split
str.split(delimeter)
delimeter => ตัวคั่น โดยการ split จะทำการแ่บ่งตามคั่น
str.split(',',4 ) =>ทำการsplit strimg ออกตามdelimiter (',') ซึ่งแบ่งออกเป็น4 ส่วน
str.split(/ /) แบ่งตามจำนวน space bar
...เยอะมาก
ออกมาเป็นarray

str.slice(i..n)
str.index('h')
str.replace "word" //replace whole str and replace in the old string
str.gsub(pattern,replacement)
str.sub(pattern,replacement)
str.include? "string" => boolean
str.to_s
str.to_i
...





วันจันทร์ที่ 3 พฤษภาคม พ.ศ. 2553

Basic::Ruby (part I)

everything in Ruby is object

example 1 is an object

try 1.class // output is Fixnum

example "BENZ" is an object

try "BENZ".class

someObj.someMethod
someObj ->name of object that reference to the object
someMethod ->to message to another object


puts ->to print string on the screen
gets ->to get string in commandline

ปล. method "gets" รับ "\n"ด้วยดังนั้น เวลารับให้เราตัด "\n"ออก หากเราต้องการนำไปเปรียบเทียบ string ให้ทำดังนี้
str=gets.chomp


case number
when number value interval
-----------------------
when number value interval
-----------------------
end

assignment statement

a=b

Control flow construct

if boolean_test
-------------------------
else
------------------------
end

unless boolean_test

else

unless จะกลับกับ if ตรงที่ ถ้า boolean test ของ if เป็นจริง จะทำ statement ใน if แต่ถ้า เป็น unlessถ้า boolean test เป็นเท็จ จะทำ statement ใน unless เช่น
unless number >=5
puts "number is less than 5"
else
puts "number is greater than 5"
end
หรือ พูดอีกอย่างก็คือ ผลลัพธ์ที่นอกจาก number >=5 ให้ทำ ในstatement unless


boolean => true , false

Boolean Constructs
> ,< ,>=,<=, !=,== <=> หมา่ยถึงการเปรียบเทียบระหว่าง2value ถ้า ตัวหน้า.....ตัวหลัง (มากกว่า เป็น1 ,เท่ากันเป็น 0 ,น้อยกว่าเป็น -1)
เช่น
a=10
a<=>9 // output is 1
a<=>10 //output is 0
a<=>11 //output is -1

Boolean Operator
and ,&&
or , ||

Loop Block and iterator

while booleantest
statement
increament
end
while->ทำจนกว่าจะเป็นเท็จ


until booleantest
statement
increament
end

until->ทำจนกว่าจะเป็นจริง

for i in a .. n
statement
end

for ->to do somthing in interval value for loop


number.times {|i|
statement}

number ->
object of class fixnum
times ->
method of class but in this example doesn't have any thing to do
{ } the block that to be execute

Array in ruby
can contain difference type
เช่น
a=["benz",2,3,]
เข้าถึงโดย a[0]...a[n-1]
a.length
a.each{|var | puts var}

class and object in ruby

class
Test
def hello
puts
"Hello World"
end
end

create object
t=Test.new
Test.new ->create object that allocate memory and t points to that memory

InstanceVariable VS class Variable
InstanceVariable -> @ variable that associate with object
ClassVariable -> @@ variable that associate with class


setIvar(a)
getIvar ->
is nill if you instanciate but you don't set value for instance variable
setCvar(b)
getCvar ->
if you initialize class variable in class you can get value when you instantiate object

How to access Instance variable in ruby


attr_reader :avar
attr_reader ->
method call that expect a symbol
:avar ->
symbol ที่สอดคล้ิองกับตัวแปร instance ที่เราต้องการset ค่าของมัน

attr_accessor
:avar
you declare like this . you can access "avar "to set a value by use
instance.avar=value

attr_writer :avar
...

Flow Control

เนื่องจาก ใช้ ruby interpreter ดังนั้นเริ่มจาก ทำการ load "..." ก่อน หากเราวาง Statement ไว้ใน load ก่อน ก็จะทำตาม statement ไล่ลงมา แล้ว execute หากมีการประกาศclass ถ้าในclass นั้นมีการวาง statement ในส่วนของการประกาศ class variable ก็จะทำด้วย ส่วนใน การประกาศ method จะไม่ทำ จากนั้นก็ทำตามstepมาเรื่อยๆ

Duck Typing
เกิดจากการส่งพารามิเตอร์เข้าไปในmethodซึ่งพารามิเตอร์ที่ส่งไปดันใช้ methods ในmethodนั้น ได้ เช่นส่งString เข้าไปในmethod 2ตัวโดยใช้ operator "<<"เป็นการ append Stringใน ruby แต่หา่กพารามิเตอร์ที่ส่ง ไปนั้น เป็น array integer กับ integer ก็จะเป็นว่าเราทำการadd integer เข้าไปใน array integer ซึ่งใช้ method "<<" เหมือนกันไำด้ จึงมีคำกล่าวที่ว่า
"ถ้าเห็นนกที่เดินได้เหมือนเป็ด ว่ายน้ำได้เหมือนเป็ด
ร้องได้เหมือนเป็ด นกตัวนั้นเป็นเป็ด”
ยังไม่ค่อยเข้าใจความหมายซักเท่าไหร่วันไหนคิดได้จะมาอธิบายให้





interpreter vs compiler

intrepreted program -> เป็น โปรแกรมที่สามารถ execute ได้ line by line (หมายถึง one statement )
โดยจะถูกแปลงเป็นmachine code และ execute มันทันที ซึ่งเราสามารถเปลี่ยนมันได้ง่ายในขณะที่โปรแกรมกำลัง run อยู่ แต่จะมีข้อเสียคือ เสียเวลาในการโปรเซส เนื่องจากต้องมาคอยแปลงเป็น Matchine code ในแต่ละทุกๆบรรทัดแล้วทำงานทันที แทนที่จะอ่านมาทีเดียวแล้วค่อยจัดการทั้งโปรแกรม

compiled program -> จะเป็นโปรแกรมที่้compiler จะconvert มันเป็น machine code เพียง stepเดียว ซึ่งสุดท้ายแล้ว จะได้ obj code ซึ่งประกอบด้วย binary (0,1)ซึ่ง จะบอก microprocessor ว่าคำสั่งนี้หมายถึงอะำไร และมีการลิงค์ส่วนต่างเช่น วิธีในการแสดงผลทางหน้าจอ ว่าจะมีการเรียกprint อย่างไร

virtual machine ->เมื่อเราเขียนโปรแกรมเช่นjava ซึ่งเราเขียนแล้ว save เป็น.java จากนั้นเราใช้java compiler ทำงาน จะได้ java bytecode ซึ่งเป็น intermediate form ซึ่งจะสามารถรันได้ ใน interpreterที่เฉพาะ แล้วจึงค่อยรัน byte codeใน java interpreter ซึ่งจะมีการ optimize code ให้สามารถรันได้ใน ทุกๆmachine เนื่องจาก interpreterนั้นขึ้นกับ machine นั้น

MVC in Ruby On Rails

Ruby on rails เป็น framework ที่ใช้สำหรับสร้า่ง web application ซึ่งมีโครงสร้างแบบ MVCมาจาก
-Model -> โปรแกรมที่ทำหน้าที่คำนวณงานของ เว็บ app
-View -> โปรแกรมที่ทำหน้าที่ติดต่อสื่อสารกับผู้ใช้
-Controller ->โปรแกรมที่ควบคุมการทำงานระหว่าง model กับ view
โดยขั้นตอนการทำงานมีดังนี้คือ

เริ่มจาก client ส่ง request ไปที่ web app โดยส่งต่อมาที่ controller ก่อนหน้านั้นจะต้องถูก ActionPack(ActionView->module สร้า่ง view + ActionController->module สร้างcontroller)ตีความของ request path ที่ user ส่งเข้ามาแล้วทำการโยนไปให้ action ในcontroller ซึ่งส่วนใหญ่แล้ว action ใน controller จะเรียก ไปยัง Model ซึ่งมีไว้สำหรับการคำนวณหรือติดต่อไปยัง database query ข้อมูลออกมา เมื่อโมเดลทำเสร็จจะส่้งผลกลับมาที่controller แล้วทำการ render view template(เป็นรูปแบบของViewซึ่งเป็น code ruby ที่จะใช้สำหรับสร้าง view (html page)เพื่อส่งกลับมาให้user)

วันอาทิตย์ที่ 2 พฤษภาคม พ.ศ. 2553

animation maya: แบบที่1

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

1.มาที่keyframe ที่ 1 แล้วทำการเคลื่อนที่โมเดล ณ จุดๆหนึ่ง แล้วจัดท่าของโมเดล ในท่าหนึ่ง เมื่อได้ที่แล้วกด ปุ่ม s เพื่อ ยืนยันว่า ณ frameที่1 เราให้มันเป็นแบบนี้

2.มาที่ key frame ที่ 3 แล้วทำการเคลื่อนที่โมเดล ณ จุดอีกจุดหนึ่ง แล้วจัดท่าโมเดลอีกแบบหนึ่งดังรูป แล้วกด ปุ่ม s เพื่อยืนยัน
ดังรูป

ปล.สิ่งที่สำคัญที่สุดคือการ save เนื่องจาก เราสร้าง bone ขึ้นมา ซึ่งเป็น boneนั้นมันมีหลายส่วนนั่นหมายความว่า หาเรา คลิ๊กเลือก bone ส่วนหัว แล้วทำการ save คือการบันทึกการเปลี่ยนแปลงเฉพาะ bone ส่วนนั้น ส่วน bone ส่้วนอื่นก็ต้องsave เหมือนกัน แต่สุดท้ายแล้วเมื่อมีการเล่น animationทุกอย่างก็จะเคลื่อนที่ตามเวลาที่กำหนด