28
Ruby 使用手冊 Part 1 Compass Study Group Jian-Long Huang 2016.05.03

Ruby 使用手冊 (Part 1)

Embed Size (px)

Citation preview

Ruby 使用手冊Part 1

Compass Study Group

Jian-Long Huang

2016.05.03

甚麼是 Ruby?• 直譯式腳本語言 (interpreted scripting language):

能夠直接產生作業系統呼叫

強大的字串處理 (string operations) 及正規表示式 (regular expressions)

在開發時提供即時回饋

• 快捷易用:

不需要變數宣告 (variable declarations)

變數不需要型別 (typed)

語法簡單一致

自動管理記憶體

2

甚麼是 Ruby?• 物件導向程式設計:

任何東西都是物件

類別、方法、繼承等

單件方法 (singleton methods)

模組提供「混入」(mixin) 功能

迭代器 (iterators) 及閉包 (closures)

• 以及:

多精確度整數 (multiple precision integers)

方便的例外處理 (exception processing)

動態載入 (dynamic loading)

執行緒支援 (threading support)

3

起步走• 顯示 Ruby 版本

• 執行 Ruby 命令

• 執行 Ruby 檔

$ ruby –vruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]

$ ruby -e 'puts "hello world"'hello world

$ echo "puts 'hello world'" > hello.rb$ ruby hello.rbhello world

4

安裝 Ruby• Windows

RubyInstaller for Windows

• Linux (Ubuntu)

• Linux (CentOS)

• Mac OS X

• 更多參考 https://www.ruby-lang.org/zh_tw/documentation/installation/

$ sudo apt-get install ruby

$ sudo yum install ruby

$ brew install ruby

5

簡單示範• 計算階乘

# 計算出數字的階乘# 請把程式儲存為 fact.rb

def fact(n)if n == 01

elsen * fact(n-1)

endend

puts fact(ARGV[0].to_i)

6

簡單示範• ARGV: 命令列引數

• to_i: 將字元字串 (character string) 轉換為整數

• 不加 return,回傳值即為最後一個 statement 的傳回值。

7

互動模式• 執行 ruby而未輸入引數,Ruby 會從標準輸入 (standard input) 讀取指令,在輸入結束後 (送出 Ctrl-D 指令) 開始執行。

• 輸入 irb 指令,可以進入互動模式。

8

字串 (String)• 使用雙引號或單引號括起

• 雙引號可以使用字串內插 (string interpolation)

• 雙引號可以使用反斜線轉義字符

a = "foo"a = 'bar'

a = "foo"b = "#{a}bar" # ==> "foobar"

a = "foo\n" # ==> 輸出 foo + 換行符號

9

字串 (String)• 串接字串

• 重複字串

• 提取字串

a = "foo" + "bar" # ==> "foobar"

a = "foo" * 2 # ==> "foofoo"

a = "parsley"a[0] # ==> "p"a[-1] # ==> "y"a[0,1] # ==> "p"a[-2,2] # ==> "ey"a[0..3] # ==> "pars"a[0...3] # ==> "par"a[-5..-2] # ==> "rsle"

10

字串 (String)• 字串比對

"foo" == "foo" # ==> true"foo" == "bar" # ==> false

11

正規表示式• 和 Perl 一樣,Ruby 使用 string =~ /<pattern>

發現符合,傳回字串中符合之位置

沒有符合,傳回 nil

• 更多參考 http://ruby-doc.org/core-2.1.1/Regexp.html

# 抓出手機號碼phone = "123-456-7890"if phone =~ /(\d{3})-(\d{3})-(\d{4})/ext = $1city = $2num = $3

end

12

陣列 (Array)• 使用中括號 ([]) 建立陣列,元素可不同型態

• 陣列串接

• 陣列重複

• 使用 join 轉成字串

• 字串使用 split 轉成陣列

ary = [1, 2, "3"]

ary + ["foo", "bar"] # ==> [1, 2, "3", "foo", "bar"]

ary * 2 # ==> [1, 2, "3", 1, 2, "3"]

ary.join(":") # ==> "1:2:3"

"1:2:3".split(":") # ==> ["1", "2", "3"]

13

雜湊 (Hash)• 使用大括號 ({}) 建立雜湊,key 和 value 可為不同型態

