Roll With IT

tamakiのIT日記

チェリー本輪読会 第1週目まとめ

f:id:shirotamaki:20210619091936p:plain

🍒 はじめに

チェリー本の輪読会に参加し4週間が経ちました。 https://shirotamaki.hatenablog.com/about 6月29日に登壇するLT会【初心者歓迎】Ruby LT会@オンライン - connpassのネタ探しも兼ね、輪読会で学んだことをブログ記事にまとめたいと思います。

まずは第1週目のまとめ記事になります。2週目以降については随時エントリーしていきたいと思います。

では早速。

フィヨルドブートキャンプでは、有志が集い輪読会が開催されています。

主催者の トミー さん(id:eatplaynap329)の呼び掛けにより始まった輪読会(トミーさんいつもありがとうございます!)

今ではレギュラーメンバー7名に加え、日によりますがラジオ参加を含めると最大16名近く集まる一大派閥? 笑 です。 オンライン上の集まりとあって、始めた当初はぎこちなかったのですが、今ではみんなとワイワイ楽しく開催しています。

まずは簡単に輪読会の概要を書いてから、本題の学んだ内容を書いていきたいと思います。

🍒 概要

課題本

gihyo.jp

通称:チェリー本 (当ブログでは今後チェリー本と記載を統一させていただきます)

輪読会の目的

  • Rubyを楽しむ
  • チェリー本を深く理解する
  • 得た知識をみんなで共有する
  • 疑問をたくさん持ち、著者の伊藤さんに直接質問してみる(伊藤さんはフィヨルドブートキャンプのメンターもされています)

輪読会の形式

  • 特に期限を設けた輪読会ではないため、第1章から順番に読み進めていく形式を取っています。
  • 必要に応じてモブプロを行い、実際に動きを確認しながら進めていきます。

参加条件

開催日時・場所

  • 平日 9:00〜10:00
  • Discordの輪読会チャンネル

🍒 輪読会 第1週目まとめ

では本題へ。

第1週目で学んだことについて書きたいと思います。

第1章1.1.1〜第2章2.8.6まで

期間:2021年05月25日〜2021年05月28日

Rubyのバージョンは?

Rubyのバージョンは「3.0.0」で進めていくことにしました。(輪読会スタート当時の安定版は3.0.1)

本書はRuby2.4.0を元に書かれていますが、必要に応じて著者の伊藤さんのQiita記事で補完すれば、バージョンは3.0.0で問題なさそうです。

Ruby 3.0で発生する「プロを目指す人のためのRuby入門」との差異について - Qiita

Rubyのバージョンの見方

例: 3.0.0

Ruby のバージョンは、major.minor.teeny という3つの形式で表されています。

  • majorバージョンは、アーキテクチャやコンセプトの変更が行われるとバージョンアップします。
  • minorバージョンは、大幅な仕様変更や機能追加されるとバージョンアップします。
  • teenyバージョンは、軽微な仕様変更、小さな機能追加等が行われるとバージョンアップします。(teenyは「小さな」の意)
$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]

エディタは何を使うの?

エディタについては、各々自由に好きなものを使うことになっています。

しかし、参加メンバーに伺うとRubyMineが圧倒的多数を占めていました。 私自身、VSCodeとRubyMineしか使ったことがなく使用歴も浅いため、RubyMineの便利さにまだそこまでメリットを感じていませんでした。しかし、長くRubyMineを使っている方や現役のプログラマの方のご意見を伺うと(著者の伊藤さんもRubyMineを愛用している)、「Rubyを使うならRubyMine!!」と、圧倒的な人気を誇っているようで、Rubyを書くことに適したとても拡張性の高いエディタであるのは間違いなさそうです。まだまだ使いこなせていないので、輪読会を通してRubyMineとも仲良くなりたいと思います。

丸め誤差

