0
<ul>RUBY 程式語言 入門導覽 </ul><ul>[email_address]   <li>2010.05.23@ OSSF </li></ul>
<ul>Who am I? </ul><ul><ul><li>鄧慕凡, Ryudo </li></ul></ul><ul><ul><ul><li>http://blog.freebbs.tw
twitter: ryudoawaru </li></ul></ul></ul><ul><ul><li>從 2007 年初開始使用 Ruby(Rails)
TOMLAN Software Studio founder </li></ul></ul><ul><ul><ul><li>http://www.freebbs.tw
http://www.gameclub.tw </li></ul></ul></ul>
講義 <ul><li>http://ryudo.freebbs.tw/ </li></ul>
<ul>什麼是  Ruby? </ul><ul><ul><li>開放原碼、物件導向的直譯式   (interpreted) 腳本 (script) 程式語言
簡單哲學、高生產力
精巧、自然的語法
創造者  Yukihiro Matsumoto </li></ul></ul><ul><ul><ul><li>靈感來自  Lisp, Perl,  和  Smalltalk
減少編程時候的不必要的瑣碎時間,令編寫程序的人高興 </li></ul></ul></ul>
<ul>irb: Interactive Ruby     馬上動手練習 </ul><ul>開啟終端機: ryudo@ryudo-x61:~$ irb irb(main):001:0> 1+3 => 4 irb(main):002:0> 'he...
<ul>IRB(Interactive Ruby Shell) </ul><ul><ul><li>互動式交談 </li></ul></ul><ul><ul><ul><li>每次指令的結果都會在下一行輸出 </li></ul></ul></ul>...
<ul>Ruby  是直譯式強型別語言 </ul><ul><ul><li>直譯式語言 </li></ul></ul><ul><ul><ul><li>Ruby/PHP/Perl/Python/VB </li></ul></ul></ul><ul>...
<ul>Ruby 是強型別 (Strongly typed) 語言 </ul><ul>irb(main): 003 : 0 > i= 1   =>  1   irb(main): 004 : 0 >  'hello'  + i  </ul><u...
<ul>整數  Integer </ul><ul>10 5 10000 9999999999999999999999 0 -100000 </ul>
<ul>浮點數  Float </ul><ul>1.1 -100.28 3.14159 </ul>
輸出 <ul><li>PUTS </li><ul><li>輸出結果值的.to_s,然後換行 </li></ul><li>P </li><ul><li>輸出結果值的.inspect,然後換行
通常拿來debug </li></ul></ul>
輸入 <ul><li>gets </li><ul><li>得到按下enter前的內容
內容是字串
後接.chomp避免把換行也加進來 </li></ul></ul>
<ul>整數四則運算 ( 結果整數 ) </ul>1 + 1   #= 2 200 * 3   #= 600  10 - 999   #= -989  100 / 20   #= 5  100 / 30   #= 3
<ul>浮點數四則運算 ( 結果 Float) </ul><ul>irb(main): 001 : 0 >  5  *  2.0  =>  10.0  irb(main): 002 : 0 >  2.0  +  100.2  =>  102.2...
<ul>更多運算 </ul><ul>puts  5  * ( 10  +  5 ) - 13   <li>puts  999  + ( 31456  / ( 13  *  7 ) ) *  -70 </li></ul>
<ul>字串  String </ul><ul>puts  'Hello, world!'   <li>puts  ''  puts  'Good-bye.'
puts  ' 馬上就會好 ' </li></ul>
Try it out!
字串的建構 <ul><li>'abc'單引號 </li><ul><li>裡面可包含&quot; </li></ul><li>&quot;def&quot;雙引號 </li><ul><li>可內插變數
可內插控制字元(
	等..) </li></ul></ul>
