Slide 1

Slide 1 text

Ruby と Rails の小ネタ集 2年振りの Ruby on Rails 開発でのちょっと面白い発見を紹介 Roppongi.rb #19 @ 株式会社メドレー様 新奥大介(SmartHR プロダクトエンジニア) 2024/06/13

Slide 2

Slide 2 text

自己紹介 新奥大介 / SmartHR プロダクトエンジニア 異業種からエンジニアを目指すにあたって Ruby を半年学習 受託開発企業入社後に Ruby での開発を半年経験 その後は 2 年間 PHP での開発が続く 現職に入社して Ruby と再会して約 1 年が経過 つまり! Ruby 歴が約 2 年の初心者が紹介する小ネタ集です 皆様ご存知の知識ばかりでも暖かく見守ってくれると嬉しいです!

Slide 3

Slide 3 text

printf で小数点を丸めた時の挙動が予想外だった話 printf メソッド format に従い引数を文字列に変換して出力 "%.2f" というフォーマットを渡すと小数点以下 2 桁まで表示 実例 pi = 3.14159 printf("%.2f\n", pi) # 出力: 3.14 予想外だった挙動 printf("%.2f\n", 0.125)

Slide 4

Slide 4 text

printf で小数点を丸めた時の挙動が予想外だった話 円周率を渡した時の挙動 pi = 3.14159 printf("%.2f\n", pi) # 出力: 3.14 このコードを書いたときどうなると思いますか? printf("%.2f\n", 0.125) # => ???

Slide 5

Slide 5 text

0.13 だよね? printf("%.2f\n", 0.125) # => ?.??

Slide 6

Slide 6 text

マジか・・・四捨五入されると思ってた・・・ printf("%.2f\n", 0.125) # => 0.12

Slide 7

Slide 7 text

予想していた挙動(四捨五入) 0.05.step(1, 0.1){ p [_1.round(3), format("%.1f", _1)]} [0.05, "0.1"] [0.15, "0.2"] [0.25, "0.3"] [0.35, "0.4"] [0.45, "0.5"] [0.55, "0.6"] [0.65, "0.7"] [0.75, "0.8"] [0.85, "0.9"] [0.95, "1.0"]

Slide 8

Slide 8 text

実際の挙動 0.05.step(1, 0.1){ p [_1.round(3), format("%.1f", _1)]} [0.05, "0.1"] # <= ここ以外は偶数丸め(銀行丸め)のルールに則っていそう [0.15, "0.2"] [0.25, "0.2"] [0.35, "0.4"] [0.45, "0.4"] [0.55, "0.6"] [0.65, "0.6"] [0.75, "0.8"] [0.85, "0.8"] [0.95, "1.0"]

Slide 9

Slide 9 text

printf で小数点を丸めた時の挙動が予想外だった話 まとめ printf で小数点を丸める時の挙動は四捨五入ではない 偶数丸め(銀行丸め)に近い挙動をする 偶数丸め is ちょうど半分の値の場合にもっとも近い偶数に丸める処理 端数処理後の値の合計が、元の値の合計値に四捨五入と比べて近くなる 公式ドキュメントの記載 出力結果は実際にはシステムに依存することになります 従って、実行する環境によって結果は変わりそう 厳密に"偶数丸め"というルールで決まっているわけではない

Slide 10

Slide 10 text

「非同期処理だけ何かをしたい」という条件分岐が簡単だった話 状況 Rails での非同期処理の実装に Sidekiq を利用していた あるメソッド中で基本的には Redis にキャッシュされた結果を参照したい ただし非同期処理中はキャッシュされたものではなく最新結果を参照したい 実装前のイメージ 非同期処理中でフラグを明示的に立てて、それによって制御する必要がある?

Slide 11

Slide 11 text

「非同期処理だけ何かをしたい」という条件分岐が簡単だった話 Sidekiq.server? で Sidekiq 中の処理なのかどうかを判定可能 実装 def results Sidekiq.server? ? fetch_results : cached_fetch_results end def cached_fetch_results Rails.cache.fetch("results/#{id}", expires_in: 1800) { fetch_results } end def fetch_results # 外部システムから結果を取得する処理 end

Slide 12

Slide 12 text

何もかもどうでも良くなった時に Sidekiq が寄り添ってくれた話 Rails コンソールログイン中のある日の新奥 こんな開発やってらんねーよ! Sidekiq とかムズすぎ! [1] pry(main) > Sidekiq.❨╯°□°❩╯︵┻━┻

Slide 13

Slide 13 text

オラア!! [1] pry(main) > Sidekiq.❨╯°□°❩╯︵┻━┻

Slide 14

Slide 14 text

!? [1] pry(main) > Sidekiq.❨╯°□°❩╯︵┻━┻ Take a deep breath and count to ten...

Slide 15

Slide 15 text

Sidekiq「新奥、落ち着いて、まずは10秒数えてみて」 [1] pry(main) > Sidekiq.❨╯°□°❩╯︵┻━┻ Take a deep breath and count to ten... 新奥「Sidekiq・・・ありがとう。君のおかげで冷静になれたよ」

Slide 16

Slide 16 text

何もかもどうでも良くなった時に Sidekiq が寄り添ってくれた話 module Sidekiq # ... def self.❨╯°□°❩╯︵┻━┻ puts "Take a deep breath and count to ten..." end # ... end

Slide 17

Slide 17 text

irb に隠れたイースター・エッグの話 irb には隠れたイースター・エッグ(おまけ要素)があるのをご存知だろうか?

Slide 18

Slide 18 text

irb(main):001> IRB.send :easter_egg, :logo -+smJYYN?mm- HB"BBYT TQg NggT 9Q+g Nm,T 8g NJW YS+ N2NJ"Sg N? BQg #( gT Nggggk J 5j NJ NJ NNge #Q #JJ NgT N( @j bj mT J Bj @/d NJ ( #q #(( NgT #J 5d #(t mT $d #q @(@J NJB; @( 5d ? HHH H HQmgggggggmN qD 5d #uN 2QdH E O 5 5JSd Nd NJH @d j Fd @J4d s NQH #d ( #( #o6d Nd NgH #d #d 4 B&Od v NgT #d F #( 9JGd NH NgUd F #d #GJQ d NP $ #J #U+#Q N Q # j j /W BQ+ BQ d NJ NJ - NjJH HBIjTQggPJQgW N W k #J #J b HYWgggN j s Nag d NN b #d #J 5- D s Ngg N d Nd F Fd BKH2 #+ s NNgg J Q J ] F H @ J N y K(d P I F4 E N? #d y #Q NJ E j F W Nd q m Bg NxW N(H- F d b @ m Hd gW vKJ NJ d K d s Bg aT FDd b # d N m BQ mV N> e5 Nd #d NggggggQWH HHHH NJ - m7 NW H N HSVO1z=?11- NgTH bB kH WBHWWHBHWmQgg&gggggNNN NNggggggNN

Slide 19

Slide 19 text

irb(main):001> IRB.send :easter_egg, :dancing

Slide 20

Slide 20 text

まとめ Ruby や Rails を扱っていて予想外なこと、知らないことがたくさんある その中には実務で使える便利なものもあれば、ちょっとクスッとさせてくるよう なコントリビュータ達の遊び心が詰まったものもあったりする 今後も Ruby や Rails を触り続けて「面白い!」と思えるような実装に出会いたい 皆様もオススメのテクニック & 小ネタがあればシェアしてください!