チェリー本ではコラムの項目で取り上げられている内容ですが、きちんと理解できていなかったため輪読会では時間を多めに取り見直しました。同じ受講生の方が、この話題をブートキャンプ内で取り上げておりそちらのまとめた日報を参考にさせていただきました。

他、以下書籍も参考にしました。

キタミ式イラストIT塾 基本情報技術者 令和03年:書籍案内|技術評論社

実際にirbを使い動かしてみます。 コンピュータの計算では、10進数を2進数へ変換して計算されるため以下のような結果となります。

irb#1(main):001:0> 0.1 * 3.0
=> 0.30000000000000004

Rational(有理数クラス)を使うことで丸め誤差問題を解決できます。 有理数とは、「整数および分数」のことです。

irb#1(main):003:0> 0.1r * 3.0r
=> (3/10)   

# 10分の3 

rationalizeメソッドを使うことでRationalクラスの数値に変換できます。

Float#rationalize (Ruby 3.0.0 リファレンスマニュアル)

irb#1(main):008:0> a = 0.1
=> 0.1
irb#1(main):009:0> b = 3.0
=> 3.0
irb#1(main):010:0> d = a.rationalize * b.rationalize
=> (3/10)

小数点に戻したい場合は、to_ffはfloatのf。浮動小数点数の意。

irb#1(main):011:0> d.to_f
=> 0.3

Rubyでは(Ruby以外の言語でもよく発生するらしい)丸め誤差問題を回避するため、上記の対応を行う必要があります。少数を扱う計算で思わぬ結果に出くわしたとき、今回の件を思い出し対処したいと思います。

falseとnil以外はすべて真(true)

Rubyの真偽値。 falsenilであれば偽になる。他の言語だと珍しいことのようです。 各言語におけるtrue/falseまとめ - 昼メシ物語

if文のelseは省略可能

条件分岐で多用しているif文。else(elsifも同様)が不要なのは知らなかったです。 今までずっと付けていた気がする....汗。今後は外していきます。

後置if

Rubyのif文は修飾子として文の後ろに置くことができます。 まずは通常のif文から。

irb(main):004:0> x = "foo"
=> "foo"
irb(main):005:1* if x == "foo"
irb(main):006:1*   puts "bar"
irb(main):007:1* end
bar
=> nil

後置ifを使い書き換えてみます。 一行でシンプルに書けます。競プロとかで使いこなしたいです。

irb(main):008:0" puts result = "bar" if x == "foo"
bar
=> nil

printfメソッドとsprintfメソッドの違い

printfsprintfメソッドのfは、formatから来ています。formatはエイリアスメソッド。 指定されたフォーマットの文字列を作成することができるメソッドです。

  • pritntfメソッドは、整形した文字列をコンソールに出力する。
  • sprintfメソッドは、整形した文字列をオブジェクトにして返す。

%bは、整数を2進数表現で出力する指定子です。 Kernel.#format (Ruby 3.0.0 リファレンスマニュアル)

printfメソッド

nilが返ってきます。

irb(main):005:0> printf('%b', 4)
100=> nil

sprintfメソッド

文字列オブジェクトが返ってきます。

irb(main):006:0> sprintf('%b', 4)
=> "100"

メソッド名は「ひらがな」「漢字」、そして「絵文字」もOK

普段、英語表記でしかメソッド名を命名したことがなかったので読み直してみて改めて驚きました。

絵文字もメソッド名にできるなんて遊び心があって面白いですね。

irb(main):004:1* def ちぇりー
irb(main):005:1*   puts "さくらんぼ"
irb(main):006:1* end
=> :ちぇりー
irb(main):007:0> ちぇりー
さくらんぼ
=> nil

irb(main):008:1* def 錯乱坊
irb(main):009:1*   puts "赤い果物"
irb(main):010:1* end
=> :錯乱坊
irb(main):011:0> 錯乱坊
赤い果物
=> nil

irb(main):012:1* def 🍒🍒🍒
irb(main):013:1*   puts "絵文字"
irb(main):014:0> end
=> :🍒🍒🍒
irb(main):015:0>  🍒🍒🍒
絵文字
=> nil

