# Ruby(02/14) Day 27 五倍紅寶石(第八屆共筆)(2021/8/03) ## id 所有物件都有 id ,可用 .object_id 來找。 ## Symbol 符號 - 有名字的物件 - id 固定,不能修改值 - 原本用完記憶體不會歸還 (Memory Leak),新版 Ruby 用完會還 - 因為 id 固定,查找、比較的速度比字串還快 - 本身就是值,不能拿來當變數用 a = :aaa a 是變數,aaa 是名字為 aaa 的物件,他本身就是值,不能拿來當變數用。 literal: 字面上的意思,蘋果標誌就是、[]、{}也是。 - :xxx.to_s:符號轉字串 最後一個引數如果是 hash,{}可省略不寫。 ![](https://i.imgur.com/pOgCBcK.png) ## String 字串 - 是字串物件 - id 不固定、可以修改他的值:連續 puts "aaa".object_id ,會得到不同的 id ,因為字串存放的記憶體位置都不同,用 .freeze 可固定記憶體 - 用完記憶體會歸還 - 可用方法較符號多 - 本身就是值,不能拿來當變數用 符號跟字串都是一個抽象類別,在上層定義方法給下層用,比較不佔記憶體。 ex: 假設我的抽象類別有50個忍術可以用 在讀取的時候只要讀取一次抽象類別 下層就可以直接用了 整個環境只會有50個忍術 如果不這樣做的話 我每次下層新建立一個忍者就要塞50個忍術給他 建立50個忍者就會有2500個忍術跑出來 而且還是重複的,很吃記憶體 - "xxx".to_sym:字串轉符號 ## 數字 - 是數字物件 - id 固定,不能修改值 - 本身就是值,不能拿來當變數用 ## 模組化 把別的檔案的內容加進來用。 - require - ()、副檔名可省略不寫 - 寫多次 require 只會載入一次內容 require("./b.rb") => 執行./b.rb 這個檔案,所有內容都會執行 require "json" => 找 json 這個套件來用,不是找這個檔案 - load - ()可省略不寫,副檔名不能省 - 寫多次 load 會載入多次內容 - live server 就是這樣,本地開發用(當我修改完會立即更新) ## Rake 用來寫各種任務的,把他濃縮成一行指令,可以快速在 Rails 建好東西。 不是 Rack = Ruby 版的 make 拆成很多 task,像是模組化的概念。 用法: - 先做一個檔名是 rakefile 的檔案!!! - 裡面寫 task end,task 名稱要用符號,手冊寫的! - desc 用來幫他加描述 - rake + 方法名稱可執行 - rake -T 可查看目前檔案內有哪些任務,有寫描述的才看的到 - namespace 可用來做分類(類似類別),避免撞名且較清楚 ```=rb # 用 task 方法定義方法名稱 foo,讓我們可以使用 # desc 用來幫他加描述(註解) namespace:db do desc:"foo方法" task :foo do puts "bar" end end # 呼叫 db 裡面的 foo 方法,這邊的:不是符號,是冒號的意思,是終端機的指令,用來找內層的東西 rake db:foo # 預設任務 task :default do puts ... end # 指定預設任務是 db:foo task :default => "db:foo" # 先後順序:會先做 => 後面的任務,上廁所前要先開門 task :go_to_toliet do puts "上廁所" end task :go_to_toliet => open_door do puts "開門" end ``` ## Block - 沒辦法單獨存活,可寄生在別的方法後面 - 是一段不會被主動執行的程式碼 - 會自動回傳最後一行的執行結果 - LocalJumpError - 用 return,會出錯,新版 Ruby 不會跑出錯誤訊息,會在 return 那邊停住 - 有用 yield 但沒寫 {} 也會出錯 - 不是參數,()內的才是 - 看到他就知道前面一定有個方法,讓我可以執行 - block_given? 可以判斷是否為 block 有兩種型態: 1. do end 結合率較弱,有多行通常會用 do end 2. {} 結合率較強,只有一行通常會用{} - yield - 用來執行 block 內的程式碼 - yield 後面沒值的話會印出 nil - 沒寫 |n| 讓 yield 帶值進來會跑出 NameError,找不到 n ```=rb # 印出 # Hello, 你好 # there! # 會跳過 here,因為沒有用 yield def say_hello puts "Hello, 你好" end say_hello { puts "here!" } puts "there!" # 印出 # Hello, 你好 # yield 轉移控制權到下面的 block # here! # 轉移控制權回到 yield 之後 # Hello, ⼤大家好 # there! def say_hello puts "Hello, 你好" yield puts "Hello, ⼤大家好" end say_hello { puts "here!" } puts "there!" # 轉讓控制權時,會帶 3 跟 8 給 block # 印出 3、8 def say_hello yield 3, 8 end say_hello do |n, m| puts n puts m end ``` ```=rb # i 的值是從 times 方法 yield 出來的 5.times do |i| ``` ```=rb # block 會自動回傳最後一行的執行結果 # 把 3 當引數傳到 n ,回傳 false,走到 else def test_two if yield(3) puts "yes, it is 2" else puts "no, it is not 2" end end test_two { |n| n == 2 } ``` ## Proc 類別 可以把 block 變成可被呼叫物件,讓他能單獨存在 可用 call 呼叫他 ```=rb a= Proc.new {|n| n*2} p a.call(2) Proc.new 可用 lambda 代替 lambda 可簡寫成: -> (n) {n + 2} ``` --- ###### tags: `Ruby`