<ul>字串可 + 不可 - </ul><ul>irb(main): 008 : 0 >  'abc'  +  'def'   <li>=>  &quot;abcdef&quot;
irb(main): 010 : 0 >  'abc' .concat( 'def' )
=>  &quot;abcdef&quot;
irb(main): 009 : 0 >  'abc'  -  'def'
NoMethodError : undefined method `-' for &quot;abc&quot;:String </li></ul>
<ul>更多字串函式 </ul><ul>var1 =  'stop'   <li>var2 =  'foobar'
var3 =  &quot;aAbBcC&quot;
var4 =  '  那很好哇  '
puts var1.reverse  #  反轉
puts var2.length  #  長度
puts var3.upcase  # 轉大寫
puts var3.downcase  # 轉小寫
puts var4.strip  # 左右去空白 </li></ul>
格式化字串 <ul><li>sprintf(輸出變數)
printf(輸出畫面)
風格類似C的同名函式
%s字串, %d整數, %f浮點數.. </li></ul>
格式化字串 i1 =  123 f1 =  456.789 printf( ' 我有  %d  元 ' , i1)  # 我有  123  元 printf( '%0.5d' , i1)  #00123 printf( '%3.5f' , f1...
練習1 <ul><li>輸出詢問名稱和年紀的訊息,再於畫面中show出對話 </li></ul>
練習1 puts  'Hello there, and what ' s your name?' name = gets.chomp puts  'Your name is '  + name +  '? What a nice name!' ...
執行 <ul><li>ruby xx.rb </li></ul>
<ul>完全物件導向的語言    包括字串和數字都是物件,無內建型別 </ul><ul>irb(main): 001 : 0 >  'abc123' .upcase  <li>=>  &quot;ABC123&quot;
irb(main): 002 : 0 >  'abc123' .class
=>  String
irb(main): 003 : 0 >  'abc123'  ==  String .new( 'abc123' )
=>  true
irb(main): 004 : 0 >  5 .times{puts  ' 你累了嗎 ?' }
你累了嗎 ?
你累了嗎 ?
你累了嗎 ?
你累了嗎 ?
你累了嗎 ?
=>  5 </li></ul>
<ul>( 區域 ) 變數  Variable 必需是小寫英文字開頭 </ul>a =  100 b =  10.5 a * b  #= 1050.0 c =  'SO' d =  'GO' c+d  #= &quot;SOGO&quot;
全域變數 <ul><li>以$開頭的變數 </li></ul>
字串內插變數 i1 =  123 puts  &quot;Iam#{i1}&quot;   #&quot;Iam123&quot;
<ul>型別轉換  Conversions </ul>var1 =  '2' var2 =  4 var3 =  4.5 var1.to_i * var2  #= 8  var1.to_f * var3  #= 9.0  var3.to_s +...
<ul>常數  Constant     大寫開頭 </ul><ul>irb(main): 001 : 0 > foo =  1   <li>=>  1
irb(main): 002 : 0 > foo =  2
=>  2
irb(main): 003 : 0 >  Foo  =  1
=>  1
irb(main): 004 : 0 >  Foo  =  2
(irb): 4 : warning: already initialized constant  Foo
=>  2     # 雖然警告但其實 OK
irb(main): 005 : 0 >  RUBY_PLATFORM
=>  &quot;i686-linux&quot;
irb(main): 006 : 0 >  ENV     # 會噴出一堆環境變數 </li></ul>
Nil 空值  <ul><li>表示為空
不等於false/0/空字串('') </li></ul>irb(main): 001 : 0 >  nil =>  nil irb(main): 002 : 0 >  nil  ==  false =>  false irb(main): 0...
註解 # <ul><li>以#開頭之後為註解 </li></ul>
陣列 Array http://ruby-doc.org/core-1.8.7/classes/String.html [ 1 , 2 , 3 , 4 ]  [ 1 , 'abc' , false ,[ nil , nil ]]  # 多維陣列...
索引操作 <ul><li>[n] 取得第n個
[n..m] 取得第n至m個
[n...m] 取得n至m-1個
[n,len]取得n開始的len個 </li></ul>
索引操作 arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] p arr[ 2 .. 3 ]  #[3, 4] p arr[ 2 ... 4 ]  #[3, 4] p arr[ 2 , 2 ]  #[3, 4]
陣列相加 [ 1 , 2 , 3 ] + [ 4 , 5 , 6 ]  # [1, 2, 3, 4, 5, 6] [ 1 , 2 , 3 ].concat [ 4 , 5 , 6 ]  # [1, 2, 3, 4, 5, 6]
更多陣列函式(1) ossf=[ 'whoswho' , 'openfoundry' , 'org' ] ossf <<  'tw' # [&quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;...
更多陣列函式 ossf.pop  # 返回從後面取出的值 ,  但陣列本身已被改變 #= [&quot;www2&quot;, &quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;org&qu...
字串陣列共通的方法 <ul><li>操作索引 </li><ul><li>[n]、[m..m]、[n,len]等 </li></ul><li>Enumerable類方法 </li><ul><li>each、map等 </li></ul><li>連...
取得字串的字元碼 'Abcde123HG' .bytes.to_a => [ 65 ,  98 ,  99 ,  100 ,  101 ,  49 ,  50 ,  51 ,  72 ,  71 ] 'Abcde123HG' [ 1 ] => ...
雜湊 Hash h = { :abc  =>  123 ,  'def'  =>  456 } #= {&quot;def&quot;=>456, :abc=>123} h[ :abc ] #= 123 h[ 'def' ] #= 456
字串符號 Symbols <ul><li>不會變動的唯一辨識符 </li></ul>h2 = {  :abc  =>  123 ,  'abc'  =>  456 } #= {&quot;abc&quot;=>456, :abc=>123} :...
PUTS/P 範例 irb(main): 011 : 0 > h = { :abc  =>  123 } => { :abc => 123 } irb(main): 012 : 0 > p h { :abc => 123 } irb(main)...
流程控制 <ul><li>大於  >
小於  <
大於等於  >=
等於  ==
不等於  !=
AND &&
OR ||
NOT ! </li></ul>
結構控制 <ul><li>If … end
Unless … end
Case when end </li></ul>
if puts  &quot; 請輸入你的月薪 &quot; your_money = gets.to_i if  your_money >=  100000 puts  &quot; 哩金好野 &quot; elsif  your_money...
unless <ul><li>除了沒有elsif外都跟if一樣,只是條件相反 </li></ul>
CASE aaa = [ 1  , 'abc' ,  1.3 ] p aaa printf( ' 你要確認哪一個 ?' ) idx = gets.to_i case  aaa[idx] when   String puts  &quot; 這是...
三元運算子 EXPRESSION ? (True Condition):(False Condition) a =  10 ; b =  100 a > b ? ( &quot;#{a} > #{b}&quot; ):( &quot;#{a} ...
迴圈 10 .times  do   puts  ' 那很好啊 ' end for  i  in   1 .. 10 puts i end x =  100 while  x >  10 x = x -  10 puts x end x =  ...
真或假 <ul><li>只有nil 和 false為假,其它為真
所以空字串和0也是真 </li></ul>
練習2 : 猜數字 <ul><li>亂數產生一個數字 </li><ul><li>rand(20)會產生0~20間的隨機數字
避免0 </li></ul><li>輸入一個數字
猜對了就跳出
猜錯了就顯示猜錯了 </li><ul><li>差10顯示差很大
10比內顯示接近了 </li></ul></ul>
練習2 : 猜數字 randnum =  0 loop  do randnum = rand( 20 ) break   if  randnum >  0 end 5 .times  do print  ' 請輸入一個數字 :' num = g...
正規表示式 phone =  &quot;002-2882-5252&quot; if  phone =~  /( d +) - ( d +) - ( d +)/ area =  $1 first =  $2 second =  $3 end ...
Method 方法 依接收者分為三大類 <ul><li>實體方法(Instance Method)
類別方法(Class Method)
函式性的方法 </li></ul>
<ul><li>實體方法 (Instance Method) </li></ul><ul><li>屬於某個類別new出來的「物件實體」之方法
接收者(self)為物件實體 </li></ul>'abcdef' .reverse  #=> &quot;fedcba&quot;
<ul><li>類別方法(Class Method) </li></ul><ul><li>類別本身的方法
接收者(self)為類別
建立物件的.new即為類別方法 </li></ul>irb(main): 009 : 0 > a =  Date .today =>  #<Date: 4910677/2,0,2299161> irb(main): 010 : 0 > puts...
<ul><li>函式性的方法 </li></ul><ul><li>沒有接收者也能執行的方法
其實並非沒有接收者,只是被省略的情形 </li></ul>sprintf( &quot;%d %04x&quot; ,  123 ,  123 )  #=> &quot;123 007b
定義函式 <ul><li>Def 函式名稱..end
以return返回值
如無設定return,以最後一個運算式的結果為return </li></ul>def   hello (name) sprintf( ' 哈囉  %s' , name) end
定義函式之參數 <ul><li>def( 參數 ..)
可設定預設值,表示可省略
可省略者「必需」在不可省略者之前 </li></ul>def   showmanytimes (text2show, times =  10 )  #=> OK! times.times{puts text2show} end def   sh...
? 與 ! 的慣例 <ul><li>函式定義以?結尾者 </li><ul><li>表示回傳值為boolean </li></ul><li>函式定義以!結尾者 </li><ul><li>表示會改變接收者本身 </li></ul></ul>irb(...
類別 (Class) 與實體 (Instance) <ul><li>類別 -> 模子
實體 -> 模子印出來的
Ruby的萬物皆類別! </li></ul>' 我愛 OSSF' .class =>  String
定義類別 class   Duck def   initialize (name) @name  = name end def   quack  # 實體方法 &quot;#{ @name } is quacking!&quot; end en...
定義類別 class  Car @@amount =  0 def   initialize (name) @name   = name @@amount +=  1 end def   name= (val) @name   = val en...
類別定義內也可以執行程式 class   Car @@amount =  0 def   initialize (name) @name  = name @@amount +=  1 end attr_accessor  :name def  ...
建立物件變數的存取函式 <ul><li>attr_accessor </li><ul><li>等於下面兩者相加 </li></ul><li>attr_writer </li><ul><li>只有寫入 代替def xxx=(val) end </...
Public/Protected/Private <ul><li>Public </li><ul><li>預設值,無限制呼叫對象 </li></ul><li>Protected </li><ul><li>繼承者可以呼叫,外部禁止,但同類別(含子...
私有/保護 定義方式 class   Abc def   pub ... end def   priv ... end def   prot ... end private  :priv public  :pub protected  :pro...
類別之繼承 <ul><li>萬物皆繼承Object這個類別的子類
被繼承者為父類別(superclass)
繼承者為子類別(subclass) </li></ul>
繼承類別 class  Vehicle attr_accessor  :tires end class   Tire attr_accessor  :size end class   Car  <  Vehicle def   initiali...
Upcoming SlideShare
Loading in...5
×

Ruby程式語言入門導覽

5,854

Published on

http://whoswho.openfoundry.org/workshop/details/88--ruby.html
的簡報

Published in: Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,854
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
98
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Ruby程式語言入門導覽"

  1. 1. <ul>RUBY 程式語言 入門導覽 </ul><ul>[email_address] <li>2010.05.23@ OSSF </li></ul>
  2. 2. <ul>Who am I? </ul><ul><ul><li>鄧慕凡, Ryudo </li></ul></ul><ul><ul><ul><li>http://blog.freebbs.tw
  3. 3. twitter: ryudoawaru </li></ul></ul></ul><ul><ul><li>從 2007 年初開始使用 Ruby(Rails)
  4. 4. TOMLAN Software Studio founder </li></ul></ul><ul><ul><ul><li>http://www.freebbs.tw
  5. 5. http://www.gameclub.tw </li></ul></ul></ul>
  6. 6. 講義 <ul><li>http://ryudo.freebbs.tw/ </li></ul>
  7. 7. <ul>什麼是 Ruby? </ul><ul><ul><li>開放原碼、物件導向的直譯式   (interpreted) 腳本 (script) 程式語言
  8. 8. 簡單哲學、高生產力
  9. 9. 精巧、自然的語法
  10. 10. 創造者 Yukihiro Matsumoto </li></ul></ul><ul><ul><ul><li>靈感來自 Lisp, Perl, 和 Smalltalk
  11. 11. 減少編程時候的不必要的瑣碎時間,令編寫程序的人高興 </li></ul></ul></ul>
  12. 12. <ul>irb: Interactive Ruby    馬上動手練習 </ul><ul>開啟終端機: ryudo@ryudo-x61:~$ irb irb(main):001:0> 1+3 => 4 irb(main):002:0> 'hello' + ' world' => &quot;hello world&quot; </ul>
  13. 13. <ul>IRB(Interactive Ruby Shell) </ul><ul><ul><li>互動式交談 </li></ul></ul><ul><ul><ul><li>每次指令的結果都會在下一行輸出 </li></ul></ul></ul><ul><ul><li>簡單測試的最佳工具 </li></ul></ul>
  14. 14. <ul>Ruby 是直譯式強型別語言 </ul><ul><ul><li>直譯式語言 </li></ul></ul><ul><ul><ul><li>Ruby/PHP/Perl/Python/VB </li></ul></ul></ul><ul><ul><li>編譯式語言 </li></ul></ul><ul><ul><ul><li>Java/C/C++ </li></ul></ul></ul><ul><ul><li>強型別 </li></ul></ul><ul><ul><ul><li>Ruby/JAVA </li></ul></ul></ul><ul><ul><li>弱型別 </li></ul></ul><ul><ul><ul><li>PHP </li></ul></ul></ul>
  15. 15. <ul>Ruby 是強型別 (Strongly typed) 語言 </ul><ul>irb(main): 003 : 0 > i= 1   => 1   irb(main): 004 : 0 > 'hello' + i  </ul><ul>TypeError : can 't convert Fixnum into String from (irb):4:in `+' from (irb): 4 </ul>
  16. 16. <ul>整數 Integer </ul><ul>10 5 10000 9999999999999999999999 0 -100000 </ul>
  17. 17. <ul>浮點數 Float </ul><ul>1.1 -100.28 3.14159 </ul>
  18. 18. 輸出 <ul><li>PUTS </li><ul><li>輸出結果值的.to_s,然後換行 </li></ul><li>P </li><ul><li>輸出結果值的.inspect,然後換行
  19. 19. 通常拿來debug </li></ul></ul>
  20. 20. 輸入 <ul><li>gets </li><ul><li>得到按下enter前的內容
  21. 21. 內容是字串
  22. 22. 後接.chomp避免把換行也加進來 </li></ul></ul>
  23. 23. <ul>整數四則運算 ( 結果整數 ) </ul>1 + 1 #= 2 200 * 3 #= 600 10 - 999 #= -989 100 / 20 #= 5 100 / 30 #= 3
  24. 24. <ul>浮點數四則運算 ( 結果 Float) </ul><ul>irb(main): 001 : 0 > 5 * 2.0 => 10.0 irb(main): 002 : 0 > 2.0 + 100.2 => 102.2 irb(main): 003 : 0 > 2.2 * 5.5 => 12.1 irb(main): 004 : 0 > 100.0 / 4.0 => 25.0 irb(main): 008 : 0 > 9.0 / 2.0 => 4.5 </ul>
  25. 25. <ul>更多運算 </ul><ul>puts 5 * ( 10 + 5 ) - 13 <li>puts 999 + ( 31456 / ( 13 * 7 ) ) * -70 </li></ul>
  26. 26. <ul>字串 String </ul><ul>puts 'Hello, world!' <li>puts '' puts 'Good-bye.'
  27. 27. puts ' 馬上就會好 ' </li></ul>
  28. 28. Try it out!
  29. 29. 字串的建構 <ul><li>'abc'單引號 </li><ul><li>裡面可包含&quot; </li></ul><li>&quot;def&quot;雙引號 </li><ul><li>可內插變數
  30. 30. 可內插控制字元( 等..) </li></ul></ul>
  31. 31. <ul>字串可 + 不可 - </ul><ul>irb(main): 008 : 0 > 'abc' + 'def' <li>=> &quot;abcdef&quot;
  32. 32. irb(main): 010 : 0 > 'abc' .concat( 'def' )
  33. 33. => &quot;abcdef&quot;
  34. 34. irb(main): 009 : 0 > 'abc' - 'def'
  35. 35. NoMethodError : undefined method `-' for &quot;abc&quot;:String </li></ul>
  36. 36. <ul>更多字串函式 </ul><ul>var1 = 'stop' <li>var2 = 'foobar'
  37. 37. var3 = &quot;aAbBcC&quot;
  38. 38. var4 = ' 那很好哇 '
  39. 39. puts var1.reverse # 反轉
  40. 40. puts var2.length # 長度
  41. 41. puts var3.upcase # 轉大寫
  42. 42. puts var3.downcase # 轉小寫
  43. 43. puts var4.strip # 左右去空白 </li></ul>
  44. 44. 格式化字串 <ul><li>sprintf(輸出變數)
  45. 45. printf(輸出畫面)
  46. 46. 風格類似C的同名函式
  47. 47. %s字串, %d整數, %f浮點數.. </li></ul>
  48. 48. 格式化字串 i1 = 123 f1 = 456.789 printf( ' 我有 %d 元 ' , i1) # 我有 123 元 printf( '%0.5d' , i1) #00123 printf( '%3.5f' , f1) #456.78900
  49. 49. 練習1 <ul><li>輸出詢問名稱和年紀的訊息,再於畫面中show出對話 </li></ul>
  50. 50. 練習1 puts 'Hello there, and what ' s your name?' name = gets.chomp puts 'Your name is ' + name + '? What a nice name!' puts 'Pleased to meet you, ' + name + '. :)'
  51. 51. 執行 <ul><li>ruby xx.rb </li></ul>
  52. 52. <ul>完全物件導向的語言    包括字串和數字都是物件,無內建型別 </ul><ul>irb(main): 001 : 0 > 'abc123' .upcase <li>=> &quot;ABC123&quot;
  53. 53. irb(main): 002 : 0 > 'abc123' .class
  54. 54. => String
  55. 55. irb(main): 003 : 0 > 'abc123' == String .new( 'abc123' )
  56. 56. => true
  57. 57. irb(main): 004 : 0 > 5 .times{puts ' 你累了嗎 ?' }
  58. 58. 你累了嗎 ?
  59. 59. 你累了嗎 ?
  60. 60. 你累了嗎 ?
  61. 61. 你累了嗎 ?
  62. 62. 你累了嗎 ?
  63. 63. => 5 </li></ul>
  64. 64. <ul>( 區域 ) 變數 Variable 必需是小寫英文字開頭 </ul>a = 100 b = 10.5 a * b #= 1050.0 c = 'SO' d = 'GO' c+d #= &quot;SOGO&quot;
  65. 65. 全域變數 <ul><li>以$開頭的變數 </li></ul>
  66. 66. 字串內插變數 i1 = 123 puts &quot;Iam#{i1}&quot; #&quot;Iam123&quot;
  67. 67. <ul>型別轉換 Conversions </ul>var1 = '2' var2 = 4 var3 = 4.5 var1.to_i * var2 #= 8 var1.to_f * var3 #= 9.0 var3.to_s + var1 #= 注意是字串
  68. 68. <ul>常數 Constant    大寫開頭 </ul><ul>irb(main): 001 : 0 > foo = 1 <li>=> 1
  69. 69. irb(main): 002 : 0 > foo = 2
  70. 70. => 2
  71. 71. irb(main): 003 : 0 > Foo = 1
  72. 72. => 1
  73. 73. irb(main): 004 : 0 > Foo = 2
  74. 74. (irb): 4 : warning: already initialized constant Foo
  75. 75. => 2     # 雖然警告但其實 OK
  76. 76. irb(main): 005 : 0 > RUBY_PLATFORM
  77. 77. => &quot;i686-linux&quot;
  78. 78. irb(main): 006 : 0 > ENV     # 會噴出一堆環境變數 </li></ul>
  79. 79. Nil 空值 <ul><li>表示為空
  80. 80. 不等於false/0/空字串('') </li></ul>irb(main): 001 : 0 > nil => nil irb(main): 002 : 0 > nil == false => false irb(main): 003 : 0 > nil == '' => false
  81. 81. 註解 # <ul><li>以#開頭之後為註解 </li></ul>
  82. 82. 陣列 Array http://ruby-doc.org/core-1.8.7/classes/String.html [ 1 , 2 , 3 , 4 ] [ 1 , 'abc' , false ,[ nil , nil ]] # 多維陣列 [ 1 , 2 , 3 , 4 ].reverse # [4, 3, 2, 1] [ 1 , 'abc' , false ,[ nil , nil ]].size # 4 [ 1 , 'abc' , false ,[ nil , nil ]].flatten # [1, &quot;abc&quot;, false, nil, nil]
  83. 83. 索引操作 <ul><li>[n] 取得第n個
  84. 84. [n..m] 取得第n至m個
  85. 85. [n...m] 取得n至m-1個
  86. 86. [n,len]取得n開始的len個 </li></ul>
  87. 87. 索引操作 arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] p arr[ 2 .. 3 ] #[3, 4] p arr[ 2 ... 4 ] #[3, 4] p arr[ 2 , 2 ] #[3, 4]
  88. 88. 陣列相加 [ 1 , 2 , 3 ] + [ 4 , 5 , 6 ] # [1, 2, 3, 4, 5, 6] [ 1 , 2 , 3 ].concat [ 4 , 5 , 6 ] # [1, 2, 3, 4, 5, 6]
  89. 89. 更多陣列函式(1) ossf=[ 'whoswho' , 'openfoundry' , 'org' ] ossf << 'tw' # [&quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;org&quot;, &quot;tw&quot;] ossf.push 'www2' # [&quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;org&quot;, &quot;tw&quot;, &quot;www2&quot;] ossf.unshift 'www2' # [&quot;www2&quot;, &quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;org&quot;, &quot;tw&quot;, &quot;www2&quot;
  90. 90. 更多陣列函式 ossf.pop # 返回從後面取出的值 , 但陣列本身已被改變 #= [&quot;www2&quot;, &quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;org&quot;, &quot;tw&quot;] ossf.shift ## 返回從前面取出的值 , 但陣列本身已被改變 #= [&quot;whoswho&quot;, &quot;openfoundry&quot;, &quot;org&quot;, &quot;tw&quot;]
  91. 91. 字串陣列共通的方法 <ul><li>操作索引 </li><ul><li>[n]、[m..m]、[n,len]等 </li></ul><li>Enumerable類方法 </li><ul><li>each、map等 </li></ul><li>連接、逆轉相關方法 </li><ul><li>reverse、concat、delete </li></ul></ul>
  92. 92. 取得字串的字元碼 'Abcde123HG' .bytes.to_a => [ 65 , 98 , 99 , 100 , 101 , 49 , 50 , 51 , 72 , 71 ] 'Abcde123HG' [ 1 ] => 98
  93. 93. 雜湊 Hash h = { :abc => 123 , 'def' => 456 } #= {&quot;def&quot;=>456, :abc=>123} h[ :abc ] #= 123 h[ 'def' ] #= 456
  94. 94. 字串符號 Symbols <ul><li>不會變動的唯一辨識符 </li></ul>h2 = { :abc => 123 , 'abc' => 456 } #= {&quot;abc&quot;=>456, :abc=>123} :abc .object_id #= 263138 # 不論宣告幾次都是一樣的實體 'abc' .object_id #= 84140440 'abc' .object_id #= 84137350 # 字串重複宣告後就不一樣實體
  95. 95. PUTS/P 範例 irb(main): 011 : 0 > h = { :abc => 123 } => { :abc => 123 } irb(main): 012 : 0 > p h { :abc => 123 } irb(main): 013 : 0 > puts h abc123 irb(main): 014 : 0 > puts :ossf ossf irb(main): 015 : 0 > p :ossf :ossf
  96. 96. 流程控制 <ul><li>大於 >
  97. 97. 小於 <
  98. 98. 大於等於 >=
  99. 99. 等於 ==
  100. 100. 不等於 !=
  101. 101. AND &&
  102. 102. OR ||
  103. 103. NOT ! </li></ul>
  104. 104. 結構控制 <ul><li>If … end
  105. 105. Unless … end
  106. 106. Case when end </li></ul>
  107. 107. if puts &quot; 請輸入你的月薪 &quot; your_money = gets.to_i if your_money >= 100000 puts &quot; 哩金好野 &quot; elsif your_money >= 22000 puts &quot; 還好比 22K 多 &quot; else puts ' 唉 ' end
  108. 108. unless <ul><li>除了沒有elsif外都跟if一樣,只是條件相反 </li></ul>
  109. 109. CASE aaa = [ 1 , 'abc' , 1.3 ] p aaa printf( ' 你要確認哪一個 ?' ) idx = gets.to_i case aaa[idx] when String puts &quot; 這是一個字串 &quot; when Integer puts &quot; 這是一個整數 &quot; when Float puts &quot; 這是一個浮點數 &quot; when Numeric puts ' 這是一個數字 ' else puts &quot; 這是其它類型的物件 &quot; end
  110. 110. 三元運算子 EXPRESSION ? (True Condition):(False Condition) a = 10 ; b = 100 a > b ? ( &quot;#{a} > #{b}&quot; ):( &quot;#{a} < #{b}&quot; ) #=> &quot;10 < 100&quot;
  111. 111. 迴圈 10 .times do puts ' 那很好啊 ' end for i in 1 .. 10 puts i end x = 100 while x > 10 x = x - 10 puts x end x = 100 until x <= 10 x = x – 10 next if x == 50 # 跳過下一步繼續 puts x end abc = [ 1 , 2 , 3 ] loop do abc.pop p abc break if abc.empty? # 跳出 end
  112. 112. 真或假 <ul><li>只有nil 和 false為假,其它為真
  113. 113. 所以空字串和0也是真 </li></ul>
  114. 114. 練習2 : 猜數字 <ul><li>亂數產生一個數字 </li><ul><li>rand(20)會產生0~20間的隨機數字
  115. 115. 避免0 </li></ul><li>輸入一個數字
  116. 116. 猜對了就跳出
  117. 117. 猜錯了就顯示猜錯了 </li><ul><li>差10顯示差很大
  118. 118. 10比內顯示接近了 </li></ul></ul>
  119. 119. 練習2 : 猜數字 randnum = 0 loop do randnum = rand( 20 ) break if randnum > 0 end 5 .times do print ' 請輸入一個數字 :' num = gets.chomp.to_i if num == randnum puts ' 猜對了 ~YEAH!' break end if num - randnum >= 10 puts &quot; 猜的大很多 &quot; elsif (num - randnum) < 10 && (num - randnum) >= 1 puts ' 猜的大一點 ' elsif randnum - num >= 10 puts ' 猜的小很多 ' else puts ' 猜的小一點 ' end end
  120. 120. 正規表示式 phone = &quot;002-2882-5252&quot; if phone =~ /( d +) - ( d +) - ( d +)/ area = $1 first = $2 second = $3 end p [area, first, second]
  121. 121. Method 方法 依接收者分為三大類 <ul><li>實體方法(Instance Method)
  122. 122. 類別方法(Class Method)
  123. 123. 函式性的方法 </li></ul>
  124. 124. <ul><li>實體方法 (Instance Method) </li></ul><ul><li>屬於某個類別new出來的「物件實體」之方法
  125. 125. 接收者(self)為物件實體 </li></ul>'abcdef' .reverse #=> &quot;fedcba&quot;
  126. 126. <ul><li>類別方法(Class Method) </li></ul><ul><li>類別本身的方法
  127. 127. 接收者(self)為類別
  128. 128. 建立物件的.new即為類別方法 </li></ul>irb(main): 009 : 0 > a = Date .today => #<Date: 4910677/2,0,2299161> irb(main): 010 : 0 > puts a 2010 - 05 - 22
  129. 129. <ul><li>函式性的方法 </li></ul><ul><li>沒有接收者也能執行的方法
  130. 130. 其實並非沒有接收者,只是被省略的情形 </li></ul>sprintf( &quot;%d %04x&quot; , 123 , 123 ) #=> &quot;123 007b
  131. 131. 定義函式 <ul><li>Def 函式名稱..end
  132. 132. 以return返回值
  133. 133. 如無設定return,以最後一個運算式的結果為return </li></ul>def hello (name) sprintf( ' 哈囉 %s' , name) end
  134. 134. 定義函式之參數 <ul><li>def( 參數 ..)
  135. 135. 可設定預設值,表示可省略
  136. 136. 可省略者「必需」在不可省略者之前 </li></ul>def showmanytimes (text2show, times = 10 ) #=> OK! times.times{puts text2show} end def showmanytimes (times = 10 , text2show) # => 錯誤 times.times{puts text2show} end
  137. 137. ? 與 ! 的慣例 <ul><li>函式定義以?結尾者 </li><ul><li>表示回傳值為boolean </li></ul><li>函式定義以!結尾者 </li><ul><li>表示會改變接收者本身 </li></ul></ul>irb(main): 001 : 0 > [ 1 , 2 , 3 , 4 ].empty? => false irb(main): 002 : 0 > [ 1 , 2 , 3 , 4 ,[ 5 , 6 ]].flatten => [ 1 , 2 , 3 , 4 , 5 , 6 ]
  138. 138. 類別 (Class) 與實體 (Instance) <ul><li>類別 -> 模子
  139. 139. 實體 -> 模子印出來的
  140. 140. Ruby的萬物皆類別! </li></ul>' 我愛 OSSF' .class => String
  141. 141. 定義類別 class Duck def initialize (name) @name = name end def quack # 實體方法 &quot;#{ @name } is quacking!&quot; end end d = Duck .new( ' 唐老鴨 !' ) puts d.quack # 唐老鴨 ! is quacking! 建構式 ! 物件實體變數
  142. 142. 定義類別 class Car @@amount = 0 def initialize (name) @name = name @@amount += 1 end def name= (val) @name = val end def name @name end def self . amount @@amount end end c1 = Car .new( ' 霹靂車 ' ); c2 = Car .new( ' 火戰車 ' ) c3 = Car .new( 'Focus' ); c3.name = 'Focus ST' puts &quot; 現在有 &quot; + Car .amount.to_s + &quot; 台車了 &quot; 物件類別變數 實體方法
  143. 143. 類別定義內也可以執行程式 class Car @@amount = 0 def initialize (name) @name = name @@amount += 1 end attr_accessor :name def self . amount @@amount end end class Car @@amount = 0 def initialize (name) @name = name @@amount += 1 end def name= (val) @name = val end def name @name end def self . amount @@amount end end =
  144. 144. 建立物件變數的存取函式 <ul><li>attr_accessor </li><ul><li>等於下面兩者相加 </li></ul><li>attr_writer </li><ul><li>只有寫入 代替def xxx=(val) end </li></ul><li>attr_reader </li><ul><li>只有讀取 代替 def xxx end </li></ul></ul>
  145. 145. Public/Protected/Private <ul><li>Public </li><ul><li>預設值,無限制呼叫對象 </li></ul><li>Protected </li><ul><li>繼承者可以呼叫,外部禁止,但同類別(含子類別)的其它實體可以呼叫 </li></ul><li>Private </li><ul><li>繼承者可以呼叫,外部禁止同類別(含子類別)的其它實體 不可以 呼叫 </li></ul></ul>
  146. 146. 私有/保護 定義方式 class Abc def pub ... end def priv ... end def prot ... end private :priv public :pub protected :prot end class Abc public def pub ... end private def priv ... end protected def prot ... end end =
  147. 147. 類別之繼承 <ul><li>萬物皆繼承Object這個類別的子類
  148. 148. 被繼承者為父類別(superclass)
  149. 149. 繼承者為子類別(subclass) </li></ul>
  150. 150. 繼承類別 class Vehicle attr_accessor :tires end class Tire attr_accessor :size end class Car < Vehicle def initialize (name) @tires = [] 4 .times{ @tires << Tire .new} end end class Motorcycle < Vehicle def initialize (name) @tires = [] 2 .times{ @tires << Tire .new} end end
  151. 151. 探索繼承類別 c = Car .new( 'Mondeo 2.0' ) puts c.is_a?( Vehicle ) #true puts c.class.superclass #Vehicle
  152. 152. 走訪迴圈 langs = [ 'VB' , 'C#' , 'C' , 'JavaScript' ] langs.each do |lang| puts &quot; 我會 #{lang}&quot; end 輸出: # 我會 VB # 我會 C# # 我會 C # 我會 JavaScript
  153. 153. 迭代器 iterator <ul><li>不同於for或while,迭代器是一種走訪接收者(通常是陣列或陣列的子類)元素的「方法」
  154. 154. do..end是迭代器方法的參數,可以將其代換為{},此類參數通稱為「code block」,也稱作匿名函式 </li></ul>
  155. 155. Code Block <ul><li>Ruby主要特色之一
  156. 156. 由於是一種匿名函式,故可接收參數
  157. 157. 習慣Ruby的人不會常用for/while,會使用iterator和code block </li></ul>
  158. 158. Code block 10 .times{|x| puts x} # 輸出 0 到 9 ( 1 .. 9 ).each{|x| puts x} #1 到 9 ( 1 ... 9 ).each{|x| puts x} #1 到 8 arr3 = [ 'ggg' , 123 , Time .now] arr3.each_with_index{|x, i| puts &quot; 第 #{i+1} 個元素的類別是 :#{x.class.to_s}&quot; } # 第 1 個元素的類別是 :String # 第 2 個元素的類別是 :Fixnum # 第 3 個元素的類別是 :Time
  159. 159. 進階Code Block arr = [ 1 , 2 , 3 , 4 , 5 , 6 ] #=> [1, 2, 3, 4, 5, 6] arr.map{|a| a+ 10 } #=> 造出新陣列 [11, 12, 13, 14, 15, 16] arr.select{|a| a > 3 } #=> 只挑選大於 3 者 [4, 5, 6] arr.reject{|a| a> 3 } #=> 和 select 相反 [ 4 , 5 , 1 , 2 , 3 ].sort{|a, b| a <=> b} #=> 基本排序
  160. 160. 進階Code Block arr1 = [ 'abc' , 'whoswho.openfoundry.org' , 'OSSF' ] arr1.sort_by{|w| w.length} # 用字數排序 #=> [&quot;abc&quot;, &quot;OSSF&quot;, &quot;whoswho.openfoundry.org&quot;] arr2 = [ 5 , 10 , 15 , 20 , 25 ] arr2.inject{|sum, x| sum += x } # 計算總合 => 75
  161. 161. Code Block應用 # 一般檔案操作寫法 fc = open( 'abc.html' , 'w' ) fc.puts( '<html>' ) ..... fc.puts( '</html>' ) fc.close # 關閉檔案指標 # 使用 Code Block open( 'abc.html' , 'w' ) do |fc| fc.puts( '<html>' ) ..... fc.puts( '</html>' ) end # 無需呼叫 close
  162. 162. 練習3 <ul><li>建立一個有多個字串的陣列
  163. 163. 將每個元素變大寫再反轉後結合在一起
  164. 164. 使用code block/inject </li></ul>
  165. 165. 練習3 def my_str_arr_processer (arr) return arr.inject( '' ){|s, a| s.concat(a.upcase.reverse)} end p my_str_arr_processer([ 'ab' , 'c' , 'g88' ])
  166. 166. 練習4擴充字串 <ul><li>擴充String類別
  167. 167. 加入find_capital_letters方法 </li><ul><li>尋找出大寫字母回傳
  168. 168. 大寫字母的範圍:65~90
  169. 169. 使用each_char方法尋遍全字串,或是bytes.to_a </li></ul></ul>
  170. 170. 練習4 class String def find_capital_letters s2r = '' self .each_char{|c| cc = c[ 0 ].to_i s2r.concat(c) if cc >= 65 && cc <= 90 } return s2r end end puts 'SUSE Linux' .find_capital_letters
  171. 171. Yield and Method 在函式中使用 yield 來執行 code block def test_block puts &quot;I love Ruby ,&quot; yield end test_block{ puts 'Ruby loves programmers!' } # 顯示 I love Ruby , Ruby loves programmers!
  172. 172. Yield and Method 在函式中使用 yield 來執行 code block def to_div (times) buffer = '<DIV>' times.times{|x| yield (buffer, x)} buffer.concat '</DIV>' end divhtml = to_div( 3 ) do |buf, x| buf.concat &quot;<p>No.#{x+1}</p>&quot; end puts divhtml # <DIV><p>No.1</p><p>No.2</p><p>No.3</p></DIV>
  173. 173. Proc object 將 code block 明確轉成物件 def test_block (&block) # 注意 & printf &quot;I love Ruby ,&quot; block.call end def to_div (times, &block) # 注意 & buffer = '<DIV>' times.times{|x| block.call(buffer, x)} buffer.concat '</DIV>' end blk1 = Proc .new{ puts( 'Ruby loves programmers!' )} blk2 = lambda{|buf, x| buf.concat &quot;<p>No.#{x+1}</p>&quot; } test_block(&blk1) puts to_div( 3 ,&blk2) 傳參數以及方法宣告皆需要加 & 來明確告知
  174. 174. 傳遞不定參數 <ul><li>Def xxx(*args)
  175. 175. 在方法內被視為陣列 </li></ul>def abc(*args) buf = '' args.each{|x| buf.concat yield (x)} return buf end abc( 'I' , 'LOVE' , 'OSSF' ) do |inner_text| &quot;<p>#{inner_text}</p><BR/>&quot; end # 輸出 #<p>I</p><BR/><p>LOVE</p><BR/><p>OSSF</p>
  176. 176. 參數尾 Hash 可省略 { } def tag_with_html (tag_name, inner_text, html_options) buf = &quot;<#{tag_name}&quot; html_options.each do |opt, val| buf.concat(sprintf( ' %s=&quot;%s&quot; ' , opt.to_s, val.to_s)) end buf.concat &quot;>#{inner_text}</#{tag_name}>&quot; return buf end puts tag_with_html( 'td' , 'Ruby Programming' , :bglocor => 'Red' , :width => 100 ) #<td width=&quot;100&quot; bglocor=&quot;Red&quot; >Ruby Programming</td> puts tag_with_html( 'td' , 'Ruby Programming' , { :bglocor => 'Red' , :width => 100 }) # 結果相同
  177. 177. 例外 Exception begin ..... rescue StandardError => ex #ex 為例外物件 p ex # 秀出 error 的詳細 ensure ..... # 無論如何都要執行的內容 end
  178. 178. 例外 Exception <ul><li>rescue後若有接例外類別名稱,代表只處理該例外類別的例外,不指定則處理一切例外
  179. 179. 「$!」為最後發生例外物件,「$@」為發生錯誤的行號等資訊 </li></ul>
  180. 180. Module <ul><li>只有方法部份的集合體
  181. 181. 無實體
  182. 182. 用途: </li><ul><li>類似單例(Singleton)類別
  183. 183. 命名空間(Name Space)
  184. 184. Mix in </li></ul></ul>
  185. 185. Module for Singleton Class module HtmlHelper HTML_ESCAPE = { '&' => '&amp;' , '>' => '&gt;' , '<' => '&lt;' , '&quot;' => '&quot;' } def self . h (s) s.to_s.gsub( /[&&quot;><]/ ){ |special| HTML_ESCAPE [special] } end end puts HtmlHelper .h( '<img src=&quot;abc.gif&quot;/> 我是圖片 ' ) #&lt;img src=&quot;abc.gif&quot;/&gt; 我是圖片
  186. 186. Module for Namespace module Forum class Member # 類別全名為 Forum::Member .... end class Topic #Forum::Topic end end
  187. 187. Module for Mix-in 多重繼承之實現 module ShareMod def subject ... end end class Forum include ShareMod end class SubForum include ShareMod end #Foum 和 SubForum 都會有 subject 的 instance method 間接實現了 多重繼承
  188. 188. 動態型別 (duck typing) 不管黑貓白貓,會抓老鼠的都是好貓 class PersianCat def find_mice # 抓老鼠 end end class RussianBlueCat def find_mice # 抓老鼠 end end
  189. 189. 動態型別 (duck typing) 不論出身正確 ( 參數型別 ) ,只論達成目標 ( 方法 ) def fetch_and_reverse (arr, idx) return arr[idx].reverse if arr[idx] && arr[idx].respond_to?( :reverse ) end aa = [ 'abc' , 'RyudoAwaru' , 'Linux' ] ha = { 0 => 'abc' , 1 => 'Ubuntu' } hb = { :first => 'RedHat' , :second => 'Suse' } p fetch_and_reverse(aa, 1 ) #&quot;urawAoduyR&quot; p fetch_and_reverse(ha, 0 ) #&quot;urawAoduyR&quot; p fetch_and_reverse(hb, :second ) #&quot;esuS&quot; 只要 arr 能響應 [] 和 :reverse 這兩個方法即能達成目標
  190. 190. Metaprogramming 用程式寫程式
  191. 191. define_method class Movie def initialize (id, name) @id = id @name = name end QualityNames = [ :fullhd , :hd , :sd ] # 定義 fullhd_movie_file, hd_movie_file, sd_movie_file # 三個方法 QualityNames .each do |qt| define_method &quot;#{qt.to_s}_movie_file&quot; .to_sym do return &quot;/movies/#{qt.to_s}/#{ @id }.mp4&quot; end end end a = Movie .new( 123 , ' 阿凡達 ' ) puts a.hd_movie_file #/movies/hd/123.mp4
  192. 192. Domain-Specific Language 領域特定語言 Class MyApp < Sinatra :: Base get '/books/*.*' do # matches /books/ruby-guide.html end get '/rooms/:id/index.html' do # matches '/rooms/123/index.html end end HTTP 動詞對應網址樣式, 即可做 WEB 伺服器的處理
  193. 193. Method Missing class Wheel attr_accessor :radius def initialize (radius) @radius = radius end end class Car attr_accessor :wheels def initialize @wheels = [] 4 .times{ @wheels << Wheel .new( 30 )} end def method_missing (mname, *args) if mname.to_s =~ /wheel ( d )/ return @wheels [ $1 .to_i] end end end my_car = Car .new p my_car.wheel_1 #<Wheel:0x8f6dea4 @radius=30> Car 並不預設 wheel_1 執行 method_missing
  194. 194. 物件方法查詢 object.methods # 列舉該物件的所有方法列表 object.private_methods # 列舉該物件的所有方法列表 object.protected_methods # 列舉該物件的所有方法列表 object.public_methods # 列舉該物件的所有方法列表 object.respond_to?( :method_name ) # 列舉是否支援某方法
  195. 195. 練習5 <ul><li>建立TextFileSearcher類別 </li><ul><li>建構式:傳入檔名
  196. 196. 方法:search_word </li><ul><li>輸入一個單字
  197. 197. 一次讀取一行內容(gets)
  198. 198. 如果該單字出現就show出這行,並顯示單字出現次數
  199. 199. 檔案可去http://www.ruby-lang.org/en/about/
  200. 200. 可用String#scan方法 </li></ul></ul></ul>
  201. 201. String#scan <ul><li>將找到的字串集合化為陣列
  202. 202. 可接受字串或正規表示式 </li></ul>$KCODE = 'u' stra = <<&quot;ABC&quot; 為紓解緊鄰中科的大肚山花園公墓,每逢清明節必塞車的窘境,台中市政府今年向男塾求援,希望他們能提供停車場成為公車轉運站。 「這怎麼可以,我們自己的客人也要停車呀」、「一天可湧入幾千位顧客耶,又是假日,客人一定會抱怨的啦」……員工七嘴八舌地回絕市政府的要求。不過董事長江田島平八卻二話不說,一口答應,員工一片譁然。 「捨三天生意,卻可以換來未來二十年的生意,這麼好的事情一定要做!」對無法理解的員工,江田島平八說,一旦停車場開放為接駁站,必定帶來龐大廣告效益,他的遠見說服了員工。 ABC p stra.scan ' 江田島平八 '
  203. 203. 練習5 class TextFileSearcher def initialize (fn) @file_path = fn end def search_word (word) open( @file_path , 'r' ) do |fc| while line = fc.gets line.downcase! ar = line.scan(word.to_s) unless ar.empty? puts &quot;#{line} meets #{word} #{ar.size} times.&quot; end end end end end tt = TextFileSearcher .new( 'r.txt' ) tt.search_word( 'ruby' )
  204. 204. RubyGems <ul><li>類似php的pear
  205. 205. 指令 gem </li><ul><li>List 列出現有的gem
  206. 206. Install gemname 安裝
  207. 207. Update gemname 升級
  208. 208. Uninstall gemname 移除 </li></ul></ul>
  209. 209. Sinatra Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort: http://www.sinatrarb.com
  210. 210. 安裝 <ul><li>Sudo gem1.8 install sinatra </li></ul>
  211. 211. Sinatra基本特性 <ul><li>A WEB Framework base on Rack.
  212. 212. DSL化的URL
  213. 213. 簡單、快速 </li></ul>
  214. 214. 第一隻 web app 執行 ruby myapp.rb, 然後打開瀏覽器 http://localhost:4567 # myapp.rb require 'rubygems' require 'sinatra' get '/' do 'Hello world!' end
  215. 215. URL參數傳遞 get '/rooms/:id/index.html' do # matches '/rooms/123/index.html?width=500&height=300' params[ :id ] # => 123 params[ :width ] # => 500 params[ :height ] # => 300 end
  216. 216. URL參數傳遞 *.* 變成 splash get '/books/*.*' do # matches /books/ruby-guide.html params[ &quot;splat&quot; ] # => [&quot;ruby-guide&quot;, &quot;html&quot;] end
  217. 217. ERB Template <ul><li>Code Block的最返回erb 樣板名稱
  218. 218. 樣板名稱必需是symbol
  219. 219. 樣板檔名是erb結尾
  220. 220. 在views目錄下 </li></ul>Class MyApp < Sinatra :: Base get '/' do @page_title = &quot; 輸入程式碼 !!&quot; erb :index # 用 index.erb 輸出 , layout.erb 做 layout end end
  221. 221. 使用 template 建立 views 目錄 , 加入 index.erb 檔案 # myapp.rb require 'rubygems' require 'sinatra' get '/' do erb :index end
  222. 222. 練習:index.erb <!DOCTYPE html> <html> <head> <title> Sinatra app </title> </head> <body> <% 10 .times do %> <p> <%= &quot;Hello #{params[ :name ]}!&quot; %> </p> <% end %> </body> </html>
  223. 223. ERB語法 <ul><li><%%>間為執行程式
  224. 224. <%=%>間除執行程式外,會把結果直接layout在頁面上
  225. 225. <%=erb :abc, :layout => false, :locals => {:post => @post}%> 可以在裡面render其它的erb </li></ul>
  226. 226. LAYOUT file <ul><li>樣板間共用的部份
  227. 227. HTML的上下文
  228. 228. 預設layout.erb
  229. 229. erb命令時可用:layout => :layout 做設定 </li></ul>
  230. 230. LAYOUT file <!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;> <html dir = &quot;ltr&quot; xmlns = &quot;http://www.w3.org/1999/xhtml&quot; > <head> <title> <%= @page_title %> </title> <meta http-equiv = &quot;Content-Type&quot; content = &quot;text/html; charset=utf-8&quot; /> </head> <body> <%= yield %> #yield 代表 erb 要 render 的部份 </body> </html>
  231. 231. 傳遞變數到 Template get '/array' do @arr = [ &quot;aaa&quot; , &quot;bbb&quot; , &quot;ccc&quot; , &quot;ddd&quot; ] erb :array end <% @arr .each do |item| %> <p> <%= item %> </p> <% end %>
  232. 232. POST FORM get '/' do erb :index end post '/query' do params[ :keyword ] end <form action = &quot;/query&quot; method = &quot;post&quot; > <p><input type = &quot;text&quot; name = &quot;keyword&quot; value = &quot;&quot; ></p> <p><input type = &quot;submit&quot; value = &quot;Submit&quot; ></p> </form>
  233. 233. 練習6 將強調字詞粗體化 <ul><li>去http://zonble.net/etc/bw.php製造廢文
  234. 234. 生出表單,欄位是廢文內容以及要強調的字眼,例如「我的名字」部份
  235. 235. 處理後將文章要強調的部份用<b>框起來 </li></ul>
  236. 236. String#gsub <ul><li>將符合第一個參數的字取代為第二個參數的字
  237. 237. 可配合正規表示式接收BLOCK做樣式匹配更改內容 </li></ul>'abc123def123GGG' .gsub( '123' , '456' ) => &quot;abc456def456GGG&quot;
  238. 238. 練習6 #t6.rb require 'rubygems' require 'sinatra' get '/' do erb :index end post '/' do @text = params[ :text2parse ].gsub(params[ :word ], &quot;<b>#{params[ :word ]}</b>&quot; ) erb :post end
  239. 239. 練習6 #index.erb <form action = &quot;/&quot; method = &quot;post&quot; > <input type = &quot;text&quot; name = &quot;word&quot; value = &quot;&quot; /><br/> <textarea name = &quot;text2parse&quot; cols = &quot;100&quot; rows = &quot;20&quot; ></textarea><br/> <input type = &quot;submit&quot; value = &quot; 送出 &quot; /> </form> #post.erb <p> <%= @text %> </p>
  240. 240. ActiveRecord入門
  241. 241. 什麼是 ORM ? <ul><li>ORM: Object-Relational Mapping
  242. 242. 將資料庫表格 (table) 對應到類別 (classe) </li><ul><li>提供類別方法對表格操作 </li></ul><li>將資料庫列 (row) 對應到 物件 (object) </li><ul><li>提供物件方法對個別的資料做操作 </li></ul><li>將資料庫欄位 (column) 對應到物件屬性 (object attribute) </li></ul>
  243. 243. 開始操作 - 建立留言板 DB 借用 rails <ul><li>rails MyPost
  244. 244. cd MyPost
  245. 245. script/generate model Post </li></ul>
  246. 246. 建立DB 編輯 db/migrate 下的第一個 .rb class CreatePosts < ActiveRecord :: Migration def self . up create_table :posts do |t| t.string :author t.string :subject t.text :message t.timestamps end end def self . down drop_table :posts end end
  247. 247. 建立DB <ul><li>rake db:migrate
  248. 248. Post DB建立完成 </li></ul>
  249. 249. Console <ul><li>script/console
  250. 250. 進階版的IRB
  251. 251. 會把rails的環境load進來 </li></ul>
  252. 252. CRUD 操作 post = Post.new <ul><li>Class method </li><ul><li>Post.find #找id
  253. 253. Post.create #新建並SAVE
  254. 254. Post.new #建立不立刻SAVE </li></ul><li>Instance method </li><ul><li>post.save
  255. 255. post.update_attributes #更新屬性並馬上存檔
  256. 256. post.destroy </li></ul></ul>
  257. 257. CRUD 操作 post = Post.new p = Post .new( :author => 'OSSF' , :subject => ' 今天有 RUBY 課程 ' , :message => ' 那很好哇 ~~~~' ) p.save p.id # 輸出 1 puts Post .count # 輸出 1 p1 = Post .find( 1 ) p1 = Post .find_by_author( 'OSSF' ) p1.subject # 輸出 今天有 RUBY 課程 p1.update_attributes( :author => ' 自己填 ' , :message => ' 好累喔 !!~~' ) p p1 p1.destroy puts Post .count
  258. 258. 練習:建立一些文章
  259. 259. DSL化的搜尋 <ul><li>find_by_attrname -> 依照屬性名找出第一筆對應
  260. 260. find_all_by_attrname -> 依照屬性名找出全部對應 </li></ul>
  261. 261. Model Validation 不正確的資料無法儲存 <ul><li>validates_presence_of </li><ul><li>必需存在 </li></ul><li>validates_length_of, :in, :minimum.. </li><ul><li>(字串)長度該多大 </li></ul><li>validates_numericality_of </li><ul><li>必需是數字 </li></ul><li>validates_uniqueness_of </li><ul><li>必需是唯一 </li></ul><li>validates_format_of </li><ul><li>符合正規表示式 </li></ul></ul>
  262. 262. 練習:加上validates <ul><li>限制所有屬性不得為空
  263. 263. 限制author的length必需大於3
  264. 264. 限制subject的長度必需介於5~30間 </li></ul>
  265. 265. rake-Ruby的make <ul><li>方便設定執行指令的相依性
  266. 266. 也DSL化 </li></ul>namespace :gameclub do desc &quot; 自動移除論壇的操作 &quot; task :daily_remove => :environment do Billboard .should_remove.each do |bbs| if bbs.destroy puts &quot; 成功刪除論壇 ID#{bbs.id}, #{bbs.full_url}&quot; else puts &quot; 刪除論壇 ID#{bbs.id}, #{bbs.full_url} 失敗 !&quot; end end end end rake gameclub:daily_remove
  267. 267. DB Migration? <ul><li>使用 Ruby 語法定義資料庫Schema
  268. 268. 讓資料庫的修改也可以版本控制
  269. 269. 跨資料庫通用(自訂指令除外) </li></ul>
  270. 270. Sinatra實作網頁留言板 <ul><li>建立views目錄
  271. 271. 建立app.rb檔
  272. 272. 將之前練習的views/layout.erb複製到這裡的views下 </li></ul>
  273. 273. 表象化狀態轉變 Representational State Transfer <ul><li>Roy Fielding 博士在2000年他的博士論文中提出來的一種軟體架構風格。
  274. 274. 相較於 SOAP、XML-RPC 更為簡潔容易使用
  275. 275. 諸Web Service 中最為普遍的 API 格式, Amazon、Yahoo!、Google API 等均有提供。 </li></ul>
  276. 276. 7 Actions URL VERB 用途 /posts get 列表 /posts post 建立新留言 /posts/:id get show完整留言 /posts/:id/edit get 進入編輯頁 /posts/:id put 提交修改 /posts/:id/delete get 刪除 /posts/new get 新增頁面
  277. 277. REST-STYLE URL PATTERN URL 行為 實體/類別 VERB /posts 無 類別 get /posts 無 類別 post /posts/:id 無 實體 get /posts/:id/edit edit 實體 get /posts/:id 無 實體 put /posts/:id/delete delete 實體 get /posts/new new 類別 get
  278. 278. 前置作業 <ul><li>建立DB(ORM)的連線
  279. 279. require必要的lib </li></ul>require 'rubygems' require 'sinatra' require 'active_record' $DBCONFIG = YAML ::load File .open( &quot;config/database.yml&quot; , 'r' ).read ActiveRecord :: Base .establish_connection $DBCONFIG [ &quot;development&quot; ] Dir .glob( 'app/models/*.rb' ).each{ |f| require f} get '/' do redirect '/posts' end
  280. 280. CONTROLLER get '/posts/new' do #new @post = Post .new erb :new end get '/posts' do #list @posts = Post .all erb :index end
  281. 281. CONTROLLER put '/posts/:id' do #update puts &quot; 到了 put #{params.inspect}&quot; @post = Post .find(params[ :id ].to_i) if @post .update_attributes( :author => params[ :author ], :subject => params[ :subject ], :message => params[ :message ]) p @post redirect &quot;/posts&quot; else erb :edit end end
  282. 282. CONTROLLER get '/posts/:id' do #show @post = Post .find(params[ :id ].to_i) erb :show end get '/posts/:id/delete' do #delete @post = Post .find(params[ :id ].to_i) @post .destroy redirect &quot;/posts&quot; end post '/posts' do #create puts &quot; 建文章 &quot; @post = Post .new( :author => params[ :author ], :subject => params[ :subject ], :message => params[ :message ]) if @post .save redirect &quot;/posts&quot; else erb :new end
  283. 283. Views #new.erb <%=erb '_post_err' .to_sym, :locals => { :post => @post }%> <form action = &quot;/posts&quot; method = &quot;post&quot; > <%=erb '_form' .to_sym%> </form> #edit.erb <%=erb '_post_err' .to_sym, :locals => { :post => @post }%> <form action = &quot;/posts/<%= @post .id%>&quot; method = &quot;post&quot; > <input name = &quot;_method&quot; type = &quot;hidden&quot; value = &quot;put&quot; /> <p><a href = &quot;/posts/<%= @post .id%>/edit&quot; > 修改 </a></p> <%=erb '_form' .to_sym%> </form>
  284. 284. VIEWS #_form.erb <table width = &quot;80%&quot; border = &quot;1&quot; > <tr> <td width = &quot;50&quot; align = &quot;right&quot; > 作者 </td> <td><input name = &quot;author&quot; type = &quot;text&quot; size = &quot;8&quot; value = &quot;<%= @post .author%>&quot; /></td> </tr> <tr> <td align = &quot;right&quot; > 標題 </td> <td><input name = &quot;subject&quot; type = &quot;text&quot; size = &quot;40&quot; value = &quot;<%= @post .subject%>&quot; /></td> </tr> <tr> <td align = &quot;right&quot; > 內文 </td> <td><textarea name = &quot;message&quot; cols = &quot;80&quot; rows = &quot;20&quot; > <%= @post .message%> </textarea></td> </tr> <tr> <td align = &quot;right&quot; > &nbsp; </td> <td><input type = &quot;submit&quot; value = &quot; 送出 &quot; /></td> </tr> </table>
  285. 285. VIEWS #_post_err.erb <% unless post.errors.blank?%> <ul> <%post.errors.each do |att,msg|%> <li> <%=att%> : <%=msg%> </li> <% end %> </ul> <% end %>
  286. 286. VIEWS #index.erb <p><a href = &quot;/posts/new&quot; > 新增 </a></p> <table border = &quot;1&quot; > <tr> <th> ID </th> <th> 刪 </th> <th> 作者 </th> <th> 標題 </th> </tr> <% @posts .each do |post|%> <tr> <td> <%=post.id%> </td> <td><a onclick = &quot;return confirm(' 確定要刪除嗎 ?')&quot; href = &quot;/posts/<%=post.id%>/delete&quot; > DEL </a></td> <td> <%=post.author%> </td> <td><a href = &quot;/posts/<%=post.id%>&quot; > <%=post.subject%> </a></td> </tr> <% end %> </table>
  287. 287. VIEWS #show.erb <p><a href = &quot;/posts/<%= @post .id%>/edit&quot; > 修改 </a></p> <table width = &quot;80%&quot; border = &quot;1&quot; > <tr><td width = &quot;50&quot; align = &quot;right&quot; > 作者 </td><td> <%= @post .author%> </td></tr> <tr><td align = &quot;right&quot; > 標題 </td><td> <%= @post .subject%> </td></tr> <tr><td align = &quot;right&quot; > 內文 </td><td> <%= @post .message%> </td></tr> </table>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×