Slide 1

Slide 1 text

Ruby Conf Taiwan 2023 John Lin (@johnlinvc) Unearth Ruby builtin Gems
 發掘 Ruby 的內建 Gems

Slide 2

Slide 2 text

Ruby Conf Taiwan 2023 About ME 關於我 • John Lin • @johnlinvc • Principle Architect @ West Pharma 西 式亞洲 • https://johnlin.vc

Slide 3

Slide 3 text

Ruby Conf Taiwan 2023 Agenda 大 綱 • What is builtin gem?
 什麼是內建 gems • Introduce some useful / interesting builtin gems.
 介紹有 用 /有趣的內建 gems。 • Slide 投影片 : https://johnlin.vc/ruby-conf-tw-2023/

Slide 4

Slide 4 text

Ruby Conf Taiwan 2023 What is builtin Gem? 什麼是內建 Gems? • Gems that come with the default ruby installation.
 安裝 Ruby 時就會預設安裝的 Gems。 • Part of the Standard library.
 Standard library 的 一 部分。 • To provide extended features. 
 提供額外功能。 • 3 types of Standard libraries. 有 3 種 Standard libraries
 Default Library, Default Gem & Bundled Gem.

Slide 5

Slide 5 text

Ruby Conf Taiwan 2023 Default Library • Ruby version/implementation related library. Will NOT become Gems.
 Ruby 版本/實作相關的 library。不會變成 Gems。 • Example 範例 • mkmf: Generate Make fi le for C extensions (only in MRI)
 幫 C extension 產 生 Make fi le (只有 MRI 有) • rbcon fi g: List system info like size of Long. (JRuby use FFI) (MRI use c extension)
 列舉系統資訊,像是 long 的 大 小 。 (JRuby 用 FFI) (MRI 用 c extension)

Slide 6

Slide 6 text

Ruby Conf Taiwan 2023 Default gem • Installed by default. 預設就會安裝。 • Can be upgraded. 可以升級。 • Can NOT be deleted. 不能被刪除。 • Maintained by ruby core. 由 Ruby core 維護。

Slide 7

Slide 7 text

Ruby Conf Taiwan 2023 Bundled gem • Starting from 2.2.0 https://bugs.ruby-lang.org/issues/9852 
 2.2.0 開始 • Installed by default. 預設就會安裝 • Can be upgraded & uninstalled. 可以升級或刪除。 • Need to be added to Gem fi le when using Bundler。 
 用 Bundler 的時候需要加進 Gem fi le 裏。 • Not maintained by Ruby core. 不由 Ruby core 維護。

Slide 8

Slide 8 text

Ruby Conf Taiwan 2023 Why default/bundled gems? • To provide extra features. 提供額外功能。 • Unbind the development of these gem from the interpreter itself. 
 讓這些 Gem 可以獨立於直譯器外開發。

Slide 9

Slide 9 text

Ruby Conf Taiwan 2023 Default vs bundled gems • Bundled gems can be uninstalled.
 Bundled gems 可以被反安裝。 • Bundled gems need to be added to Gem fi le when using Bundler。 
 bundled gems 在 用 Bundler 的時候需要加進 Gem fi le 裏。 • There's an e ff ort to promote default gem into bundled gem by @hsbt.
 @hsbt 正在努 力 的把 default gem 升格為 bundled gem。

Slide 10

Slide 10 text

Ruby Conf Taiwan 2023

Slide 11

Slide 11 text

Ruby Conf Taiwan 2023 Find out builtin gems • https://stdgems.org/ • Or Use the source.
 或是看原始碼。

Slide 12

Slide 12 text

Ruby Conf Taiwan 2023 Builtin gems by buried level 埋藏深度 • Surface 地表 • Crust 地殼 • Mantle 地函 • Core 地核

Slide 13

Slide 13 text

Ruby Conf Taiwan 2023 Surface 地表 • Too famous to be in this talk. 太有名了,就不講了。 • irb • rake • rbs • minitest

Slide 14

Slide 14 text

Ruby Conf Taiwan 2023 Crust 地殼 A lot of people are using them. 
 滿多 人 在 用 的。 • Base64 • Set • OpenStruct • Secure Random

Slide 15

Slide 15 text

Ruby Conf Taiwan 2023 base64 • Convert to & from base64 encoding.
 64進位編碼轉換器。 • Maintainer: Yusuke Endoh (@mametter). World No.1 IOCCC player.

Slide 16

Slide 16 text

