每次都說要學 Ruby, 但是都沒有動力去學~ 買了 "Ruby Programming - 向Ruby之父學程式設計" 這本書, 也是一直沒看, 正好昨天剛從美國回來, 時差因素睡不著, 趁凌晨就花點時間把這本書看完, 順便做了一些筆記~(第 1~9 章的筆記, Module 部份暫時不寫, 尚未理解, 等測試後再另外補充)
相信程式有基礎的, 應該看看就懂了~ 🙂
感覺 Ruby 的程式寫起來, 蠻語意化的. 型態分別一律都是 Object, 所以要再注意一下.(PHP 一律都用 $, 在 Ruby 有分 $/@/@@ 等).
至於 Rails, 等 Ruby 再熟悉一點再碰, 不要還不會走路就想要跑~ 🙂
Ruby 的 彈性很大, 然後 Rails 就是綁死寫法(MVC). 我覺得 語言彈性大(也要夠簡單), Framework 綁死寫法, 這樣會比較容易被一般大眾接受.
ruby 要直接在 command line 執行的話, 會有亂碼的問題, 解法: ruby -Ku # u => UTF-8
Print/puts/p/pp
- print("hello world\n")
- puts("hello world")
- p "100" # 類同 print_r
- p 100
- print("sin(3.1415) = ", sin(3.1415), "\n")
- require "pp"; pp array # 格式排的比較好看的 p
前端頁面要秀出
- h()
Class type
- Numeric
- String
- Array
- Hash
- Regexp
- File
Variable
- 區域變數 小寫字母 或 _ 起頭的變數
- 全域變數 $ 起頭的變數
- 實體變數 @ 起頭的變數
- 類別變數 @@ 起頭的變數
- 虛擬變數 true / false / self
Ruby 習慣命名法
- variable: sort_list_by_name
- function name: sortListByName
Variable
- age = 18
- name = 'Jon'
- hello = 'Hello World,'
- hi = hello + name # Hello World,Jon
Comment
- =begin
- comment
- =end
- # comment
Array
- name = []
- name = ["abc", "def", "ghi", "jkl"]
- print "first name", name[0], "\n" # abc
- p name[1] # def
- p name # ["abc", "def", "ghi", "jkl"]
- name.size # 4
- %w: 元素是字串且不含空白
- lang = %w(Ruby Perl Python)
- p lang # ["Ruby", "Perl", "Python"]
Hash
- name = {"normal" => 0, "small" => -1, "big" => +1, "same" => "the same"}
- p name["normal"] # 0
- p name["big"] # +1
- name["verybig"] = "+2"
- p name["verybig"] # "+2"
- name.each { |key, value|
- print "This: ", key, " => ", value, "\n"
- }
Regex
- p /Ruby/ =~ "Ruby" # 0 (first position)
- p /Ruby/ =~ "Diamond" # nil
- p /Ruby/ =~ "It's Ruby" # 5
- p /Ruby/i =~ "ruby" # 0
If/else
- p (1 != 1)
- if "Ruby" == "Ruby"
- print("true")
- end
[then 可省略]
- if "Ruby" == "Ruby" then
- print("true")
- end
[then 可省略]
- if "Ruby" == "Ruby" then
- print("true")
- else
- print("false")
- end
[then 可省略]
- if x > 1 && x < 10 then
- # a
- elsif x == 5 then
- # b
- else
- # c
- end
一行寫法: print "a > b" if a > b
[then 可省略]
- unless a > b then
- # print a < b condition
- end
[then 可省略]
- item = array[0]
- case item
- when String then
- puts "This is a String."
- when Numeric
- puts "This is a Numeric."
- when /^From/i
- puts "First word is From."
- else
- puts "This is a something."
- end
case 中, when 用的是 ===, === 是 比對 區段所指定的值
- # when A => if A === value
- p ((1..3) === 2) # true
- p /zz/ === "zyzzy" # 2
- p String === "xyzzy" # true
Loop
times
- 100.times {
- print "print 100 times"
- }
[do 可省略]
- 100.times do
- print "print 100 times"
- end
for
- sum = 0
- for i in 1..5
- sum += i
- end
while/do
- [do 可省略]
- i = 1
- while i < 10 do
- puts(i)
- end
util (while 反過來)
- util sum > 50
- sum += 1
- end
each (foreach)
- name = ["abc", "def", "ghi", "jkl"]
- name.each { |n|
- print n, "\n"
- }
loop (無窮迴圈, 要搭配 break/next/redo)
- break: 停止動作, 馬上跳出迴圈
- next: 直接跳到迴圈的下一個 (continue)
- redo: 以相同的條件重新進行這一圈
- loop {
- puts "hello world"
- }
例外處理
- begin
- 有可能發生例外的處理動作
- rescue
- 例外發生時的處理措施
- retry # 重新再跑一次 begin
- ensure
- 無論例外發生與否都堅持要執行的動作
- end
- $! 最後發生的例外(例外物件)
- $@ 最後例外所發生的位置相關資訊
- 例外物件的方法:
- class 例外種類
- message 例外的訊息
- backtrace 例外的發生位置資訊($@ = $!.backtrace)
Function
- def hello
- print "hello world"
- end
- def hello2(a, b=1, c=2)
- print "hello world"
- end
- hello(); hello2(1, 2, 3)
Class
說明:(可用可不用)
- attr_reader :name 只定義用來讀取的方法(定義 name 方法)
- attr_writer :name 只定義用來寫入的方法(定義 name= 方法)
- attr_accessor :name 定義用來讀取與寫入的方法(定義上述兩種方法)
Example:
- class HelloWorld # class << HelloWorld
- Version = "1.0"
- @@count = 0
- def initialize(myname="Ruby")
- @name = myname
- end
- # initialize always private
- def hello # def HelloWorld.hello(name), def self.hello(name)
- @@count += 1
- print "Hello, World. I am ", @name, ".\n"
- end
- public: hello # defalue
- def name=(value) # modify @name, => attr_accessor :name
- @name = value
- end
- private: name
- def HelloWorld.count
- @@count
- end
- end
- bob = HelloWorld.new("Bob")
- alice = HelloWorld.new("Alice")
- ruby = HelloWorld.new # ruby = HelloWorld::new
- bob.hello
- p HelloWorld::Version # "1.0"
- p HelloWorld.count # 1
String class: ext_string.rb
- class String
- def count_word
- ary = self.split(/\s+/)
- return ary.size
- end
- end
- str = "Just Anther Ruby Newbie"
- p str.count_word # 4
繼承
- class RingArray < Array
- def[](i)
- idx = i % size
- super(idx)
- end
- end
- eto = RingArray["子", "丑"]
- p eto[1] # 丑
- p eto[-1] # 丑
Require file
- require "hello" # hello.rb
- hello()
Command line
- print "First args: ", ARGV[0], "\n"
Read file
- filename = ARGV[0]
- file = open(filename)
- text = file.read # read all file
- =begin
- while text = file.gets do # read one line
- print text
- end
- =end
- print text
- file.close
Ruby 物件的唯一性
- 所有物件都有一個 ID 與 值, 可以用 object_id 或 __id__ 取得
- ary1 = []
- ary2 = []
- p ary1.object_id # -605604308
- p ary2.__id__ # -605604309
- ary3 = ary1
Check 是否為相同物件 (equal 的 "? / ()" 中間不能有空白)
- p ary1.equal?(ary2) # false
- p ary1.equal?(ary3) # true
- p "".empty? # true
- p "AA".empty? # false
Type
- ad = ARGV[0].to_i # ad = "1980".to_i (to integer)
- print ad - 1911
- p "12.3".to_f # 12.3
- p 1.2.round # 1
- p 1.8.round # 2
Other
- ary = [] # ary = Array.new
- str = "Hello"
- p ary.class # Array
- p str.class # String
- p str.is_a?(String) # true
- p str.is_a?(Object) # true
除了if外,while、unless、until都可以用一行文
raise也可以用: puts "xxx" raise something
attr_xxxx的用處是讓外部可以直接存取物件變數,就是自己新增setter or getter
另外,幾乎所有東西都可以用block型態
# File:
File.open("xd.txt") do |f|
puts f.readlines
end
嗯嗯, 果然是很活的語言...