h = {1 => 2, "2" => "4"} # ==> {1=>2, "2"=>"4"}

# 使用 symbol 當作 key,有兩種寫法h = {:foo => 1, :bar => 2}h = {foo: 1, bar: 2}

14

字串符號 (Symbol)• 一個 Symbol 物件皆為冒號開頭,例如 :foo 或 :foo_bar。它的作用就是代表一個名字,最大的作用就是當做 Hash 的鍵 (key)。例如 { :foo => 1, :bar => 2 },在這裡我們只需要一個識別的名字,不需要使用字串物件。

• 使用 Symbol 寫法更簡潔和獲得效能上的好處。

• 更多參考 http://kaochenlong.com/2016/04/25/string-and-symbol/

15

Percent Literals (Percent Strings)• http://bearsu.logdown.com/posts/304719-ruby-percent-literals

16

Ruby 是完全物件導向• 在 Ruby,每樣東西都是物件,使用 if、while 等條件判斷時,空字串、空陣列、空雜湊都視為 true。

17

繼續簡單示範• 猜字程式

01 words = ['foobar', 'baz', 'quux']02 secret = words[rand(3)]0304 print "guess?"05 while guess = STDIN.gets06 guess.chop!07 if guess == secret08 puts "You win!"09 break10 else11 puts "Sorry, you lose."12 end13 print "guess?"14 end15 puts "the word is "+ secret + " . "

18

繼續簡單示範• rand(3): 隨機傳回 0, 1, 2 其中一個數值

• STDIN.gets或 gets:收集使用者輸入的一行內容,直到使用者輸入 Ctrl-D

• chop: 刪除字串的最後一個字元並回傳結果

• chop!: 同 chop,但會永久改變物件本身

19

繼續簡單示範• 正規表示式

01 st = "\033[7m"02 en = "\033[m"0304 puts "Enter an empty string at any time to exit."0506 while true07 print "str> "; STDOUT.flush; str=gets.chop08 break if str.empty?09 print "pat> "; STDOUT.flush; pat=gets.chop10 break if pat.empty?11 re = Regexp.new(pat)12 puts str.gsub(re, "#{st}\\&#{en}")13 end

20

繼續簡單示範• empty?: 在定義方法的時候名稱可以是任何符號,一般來說結尾加上 ? 表示只會傳回 Boolean 值,是 Ruby 的慣例。

• gsub: globally substitute 的縮寫,將匹配的內容取代成另外一個字串。

\&: 上個匹配的對象 (last match)

21

控制結構• case

i=8case iwhen 1, 2..5puts "1..5"

when 6..10puts "6..10"

when 'aaa', 'bbb'puts "aaa or bbb"

when /def/ # 正規表示式puts "includes /def/"

end

22

控制結構• while

i = 0while i < 3puts i += 1

end

# 可以簡寫成puts i += 1 while i < 3

23

控制結構• if

i = 0if i == 0puts "It's zero."

end

# 可以簡寫成puts "It's zero" if i == 0

24

控制結構• unless: if 的否定型

• until: while 的否定型

• 何時用 if,何時用 unless?

一般來說,儘量使用正向表達,少用 ! 符號

# Goodputs "It's nil" if foo.nil?puts "It's not nil" unless foo.nil?

# Not goodputs "It's not nil" if !foo.nil?

25

控制結構• 中斷迴圈

break: 中斷所有迴圈

next: 中斷目前迴圈,從下個迴圈開始

redo: 重新執行目前迴圈

return: 中斷迴圈並跳出迴圈所在的方法

• for

for num in (4..6)puts num

end

for elt in [100, -9.6, "pickle"]puts elt

end

26

控制結構• for 的另一種寫法

# 如果你習慣用 C 或 Java,你可能會比較喜歡這個。for element in collection...

end

# Smalltalk 程式員則可能喜歡這個。collection.each { |element|...

}

collection.each do |element|...

end

27

迭代器 (Iterator)• 字串常用的迭代器

each_byte: 取出每個字元

each_line: 取出每一行

• 定義迭代器:

在 function 使用 yield ,該 function 就變成迭代器。

yield 可將控制移至傳遞往迭代器的程式碼區塊 (block of code)。

def repeat(num)while num > 0yieldnum -= 1

endend

repeat(3) { puts "foo" }

28