Ruby Conf Taiwan 2023 base64 • base64 encoding is not encryption, more like binary or hexadecimal .
 base64 不是加密,比較像是 二 進位或 十 六進 位。 • Don't use it for encryption / hashing !
 不要 用 它來加密或是計算雜湊!


Slide 17

Slide 17 text

Ruby Conf Taiwan 2023 base64 • encode64: output splitted with newline if too long, have an ending newline
 編碼的輸出會 自 動換 行 。結尾也有換 行 。 • decode64, ignore any none base64 chars & newline.
 會忽略輸入中的不合格字元和換 行 。 require 'base64' # => true binary = "\x0a\x1b\x2c\x3d\x4e\x5f" # => "\n" + "\e,=N_" b64 = Base64.encode64(binary) # => "ChssPU5f\n" Base64.decode64(b64)==binary # => true

Slide 18

Slide 18 text

Ruby Conf Taiwan 2023 base64 • Very dense implementation.
 實作超級簡潔。 • Likely because it's Mr. Endo?
 大 概因為是 Endo 寫的? def encode64(bin) [bin].pack("m") end def decode64(str) str.unpack1("m") end

Slide 19

Slide 19 text

Ruby Conf Taiwan 2023 base64 • strict_encode64, output without any newline.
 輸出不會有任何換 行 。 • strict_decode64, raise error when there's any non base64 chars
 當有任何不合格字元時,會 raise error。 Base64.encode64("a"*50) # => "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW FhYWFhYWFhYWFhYWFhYWFhYWFh\n" + "YWFhYWE=\n" Base64.strict_encode64("a"*50) # => "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=" Base64.strict_decode64("aaaa\n") # => :29:in `unpack1': invalid base64 (ArgumentError)

Slide 20

Slide 20 text

Ruby Conf Taiwan 2023 base64 • urlsafe_encode64, same as strict, but use - instead of +, _ instead of / to avoid url encoding issue
 和strict 一 樣,但是 用 - 取代 +, 用 _ 取代 / 來避免 URL 編碼問題。 • urlsafe_encode64, decode data encoded by urlsafe_encode64
 用 來解上 面 的輸出。 plus_slash = "+/+/" # => "+/+/" b64_plus_slash = Base64.decode64(plus_slash) # => "\xFB\xFF\xBF" Base64.encode64(b64_plus_slash) # => "+/+/\n" Base64.urlsafe_encode64(b64_plus_sl ash) # => "-_-_"

Slide 21

Slide 21 text

Ruby Conf Taiwan 2023 Set • A data stucture that contains only uniq values.
 只包含獨特值的資料結構。 • Useful when doing interview questions.
 面 試的時候很有 用 。 • Maintainer: Akinori MUSHA (@knu) •

Slide 22

Slide 22 text

Ruby Conf Taiwan 2023 Set • Set#add to add new value.
 加入新的值 • Set#delete to delete value.
 刪除 一 個值 • Set#include? to check if values inside
 檢查有沒有某個值 set = Set.new # => # set.add("rubyconf") # => # set.add("tw") # => # set.include?("tw") # => true set.delete("tw") # => #

Slide 23

Slide 23 text

Ruby Conf Taiwan 2023 Set • Actually implemented with Hash.
 實際上是 用 Hash 實作的。 • store ture as the value.
 Hash 存的值是 true。 def initialize(enum = nil, &block) @hash ||= Hash.new(false) ... end def add(o) @hash[o] = true self end def include?(o) @hash[o] end

Slide 24

Slide 24 text

Ruby Conf Taiwan 2023 Set • Set.add? returns self if add successfully.
 可以邊加值邊檢查裡 面 現在是不是已經有 了。 • set = Set.new # => # set.add?("tw") # => # set.add?("tw") # => nil

Slide 25

Slide 25 text

Ruby Conf Taiwan 2023 Set • Set#intersection, & : fi nd intersection.
 找交集。 • Set#union, | : fi nd union.
 找聯集。 • Set#di ff erence, - : fi nd di ff erence.
 找差集。 japan = Set.new(%w{japan rubykaigi ruby}) # => # tw = Set.new(%w{tw rubyconfg ruby}) # => # japan & tw # => # japan | tw # => # japan - tw # => #

Slide 26

Slide 26 text

Ruby Conf Taiwan 2023 OpenStruct • A Struct with dynamic member, allow using dot to access member. 
 有動態元素的 struct,可以 用 "." 來存取。 • Maintainer: Marc-André Lafortune(@malafortune)