returnは、メソッドを途中で脱出するときに使われることが多い

普段は省略されることの多いreturn文

他の言語経験者だと違和感が強いらしいです。

returnを書かなくても結果は同じ。以下は書いているパターン。

irb(main):007:1* def add(a,b)
irb(main):008:1*   return a + b
irb(main):009:1* end
=> :add
irb(main):010:0> add(5,7)
=> 12

上記の使い方とは別で、returnはメソッドを途中で脱出するときに使わることが多いです。 下記、条件が一致したときにメソッドをすぐに終了させる例です。

irb(main):014:1* def min(x, y)
irb(main):015:2*   if x < y
irb(main):016:2*     return "xの方が小さい"
irb(main):017:1*   end
irb(main):018:1*   "yの方が小さい"
irb(main):019:1* end
=> :min
irb(main):020:0> min(4, 6)
=> "xの方が小さい"
irb(main):021:0> min(7, 3)
=> "yの方が小さい"

ガード節(Guard Clause)

Rubyに限らず、多くのプログラミング言語リファクタリングで有用な実装手法です。 「ガード節」「ガード条件」「ガード構文」などと呼ばれています。

return foo if bar (barがtrueだったらfooを実行)といった形式を覚えておきたいです。

ちなみに、ガード節を書いた文の下一行は空けておくのがお作法らしいです。

また、完全なる余談ですが、ブログを執筆している今日6月18日はポールマッカトニーの誕生日です。 ハッピーバースデーポール!!

irb(main):016:1* def play(name)
irb(main):017:1*   return 'nameを入力してください' if name.nil?
irb(main):018:1*
irb(main):019:2*   if name == 'Paul'
irb(main):020:2*     'I play bass guitar!'
irb(main):021:2*   elsif name == 'Ring'
irb(main):022:2*     'I play drums!'
irb(main):023:2*   else
irb(main):024:2*     'I play guitar'
irb(main):025:1*   end
irb(main):026:0> end
=> :play
irb(main):027:0> play('Paul')
=> "I play bass guitar!"
irb(main):028:0> play(nil)
=> "nameを入力してください"
irb(main):029:0>

参考書籍

🍒 まとめ

第一週目を終えた率直な感想としては、「え?こんなこと書いてあったけ?」の連続で、改めて人間は忘れる生き物であると思い知らされました。

忘却曲線 - Wikipedia

しかし、何度も読み返すことで知識が定着し、そこから多くの学びを得ることができているのは間違いありません。良い教科書を何度も読み直すことの大切さを改めて痛感し、知識が知恵になっている感覚です。 また、輪読会の効果をとても感じています。疑問を持ちその場で共有し解決していけることや、自分では読み取れなかった情報を他のメンバーからの共有で気づけたりなど、これは一人では得れない学びです。

今回記事にまとめた第1週目は、本書を読み進めると同時に輪読会の進め方の意見を出し合いつつ、時間配分、司会決めなどルール整備も行いました。ルール整備とはいってもガチガチな取り決めはなく、上記輪読会の目的に沿って、まずは「楽しむ」を念頭におき、みんなでワイワイやっています。

まだ始まったばかりですが、会の前後では雑談をしたり、「チェリー本終わったら別の本でもやりたいですね〜」と、次回の候補本の話しがあったり、輪読会を通して同じ目標を持つ仲間ができとても楽しいです。

今後も上記スケジュールで随時開催しておりますので、気になった受講生の方はもちろん、卒業生、メンター、アドバイザーのみなさん!ぜひ遊びに来てください!お待ちしております〜!

最後に、著者の 伊藤さん(id:JunichiIto)、卒業生でもあり先輩プログラマの 森塚さん(id:sanfrecce-osaka)には日頃から多くのアドバイスをいただき感謝申し上げます!

今後ともどうぞよろしくお願いします!!