# Ruby(01/14) Day 26 五倍紅寶石(第八屆共筆)(2021/8/02) ## 慣例 - 幾乎所有東西都是物件,連數字也是,會有狀態跟行為 - 命名用蛇式 snake_case - `+ - * / =` 都跟我們平常的認知不同 其實這些運算是方法,後面的值是參數 ex: 5 + 3 可以看成 5 .+ (3) 5 這個物件用 + 方法,帶入 3 這個參數 ex: 5 == 3 (5跟3比較) 可以看成 5 .== (3) 5 這個物件用 == 方法,帶入 3 這個參數 - 結尾不加 ; - 用兩格空白做縮排 - 參數不用 ( ) 包起來 - 註解用 # - 只有 nil 跟 false 是假的,其他都是真的 - nil = 用物件來表示不存在或是空值 - do end 可以跟 { } 做替換 - 方法有寫 ? 通常會回傳布林值 - 方法有寫 ! 通常會有副作用,最好先看手冊再用 ## 印東西出來 = JS console.log() ### puts 只能印出值,會換行,沒有回傳值 ### print 只能印出值,不會換行,沒有回傳值 ### p 能印出型態跟裡面的值,會換行,有回傳值 ## 宣告變數、常數 ### 兩者差異: 在 Ruby 只差在命名方式不同而已 變數用小寫英文當開頭 a = 1 常數用大寫英文當開頭 A = 1 如果把常數 reassigned,Ruby 只會警告你,不會噴出無法重新賦值的錯誤訊息,還是可以正常運作 ### 變數種類 - 區域變數:username - 全域變數:$username 預設值 = nil - 實體變數:@username 預設值 = nil - 類別變數:@@username ## array 陣列 ```=rb a = [1, 2, 3, 4, 5] # 印出最後一個元素 puts a[-1] puts a[last] # 印出第一個元素 puts a[first] # 在 rails 裡面可以用 second 或 third 印出第二、第三元素,但 Ruby 內沒有 # 印出 [1, 2,... , 9, 10] p (1..10).to_a ``` ### 加入元素 - .push - << ## range 範圍 1~10 (1..10) a~z ("a".."z") A~Z ("A".."Z") ## hash 雜湊 跟 JS 物件寫法類似,用在有一堆資料要儲存的時候,沒有順序之分 ```=rb # name 是 key,"kk" 是 value # 下面是語法糖衣,後來才有的,因為別的程式都這樣寫,改這樣比較方便 a = { name: "kk", age: 31 } # 原本長下面這樣,:name才是他 key 的真面目 # : 叫做符號 a = { :name => "kk", :age => 31 } # 如果要印出 name 的值要寫 p a[:name] # 不能寫 p a["name"] # 印出所有 key 或 value p a.keys p a.values ``` ## method 方法 **在 Ruby 的物件沒有屬性,只有方法。** 如果有同樣名稱的變數跟方法,沒有用()呼叫的時候,會優先讀取到變數。 ```=rb # 方法寫法: def aa() end # 如果沒參數可省略() def aa end # 有參數也可省略(),但會不好閱讀,所以不建議省略 def aa(name) # 用雙引號或是%Q()搭配 #{} 可印出變數值 puts "hi #{name}" # 用單引號或是%q()無法印出變數值 puts 'hi #{name}' end # 如果引數跟變數數量不同會噴出 ArgumentError(given 2,expected 1) aa("kk", 123) # return 跟 JS 一樣會有回傳值,不會印出 # 方法內的 return 通常會省略,沒寫的話會自動回傳最後一行的結果 def say_hello # 印出 hi puts "hi" end # 印出 nil,因為沒寫 return 會自動回傳最後一行的結果,且 puts 沒有回傳值 p say_hello ``` - .map = .collect 對每個元素做事 - .filter = .select 過濾我要的出來 - .reject = 相反的 .select 過濾掉我不要的 - .reduce = inject 歸納,通常用在加總 ### 沒有 scope chain 在 ruby 的方法內的變數如果沒定義不會跑出去外面找,跟 JS 不同 ```=rb a = 1 def hello puts a end # 噴出NameError => 沒有 a 這個變數 hello() ``` ### 小數點 可用 to.f 轉換成浮點數,或是運算時直接改成有寫小數點 ```=rb puts 10/3.0 => 3.333 puts 10/3 => 3 (無條件捨去) ``` #### 進位 - .round()四捨五入 - .floor()無條件捨去 - .ceil()無條件進位 - .to_i()無條件捨去 .round(2) 代表四捨五入至小數點後第二位 ## 判斷式 ### if else elsif 中間沒有 e,因為跟 elseif 唸起來都一樣,但比較短 [小弘說法](https://twitter.com/yukihiro_matz/status/989061019287900162) ```=rb a = 1 if (a > 0) puts "hi" elsif (a > 1) puts "hello" else puts "oaoaoa" end ``` #### if 倒裝句 ```=rb puts "宅在家裡" if weather == "下雨" # 等同於 if weather == "下雨" puts "宅在家裡" end ``` #### if 超省略寫法 ```=rb def is_adult?(age) if age >= 18 return true else return false end end # 可寫成: def is_adult?(age) age >= 18 end ``` ### unless 沒事不要用 unless,用 if not 就好,不要搭配 else 使用,會變得不好懂 unless = if not unless not = if ### case when if else 的語法糖衣 ```=rb # .. 代表 range 範圍,0..3 等同 age >= 0 且 age <= 3 case age 0..3 puts ... when age 4..10 puts ... when age 11..18 puts ... else puts ... end ``` ## 例外處理 跟 JS 的 try、catch 一樣, Ruby 用 begin、rescue去做 Ruby 的錯誤類型都可以被歸在 Exception 底下,StandardError 只是其中的一個比較大的錯誤類型 StandardError 代表常見的錯誤類型,下面還有很多子錯誤 Ruby 的錯誤類型:[Exception](https://ruby-doc.org/core-2.5.1/Exception.html) ```=rb # 分母帶0會得到 ZeroDivisonError # 寫法1: def tt(a, b) return a / b end # 用 begin、rescue 捕捉錯誤 begin tt(1, 0) # 用 StandardError 可以捕捉到所有常見錯誤,也可以不省略不寫,變成 rescue => e rescue StandardError => e puts e end # 寫法2: def tt(a, b) return a / b ## 可以省略 begin end 不寫,只寫 rescue 就好 rescue => e puts e end # 用 begin、rescue 捕捉錯誤 begin tt(1, 0) # 用 StandardError 可以捕捉到所有常見錯誤,也可以不省略不寫,變成 rescue => e rescue StandardError => e puts e end ``` ## 迴圈 ### REPL 無窮迴圈 一直在空轉,一個互動式環境 Read-Eval-Print Loop 讀取-評估(evaluate)-輸出 循環 在 node 或 irb 環境內就是一直在做這個循環 ### for 迴圈:以圈數為主,看要繞幾圈 => for 迴圈 迭代:以元素為主,全部元素巡一次 => 類似 forEach ```=rb for name in names puts name end ``` ### while ```=rb # 條件寫在外面 x = 0 while x < 10 puts x # Ruby 沒有 x++ 的用法 x += 1 end ``` until = while not 沒事別用 until,不好懂 ### loop ```=rb loop do puts i i += 1 # 條件寫在裡面 break if i > 10 end ``` ### method 式迴圈 ```=rb # 印出五次 hello ruby 5.times do puts "hello ruby" end # 印出1~10 1.upto(10) do |i| puts i end # 印出10~1 10.downto(1) do |i| puts i end ``` ## Std 標準庫 為了省效能,不常用的方法不會放在裡面 要用的時候可以用 require "" 打包進來用 --- ###### tags: `Ruby`