Slide 27

Slide 27 text

Ruby Conf Taiwan 2023 OpenStruct • Allow direct access with dot .
 可以 用 "." 來存取。 • Can be accessed with [] as well.
 也可以 用 [] 來存取。 • Don't work if the key have weird stu ff .
 不過如果 key 太奇怪就會壞掉。 require 'ostruct' # => true person = OpenStruct.new # => # person.name = "John Smith" # => "John Smith" person.name # => "John Smith" person.address # => nil person[:name] # => "John Smith"

Slide 28

Slide 28 text

Ruby Conf Taiwan 2023 secure random • Generate random number using CPRNG(https://en.wikipedia.org/wiki/ Cryptographically_secure_pseudorandom_number_generator)
 產 生 密碼學安全的亂數。 • Maintainer: Tanaka Akira (@tanaka_akr)

Slide 29

Slide 29 text

Ruby Conf Taiwan 2023 Secure Random vs Random • Random#rand : • Use Mersenne Twister, need a seed.
 用 Mersenne Twister,需要 seed。 • Can be predicted after 624 calls.
 觀察輸出 624 次後就可以預測下 一 個值。 • Secure Random • Use /dev/urandom, Win32 or openssl
 使 用 /dev/urandom, Win32 or openssl • Hard to predict next output
 很難預測下 一 個值。

Slide 30

Slide 30 text

Ruby Conf Taiwan 2023 Secure random • Provide some wrapper around the generated random number
 亂數的輸出有 一 些 方 便使 用 的格式。 • rand to return a value between 0 and 1
 回傳 0 到 1 之間的值。 • bytes to return some bytes
 回傳 一 些 byte。 • uuid, alphanumeric, base64. require 'securerandom' # => true SecureRandom.rand # => 0.46760427030684526 SecureRandom.bytes(8) # => "K+ \xE1\xA2Q\xCFm\xBD" SecureRandom.uuid # => "73f0a178-3745-48eb-8a30-0f7364760b 47" SecureRandom.alphanumeric # => "IRCQihGOALKHhuf7" SecureRandom.base64 # => "cnBxZuU93ZqbRqolOYNmxA=="

Slide 31

Slide 31 text

Ruby Conf Taiwan 2023 Mantle 地函 Useful in some situation. less people know about them.
 有的時候有 用 ,比較少 人 知道。 • tsort • FileUtils • IPAddr • abbrev • un

Slide 32

Slide 32 text

Ruby Conf Taiwan 2023 tsort • Topological sort for graph.
 用 來找 graph 裡 面 的拓墣排序。 • Topological sort is the order of nodes by it's dependency.
 拓墣排序是節點 用 相依性排列後的順序。 • Maintainer: Akira Tanaka (@tanaka_akr)

Slide 33

Slide 33 text

Ruby Conf Taiwan 2023 tsort • It's a mixin module, require your class to provide 2 methods
 是 一 個 mixin module。需要 自己 實作兩個 method。 • tsort_each_node to provoide a list of nodes.
 提供所有的 node • tsort_each_child to provide a list of children for a speci fi c node.
 提供某 一 個 node 的所有 child。 • Call tsort to get reversed topological sort order.
 回傳反轉過的拓墣排序。 require 'tsort' # => true class Hash include TSort alias tsort_each_node each_key def tsort_each_child(node, &block) fetch(node).each(&block) end end # => :tsort_each_child {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort # => [3, 2, 1, 4]

Slide 34

Slide 34 text

Ruby Conf Taiwan 2023 tsort • By name, it's doing topological sort. But actually it's running a Strongly connected components algorithm, Tarjan's strongly connected components algorithm.
 看起來好像是跑 topological sort 。但實際上是跑 Tarjan's 演算法來找 Strongly connected components 。 • There's a Bug section about naming in README.
 說明裡有 一 個 Bug 段落來講命名。 • Tarjan's algorithm also outputs a
 reversed topological sort
 剛好會輸出反轉過的拓墣排序

Slide 35

Slide 35 text

Ruby Conf Taiwan 2023 tsort • Call strongly_connected_components to get Strongly connected components .
 回傳 Strongly connected components。 require 'tsort' # => true class Hash include TSort alias tsort_each_node each_key def tsort_each_child(node, &block) fetch(node).each(&block) end end # => :tsort_each_child {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_component s # => [[4], [2, 3], [1]]

Slide 36

Slide 36 text

Ruby Conf Taiwan 2023 Fileutils • Handle common fi le operations across platforms.
 可以跨平台處理檔案。 • Maintainer: Minero Aoki (@mineroaoki).

Slide 37

Slide 37 text

Ruby Conf Taiwan 2023 Fileutils • FileUitls.rm_rf to delete folder and all it's contents.
 刪除 目 錄和之下的所有檔案。 • cp_r to copy folder and all it's contents.
 複製 目 錄和之下的所有檔案。 • mkdir_p to create folder and all it's parent if not exists.
 創造 目 錄,包含所有的 母目 錄。 • touch to update modify time
 更新修改時間。 require 'fileutils' # => true FileUtils.mkdir_p("test/ file_utils") # => ["test/ file_utils"] FileUtils.touch("test/ file_utils/.keep") # => ["test/ file_utils/.keep"] FileUtils.cp_r("test/file_utils", "test/copy") # => nil FileUtils.rm_rf("test") # => ["test"]

Slide 38

Slide 38 text

Ruby Conf Taiwan 2023 ipaddr • Operations on IP address .
 操作 IP 位置。 • Maintainers: Akinori MUSHA (@knu) & Hajimu UMEMOTO (@h_ume)

Slide 39

Slide 39 text

Ruby Conf Taiwan 2023 ipaddr • & to fi nd bitwise AND, NOT intersection
 對位元作AND,不是交集。 • | to fi nd bitwise OR, NOT union
 對位元作AND,不是聯集。 • include? to check if IP is in a CIDR
 檢查IP是不是在區塊內。 require 'ipaddr' # => true addr1 = IPAddr.new("10.1.10.1/24") # => # addr2 = IPAddr.new("10.1.20.1/24") # => # addr1 | addr2 # => # addr1 & addr2 # => # addr1.include? (IPAddr.new("10.1.10.20")) # => true

Slide 40

Slide 40 text

Ruby Conf Taiwan 2023 ipaddr • private? to check if it's a private IP.
 檢查是否是私有網路IP • loopback? to check if it's a loopback IP.
 檢查是否是環回 IP • to_range to cast it to a range for iteration.
 可以轉換成 range。 ip172 = IPAddr.new("172.25.3.4") # => # ip172.private? # => true local = IPAddr.new("127.0.0.4") # => # local.loopback? # => true block192 = IPAddr.new("192.168.3.32/28") # => # block192.to_range # => # .. # block192.to_range.count # => 16

Slide 41

Slide 41 text

Ruby Conf Taiwan 2023 abbrev • Find all the possible uniq abbreviation for a set of string.
 幫 一 組字串找出所有可能的縮寫。 • Useful for CLI arguments, for example ./my_cmd u can be expanded into ./my_cmd update using abbrev.
 處理命令列參數時很好 用 ,./my_cmd update 可以縮寫成 ./my_cmd u。 • Maintainer: Akinori MUSHA (@knu) •

Slide 42

Slide 42 text

Ruby Conf Taiwan 2023 abbrev • .abbrev take a array of stings.
 輸入是 一 個字串陣列。 • returns a Hash as lookup table.
 回傳 一 個Hash 查找表。 • No ambiguous pre fi x in the lookup table.
 表裡 面 沒有會對到不同字串的 pre fi x Abbrev.abbrev(%w{ install update upgrade }) # => {"install"=>"install", "instal"=>"install", "insta"=>"install", "inst"=>"install", "ins"=>"install", "in"=>"install", "i"=>"install", "update"=>"update", "updat"=>"update", "upda"=>"update", "upd"=>"update", "upgrade"=>"upgrade", "upgrad"=>"upgrade", "upgra"=>"upgrade", "upgr"=>"upgrade", "upg"=>"upgrade"}

Slide 43

Slide 43 text

Ruby Conf Taiwan 2023 un • Useful to do things as cli one liner. 
 提供 一 些命令列的指令。 • Useful in Make fi le for cross platform。
 寫跨平台 Make fi le 的時候很好 用 。 • When combined with the require -r fl ag, looks like -run
 當和 require 用 的 -r 參數放在 一 起的時候。看起來像 -run。 • Maintainer: WATANABE Hirofumi

Slide 44

Slide 44 text

Ruby Conf Taiwan 2023 un • ruby -run -e cp -- [OPTION] SOURCE DEST to copy fi les
 複製檔案 • ruby -run -e mv -- [OPTION] SOURCE DEST to move fi le/folder
 移動檔案 • ruby -run -e httpd -- [OPTION] [DocumentRoot] start a http server at DocumentRoot, but need to install webrick after Ruby 3.0.0. Useful to transfer fi le in local network.
 開 一 個 http server。不過在 Ruby 3.0.0 之後需要額外裝 webrick。 用 來在區網傳檔案很好 用 。

Slide 45

Slide 45 text

Ruby Conf Taiwan 2023 Core 地核 Most people don't know Ruby have this as builtin.
 大 部分 人 不知道 Ruby 有內建 Or don't know we can use it directly.
 或是不知道可以直接拿來 用 。 • prime • Forwardable • Delegate • Singleton • did_you_mean

Slide 46

Slide 46 text

Ruby Conf Taiwan 2023 Prime • Bundled gem • Generate prime number, checks prime number, prime factorization.
 產 生 質數,檢查質數,質因數分解。 • Maintainer: Marc-Andre Lafortune(@malafortune)

Slide 47

Slide 47 text

Ruby Conf Taiwan 2023 Prime • Use Miller–Rabin primality test to check prime, 
 用 Miller-Rabin 來檢查是否是質數。 • Become very slow after reaching limit of Miller–Rabin. 3_317_044_064_679_887_385_961_981
 超過 Miller-Rabin 的極限後就會變慢。 • 
 require 'prime' # => true Prime.prime?(7) # => true 8.prime? # => false

Slide 48

Slide 48 text

Ruby Conf Taiwan 2023 Prime • Use Sieve of Eratosthenes to generate Primes 
 用 埃拉托斯特尼篩法 來產 生 質數。 Prime.take(4) # => [2, 3, 5, 7] Prime.each(7).to_a # => [2, 3, 5, 7]

Slide 49

Slide 49 text

Ruby Conf Taiwan 2023 Prime • Use Wheel factorization for prime division.
 用車 輪分解來產 生 質因數分解 用 的因數。
 Prime.prime_division(8959) # => [[17, 2], [31, 1]]

Slide 50

Slide 50 text

Ruby Conf Taiwan 2023 Forwardable • Forward speci fi c method calls to another object.
 轉發特定 method 給其他物件。 • Maintainer: Keiju Ishitsuka, Ruby' god father. Who coined the name Ruby with Matz
 Ruby 的教 父 ,和 Matz 一 起討論了 Ruby 這個名字。

Slide 51

Slide 51 text

Ruby Conf Taiwan 2023 Forwardable • def_delegator , delegate to another object with di ff erent name
 轉發呼叫給另 一 個物件的特定 method。
 class RecordCollection attr_accessor :records extend Forwardable def_delegator :@records, : [], :record_number end # => :record_number r = RecordCollection.new # => # r.records = [4,5,6] # => [4, 5, 6] r.record_number(0) # => 4

Slide 52

Slide 52 text

Ruby Conf Taiwan 2023 Forwardable • def_delegators, delegate methods to another object.
 轉發呼叫給其他物件。
 class RecordCollection def_delegators :@records, :size, :<<, :map end # => [:size, :<<, :map] r = RecordCollection.new # => # r.records = [1,2,3] # => [1, 2, 3] r.size # => 3 r << 4 # => [1, 2, 3, 4] r.map { |x| x * 2 } # => [2, 4, 6, 8]

Slide 53

Slide 53 text

Ruby Conf Taiwan 2023 Delegate • Delegate all unde fi ned methods.
 轉發所有未定義的 method。 • Maintainer: Yukihiro Matsumoto (@yukihiro_matz) , Ruby's Father.

Slide 54

Slide 54 text

Ruby Conf Taiwan 2023 Delegate • DelegateClass: create a super class that wraps the Delegated class.
 創造 一 個新的 class ,把轉發的 目 標包住。 • Main interface
 主要的 用 法。 class TimeWithAgo < DelegateClass(Time) def initialize(arg) @t = Time.new(arg) super(@t) end def years_ago = Time.now.year - year end # => :years_ago t = TimeWithAgo.new("1993-02-24 UTC") # => 1993-02-24 00:00:00 UTC t.year # => 1993 t.years_ago # => 30 ~

Slide 55

Slide 55 text

Ruby Conf Taiwan 2023 Delegate • Simple delegator , forward all unde fi ned methods to the the target object.
 轉發所有未定義的 method 給 目 標物件。 class TimeDecorator < SimpleDelegator def years_ago = Time.now.year - year end # => :years_ago t = TimeDecorator.new(Time.new("1993-02 -24 UTC")) # => 1993-02-24 00:00:00 UTC t.year # => 1993 t.years_ago # => 30

Slide 56

Slide 56 text

Ruby Conf Taiwan 2023 Delegate vs inheritance • Delegate only delegate public methods, protecting private methods from send calls.
 Delegate 只會轉發給 public method,可以 用 來讓 send 呼叫不到 private method。 • "Has a" vs "Is a"
 有 一 個 vs 是 一 個。 • Delegate can be recon fi gured during runtime easily.
 Delegate 可以在執 行 期動態修改 目 標。

Slide 57

Slide 57 text

Ruby Conf Taiwan 2023 Singleton • Provide Singleton pattern. 提供單例模式 支 援。 • Maintainer: Yukihiro Matsumoto (@yukihiro_matz) , Ruby's Father.

Slide 58

Slide 58 text

Ruby Conf Taiwan 2023 Singleton • #instance returns the singleton instance.
 回傳單例實體。 • .new is marked private.
 .new 變成 private • Easier to understand than class instance variable @@var.
 比起 用 class instance varible 容易理解。 • Thread safe
 執 行 序安全。 class BDFL include Singleton def name = "Matz" end # => :name BDFL.instance.name # => "Matz" BDFL.new # => (...:in `': private method `new' called for class BDFL (NoMethodError)

Slide 59

Slide 59 text

Ruby Conf Taiwan 2023 Did you Mean • Help user fi nd typos in their code.
 幫助使 用 者尋找錯字。 • Maintainer: Yuki Nishijima (@yuki24)

Slide 60

Slide 60 text

Ruby Conf Taiwan 2023 Did you Mean • Generates suggestion in error messages.
 在錯誤訊息中產 生 建議。 • Works for methods & constants etc.
 對 method 和 constant 名都有效。 3.3.0-preview3 :001 > evel(1) (irb):1:in `': undefined method `evel' for main (NoMethodError) Did you mean? eval 3.3.0-preview3 :003 > Irb (irb):3:in `': uninitialized constant Irb (NameError) Did you mean? IRB

Slide 61

Slide 61 text

Ruby Conf Taiwan 2023 Did you Mean • You can call it's word comparing methods directly.
 可以直接呼叫他的字串比對 method。 • Levenshtein distance, also known as edit distance.
 萊 文 斯坦距離 , 又 叫編輯距離。 • Jaro–Winkler distance, normalized similarity.
 Jaro–Winkler 距離,正規化的相似度。 DidYouMean::Levenshtein.distance("r ubyconf tw", "rubykaigi") # => 7 DidYouMean::Jaro.distance("rubyconf tw", "rubykaigi") # => 0.6026936026936026 DidYouMean::JaroWinkler.distance("r ubyconf tw", "rubykaigi") # => 0.6026936026936026

Slide 62

Slide 62 text

Ruby Conf Taiwan 2023 Customize Did you Mean to find path error class EnoentChecker def initialize(exception) @rel_path = exception.message.split("-")[1].strip @path = File.expand_path(@rel_path, File.dirname(__FILE__)) end def dictionary = Dir.foreach(File.dirname(@path)).to_a def corrections = DidYouMean::SpellChecker.new(dictionary:).correct(@rel_path).uniq end # => :corrections DidYouMean.correct_error Errno::ENOENT, EnoentChecker # => Errno::ENOENT File.read("hallo.txt") # => didyoumean.rb:14:in `read': No such file or directory @ rb_sysopen - hallo.txt (Errno::ENOENT) Did you mean? hello.txt

Slide 63

Slide 63 text

Ruby Conf Taiwan 2023 Takeaway 結論 • Ruby is battery-included. Tons of good stu ff s in standard libraries.
 Ruby 內建很多功能。標準函式庫裡有很多好東 西 。 • There's an ongoing e ff ort of promoting standard libraries to bundled gems.
 正在努 力 把標準函式庫升級成 bundled gems。 • https://stdgems.org/ have a list of standard libraries.
 有標準函式庫的清單。 • Next time you can check the Standard library before searching for 3rd party gems.
 下 一 次在 用 第三 方 Gem 之前,可以先看看標準函式庫有沒有。 •

Slide 64

Slide 64 text

Ruby Conf Taiwan 2023 Q&A X: @johnlinvc Slide : https://johnlin.vc/rubyconftw2023