koheitakahashiのブログ

2020.07.01にプログラマーとして生を受けた私が学んだことや、日常について徒然に書いていきます。

『メタプログラミングRuby 第2版』を読みました

はじめに

Rubyを学び始めてから1年弱になるものの、なんとなくRubyを書いている感が否めませんでした。
そして、Rubyを使っているのではなく、Rubyに使われているという状態です。

「Rubyを理解してRubyを使いこなしたい」と思い、Rubyをより理解するために本書を手に取りました。

学んだこと、感想をまとめます。

bookmeter.com

本書の章立て

本書はⅠ部とⅡ部に別れており、以下のような章立てで構成されていました。

Ⅰ部 メタプログラミングRuby

1章 頭文字M

2章 月曜日: オブジェクトモデル

3章 火曜日: メソッド

4章 水曜日: ブロック

5章 木曜日: クラス定義

6章 コードを記述するコード

7章 エピローグ

Ⅱ部 Railsにおけるメタプログラミング

8章 Rails ツアーの準備

9章 Active Record の設計

10章 Active Support の Concern モジュール

11章 alias_method_chain の定義

12章 アトリビュートメソッドの進化

章ごとの感想

1章 頭文字M

そもそもメタプログラミングとはなんなのかという、本書の導入部分でした。

メタプログラミングとは、

コードを記述するコードを記述すること

と本書では定義されていました。

この言葉を読んだときに、これがどういうことなのかということは1章を読んだ時点でピンときませんでした

しかし、後の章を読み進めていく中でなんとなく(本当になんとなく)、この言葉の意味が掴めました。

2章月曜日: オブジェクトモデル

「メタプログラミングができる人と一緒に仕事をしていく1週間」というストーリーで書かれており、ユーモラスだと思いながら読んでいました。

Rubyはオープンクラスの仕組みの説明と、それによりどのようなことが可能になっているかということがまとめられた章でした。

特に印象に残ったのはRefinementsのお話です。
Refinementsは2020.09.04から行われていた「RubyKaigi takeout」で発表をお聞きしていましたが、その時はあまり理解できませんでした。

今回、そこで聞いたお話と本章の内容を合わせてRefinementsが「どのようなものなのか」・「どのような問題があるのか」ということが理解できました。

3章火曜日: メソッド

「メソッドを動的に定義したい時はどうするのか」が主題となっていた章でした。

Object#senddefine_methodを駆使したり、method_missingをオーバーライドしたりという方法で上記の問題に対応できるということでした。

上記の方法を知ることができて、自分の中にあるRubyの世界が広がりました。

4章水曜日: ブロック

「ブロックとは何者なのか、どのように定義されるのか」「Procとlambdaの違いとは」という内容がまとめられた章でした。

普段何気なく使っていたブロックですが、「ブロックは束縛」ということを知って、ブロックへの理解が深まりました。

また、Procとlambdaについて存在は知っており、Procを使ったことがありました。 しかし、どのように使い分ければ良いのかが分からなかったため、両者の違いがまとめられており有り難かったです。

5章木曜日: クラス定義

class_evalとは」「特異メソッドとは」「エイリアスとは」という内容がまとめられた章でした。

正直なところ、この章はよく理解できませんでした。
特に「アラウンドエイリアス」というものを理解できませんでした。

この章は、今後本書を読み返したときに改めて整理して理解したいと思います。

6章コードを記述するコード

Kernel#evalを使うことで、渡したコード文字列を実行できるということがまとめられた内容でした。

一方でコード文字列を使用する際には、コードインジェクションのリスクがあるため、注意しなければならないということを理解しました。

コード文字列については、全く知らなかったため、勉強になりました。

8章~12章 Rails ツアー

Railsの設計、コードを見ていこうというお話なのですが、あまり理解できませんでした…。

読み返したときに、再度整理したいと思いました。

全体を通しての感想

メタプログラミングは賢くなるためのものではない。柔軟になるためのものである 。

上記の言葉の意味を真に理解できているかは分かりませんが、本書を読むことで自分の中のRubyの世界が広がったという感じがあります。

普段何気なく使っている「pputsprint」がなぜメソッド名だけで実行できるのか、「ブロックとは、selfとは何者なのか」ということを理解できました。

また、メタプログラミングを使った書き方を知ることで、自分のコードの幅が広がったように思います(チームでの開発ではあまり使ってはならないものだとは思いますが)。

自分が本書を読む前に目的として立てていた「Rubyをより理解する」という目的は十分に果たすことができましたが、一度読んだだけでは理解できなかったことが多いので、再度読み直したいと思いました。

『エンジニアのための時間管理術』を読みました

はじめに

研修中ではありますが、エンジニアとして業務に当たっていく中で「中々開発速度が上がらない」と思うようになりました。

純粋にコードを書くのが早くないということも要因なのですが、そもそもそれ以外の点で「時間の使い方や業務スケジュール、仕事の進め方がまずいのでは」と考え始めました。

そこで、「自分の時間管理・仕事の進め方」を見直したいと思い、本書を手に取りました。
早速実践できたこともあるので、以下に学んだことや感想をまとめたいと思います。

bookmeter.com

本書の章立て

本書は以下のような章立てで構成されていました。

第1章 タイムマネジメントの原則

第2章 集中と割り込み

第3章 ルーチン

第4章 サイクルシステム

第5章 サイクルシステム: 作業リストとスケジュール

第6章 サイクルシステム: カレンダーの管理

第7章 サイクルシステム: 人生の目標

第8章 優先順位

第9章 ストレスの管理

第10章 電子メールの管理

第11章 時間の浪費

第12章 文書化

第13章 自動化

各章ごとの感想

第1章 タイムマネジメントの原則

本書の指針が述べられている章でした。

そもそも、他の業種とエンジニアの時間管理方法が根本的に異なるそうです。
そのため、エンジニアならではのタイムマネジメントの原則があるということが述べられていました。

そのタイムマネジメントの原則は以下の6つでした。

  • タイムマネジメント情報を1つのDBにまとめる
  • 能力は必要な作業のために温存しておく
  • 日課を定め、それらに従う(コードライブラリを再利用し、無駄な作業は繰り返さない)
  • 習慣やモットーを養う
  • プロジェクトタイムの間は集中力を保つ
  • 日常生活の管理にも仕事で使用するのと同じツールを使用する

これ以降の章で詳しく説明されますが、その説明と合わせてなるほどと納得できる内容でした。

第2章 集中と割り込み

集中しやすい環境を作りや、仕事の進め方、割り込みへの対処が書かれた章でした。

私自身、業務に当たっていて「割り込み」というものを意識したことがなかったため、これは新しい発見でした。
そもそも、割り込みが頻繁に発生するような状況に置かれていないということもありますが、本書を読むことで自分の中の仕事に対するラベルに「割り込み」というラベルが追加された感じがあります。

本章では、割り込みへの対応は以下のような順序でやることと述べられていました。

  • 委任する
  • 記録する
  • 実行する

割り込みが頻発する状況に置かれたら、本章の内容を思い出して実践したいと考えました。

第3章 ルーチン

ルーチンは「何のために」・「どのように」作成しするのか。そもそも、「良いルーチンとは何か」ということについてまとめられていた章でした。

本章では、ルーチンとしては以下のように述べられていました。

「ルーチンとは、最初だけ考えて、後は考えないようにするためのもの」
「一度作成すれば、それについては脳のリソースを割かなくて良くなる」
ということが述べられておりました。

これについて、まさしくその通りだと実感しました。
私自身が脳のメモリが少ないので、色々なことに頭を使ってしまうと、あまり良い判断ができなくなってしまうということが多々あります。

本書で述べられている「仕事の手間が省け、決断を下す時間が短くなるもの」を見つけてルーチン化したいと思いました。
まずは業務に入った時にやっていることをルーチン化したいと思いました。

第4章 サイクルシステム

筆者が考案し、実践しているサイクルシステムについて、概要が説明されていた章でした。

そもそも、サイクルシステムとは、日々割り込みや、やるべきことが多い業務時間の中で「やるべき作業を見失わないよう」に考案されたということでした。

具体的な方法は以降の章で説明されていますが、作業リスト・今日のスケジュール・長期的な目標という3つのツールを使用していくというものでした。

第5章 サイクルシステム: 作業リストとスケジュール

サイクルシステムの重要なツールである、作業リストとスケジュールについてまとめられた章でした。

具体的な手順としては、出社したら以下のような流れが紹介されていました。

  1. やるべき作業を書き出す。この時、所要時間も書いておきます。
  2. 1で作成された「作業リスト」の1つ1つの作業に対して優先順位をつけます。
  3. 優先順位と所要時間を勘案してスケジュールを立てます。
  4. 作業が終わったものから横線を引いて、その作業を消していきます。
  5. 就業時間の30分前に残っている作業をピックアップして、それに対してどのような対応をするのかを決めます。

※ ここで、割り込みについては「この時間は割り込みに当てる」という時間を作っておき、その中で対応するようにします。

上記のようなことが、サイクルシステム(作業リストとスケジュール)を用いた時間管理術でした。

最初見た時に、一見目新しいものはないように見えました。
しかし、後述しますが、私は実際にやってみて「良い感じかもしれない」という感覚がありました。

第6章 サイクルシステム: カレンダーの管理

仕事とプライベートのカレンダーを1つにまとめようということが述べられていた章でした。

私もこれは実践したいと思ったのですが、イマイチGoogleカレンダーの複数人共有に慣れずにおります。
そのため、プライベートの予定が会社の人にバレてしまうのではないかと恐れて、実践できないでいます…。

第7章 サイクルシステム: 人生の目標

2年後、5年後、10年後、引退後などなど、長期的な目線で見た時の目標を持って、それに向かえるようにしようと章でした。

私はまだまだぼんやりしているので、もう少し業務に慣れてきて、エンジニアがどのような職業なのかということが分かり始めたら考えて文字にしたいです。

第8章 優先順位

タスクやプロジェクトに対して、どのようにして優先順位をつけていくのかということがまとめられた章でした。

本章の内容としては、顧客が優先する順位を割り振ること。そして、タスクやプロジェクトを達成した時の効果(大・小)と困難さ(難・易)の2つの軸で見た時に効果が大きく・易しいモノからこなしていくというものでした。

しかし、上記のようなタスクはほとんどないので、その場合は効果が大きく、難しいモノをやっていく方が良いと述べられていました。

この章は、顧客の方を意識する機会が私にはまだないので、あまり実感を持って理解できませんでした。
「そういうものなのか」と頭に入れておきたいと思いました。

第9章 ストレスの管理

この章では、休暇の取り方などが記載されている点でした。本書の独創的な点だと思い、興味深く読んでおりました。

確かに、本章のように休暇をとるまでにやるべきことが明文化されていることは、気兼ねなく休暇を過ごす上で大切なことだと感じました。

第10章 電子メールの管理

筆者は受信トレイを空にすることを目指していて、メールを「読まずに削除するもの」・「読んで処理するもの」・「読んで実行して削除するもの」と分けているというお話でした。

こちらに関して、私はメールを使う機会がそこまで多くなかったのですが「そのようなメール管理方法があるんだなー」と頭の隅に置いておこうと思いました。

第11章 時間の浪費

費やした時間に対して、利益率が低いものは総じて時間の浪費になるというお話でした。

私も本章で述べられていることをやって時間を浪費していたので、気をつけたいところです。

第12章 文書化

何をドキュメントとして残して、何を残さないかということがまとめられていた章でした。

本章では「顧客が読んで解決するための文書」と「社内の作業に役立つ文書」を文書化するべきだと述べられていました。

私はなんでもドキュメント化しちゃえば良いのではないかとも思っていたのですが、冷静に考えてみるとドキュメントを作成するのにもコストがかかり、それをメンテナンスすることにもコストがかかると気付きました。
だからこそ、何を残して何を残さないのかの選択が必要なのだろうと考えました。

第13章 自動化

エンジニアのやる作業は以下の4つの作業に分類されるようです。

  1. 一度だけ行う単純な作業
  2. 一度だけ行う難しい作業
  3. 頻繁に行う単純な作業
  4. 頻繁に行う難しい作業

上記の作業のうち、2と3の作業を自動化したら良いというお話でした。
こちらは、まだどのような作業があるのかということが掴めないでいるので、どのような作業があるかが掴めてきたらやってみたいと思いました。

全体を通しての感想

総じて、自分の時間管理が見直せて勉強になりました。

特に、「サイクルシステム」が自分の中で役に立ったという感じがあります。

こちらは以下のように実際に実践してみました。
まず、業務に入って10分くらいでやるべきことを洗い出し、優先順位と作業見積もり時間をつけて、
会議などのスケジュールと合わせて、1日のスケジュールを立て、それを実行していくという流れです。

実践してみて、自分の作業の進捗が分かって良いという感じです。
「スケジュール通りに進んでいるのか、進んでいないのか。進んでいないとしたら、どこの作業で時間がかかっているのか」が分かって、それに対して対応がしやすくなったと感じております。

Sendagaya.rb#328 参加レポート

はじめに

先週に引き続き、今週もSenadagaya.rbに参加させていただきました。

今回は短くはなりますが、参加した感想などをまとめます。

sendagayarb.doorkeeper.jp

内容

今回は、自己紹介 → Ruby Kaigi Takeoutの話題 → りんごジュース抽選プログラムをみんなで書こうという内容でした。

りんごジュース抽選プログラムを書こう

りんごジュース抽選プログラムとは、どういうことかと言いますと…

Ruby Kaigi運営の方々から地域のコミュニティに対してりんごジュースが送られるようです。
そこで、Sendagaya.rbでは参加しているメンバーから抽選して、当たった方がりんごジュースをもらえるようにしようというお話になっていました。

その抽選プログラムをみんなで書いて、見せ合おうとう流れです。

実際には、Array#sampleでできますが、「ワクワクとドキドキ感が得られるプログラム」がお題になりました。

ちなみに自分は以下のようなプログラムを書きました。
sampleの結果を、時間を置いて表示しているだけなんですけどね…。

people = %w(a b c d)

class DrawingMachine
  def draw(array)
    @bingo_man = array.sample
    array.delete(@bingo_man)
    array.each do |el|
      sleep 1
      puts "#{el}さん、残念はずれでした"
    end
    sleep 1
    puts "#{@bingo_man}さん おめでとうございます。当選しました" 
  end
end
drawing = DrawingMachine.new
drawing.draw(people)

命名や処理について、納得いかない部分が多いのですが、時間がなかったということでお目こぼしをお願いしますmm

皆さんのアイディア

皆さんのプログラムを見せてもらったのですが、とても面白かったし、笑いました。

「抽選終了時間がいつになるか分からないプログラム」や、「任意の数字を押すと参加者が脱落するプログラム」などがあり、アイディアが素晴らしいと思いました。

また、自分と同じような出力結果でもスマートに処理されているプログラムもあり、自分が考えつかなかった考えの一端を知れてとても面白かったです。

シンプルな抽選プログラムであっても、新しい発見と笑いに満ちていました!!

感想

前回も書きましたが、やはり見知ったコミュニティに参加すると楽しいですね。
MPが回復する感じがあります!!

『パーフェクト Ruby on Rails【増補改訂版】』を読了しました

はじめに

Railsプログラマーとして生を受けてから早2ヶ月。
まだ研修期間ではありますが、日々「私はRailsのこと何も分からない」ということを思い知ります。

「Railsの基本的なところはもちろん復習したい」、そして「Railsガイドよりも現場に寄った内容も学びたい」と思い、本書を手に取りました。

本書を読んで学んだことと感想をまとめたいと思います。

本書の章立て

本書は以下のような章立てで構成されていました。

第1章 Ruby on Railsの概要

第2章 Ruby on RailsとMVC

第3章 押さえておきたいRailsの基本機能

第4章 フロントエンドの開発手法

第5章 Rails標準の機能を活用して素早く機能実装する

第6章 Railsアプリケーション開発

第7章 Railsアプリケーションのテスト

第8章 Railsアプリケーション拡張

第9章 コードの品質を上げる

第10章 コンテナを利用したRailsアプリケーションの運用

第11章 複雑なドメインを表現する

第12章 複雑なユースケースを実現する

第13章 複雑なデータ操作を実現する

各章ごとの感想

第1章 Ruby on Railsの概要

バージョンを指定してインストールすることや、rake statsなどは初めて知りました。

第2章 Ruby on RailsとMVC

第1章に引き続き、初めて知ったことが多かったです(variantstime_ago_in_wordsnumber_with_delimiterなど)。

特にtime_ago_in_wordsは使いどころが多そうだと思いました。知れて良かったです。

第3章 押さえておきたいRailsの基本機能

正直なところ、RackについてはアプリケーションサーバーとRailsの間に立ってリクエストとレスポンスをRailsが扱いやすいように変換してくれるモノだという程度の理解しかしてませんでした。

本章では「Rackにより何が解決されたのか」・「実際にRackミドルウェアはどのように作るのか」ということがまとめられていて勉強になりました。

また、Early HintsやCSPなどは本書で初めて知りました。

Early Hintsはレスポンスを送る前にヒントを出して、アセットのダウンロードを早めにしてもらうことでページ描画までの時間を短縮するための方法。
CSPは安全にJavaScriptを実行するための仕組み。

と、それぞれ理解しました。

第4章 フロントエンドの開発手法

stimulusのことを知らなかったのですが、使い方が丁寧に書かれており分かりやすかったです。

ただ、実際にstimulusを用いてコードを書けるようにはなっていないため、stimulusを使う時になったら改めて動かしてみて理解していきたいです。

第5章 Rails標準の機能を活用して素早く機能実装する

Active Job・Active Storage・Action Miler・Action Mailbox・Action TextなどのRailsの機能の使い方が紹介されている章でした。

特に参考になったのは、Action Mailboxについての説明です。
Railsガイドにあまり詳しく載ってなかったような気がします。そのため、使われ方があまりイメージできていませんでした。

本章では、実際にどのように書くのかが記載されており、Action Mailboxの使い方・実装がイメージできました。

第6章 Railsアプリケーション開発

Railsでイベント管理アプリを作るならどのように作っていくかということが、具体的なコードと共に説明されていてる章でした。

特に印象に残ったのは、本章の最後に書かれていた以下の内容です。

その機能を学ぶ際は、単純に丸暗記するのではなく「なぜこのような機能があるのか」を積極的に調べるようにしましょう。Railsが提供している機能の多くは、Webアプリケーション開発全般で使えるベストプラクティスです。

ウェブで検索したやり方を深く考えずにそのまま使うようでは経験値は増えにくいです。大事なのは常に複数の選択肢があることを念頭に置いて、このやり方がベストなのか?なぜこの実装にするのか?を考えることです。

P344より

度々、上記のような「機能の背景」を理解せずにスッ飛ばしている時があるので、折に触れてこの心構えを思い出していきたいです。

第7章 Railsアプリケーションのテスト

system testでできることについて、本章では以下のようにまとめられていました。

  • ブラウザ上でJavaScriptの動作まで含めて確認
  • フォームへ値を入力して登録する時の動作を確認
  • 失敗した時の画面スクリーンショットを撮る

私は、なんでもかんでもテストしたくなってシステムテストを書きすぎてしまいます。
そのたえ、上記のようなsystem testでできること、model testでできることを意識して書きたいと思いました。

第8章 Railsアプリケーション拡張

この章は、外部ライブラリを使ってRailsの機能を拡張していくという内容でした。

内容はもちろん勉強になりましたが、コラムとしてgemの選び方についても触れられているのが有り難かったです。
自分はどのような基準でgemを使ったら良いかということが、まだ分からなかったので、それがまとめられていたのは助かりました。

第9章 コードの品質を上げる

Railsを用いた開発現場では実際にどのようなgemやツールが使われているのかが、まとめられている章でした。

私はまだ現場での開発経験がほとんどないので、「本章で紹介されているgemやツールを知っておけば良いのかな」という心構えができました。

第10章 コンテナを利用したRailsアプリケーションの運用

名前こそ多く耳にするDockerですが、触ったことがありませんでした。
本章を読むことで、Dockerがどのように使われているのか、どのように設定を書くのかということの一端を知ることができて良かったです。

Dockerとは、スクリプトを実行していくことで環境を構築していくツールだと理解しました。
しかし、触ってみないと分からないので必要となったときに改めて学びたいです。

第11章 複雑なドメインを表現する

複雑なドメインに対応するために、値に関連するロジックをまとめた値オブジェクトを作ったり、サービスオブジェクトを作ったりすることが述べられていた章でした。

サービスオブジェクトとは、複数のオブジェクトを組み合わせたロジックを実装するための状態を持たないクラスと理解しました。
言葉としては聞いたことがあったのですが、どのようなものかはイマイチ理解していなかったので、勉強になりました。

第12章 複雑なユースケースを実現する

複雑なユースケースに対応するために、フォームオブジェクトやプレゼンターを使うという内容でした。

この章の内容は、私が実際に直面した問題だったので実感を伴って理解できた感じがあります。

第13章 複雑なデータ操作を実現する

複雑でコード全体に散らばっているロジックを、concernを使うことでまとめるという内容でした。

正直なところ、concernについては「何となくこういうモノか」というのは分かったのですが、具体的なことは理解できませんでした。
これから実際にコードを書く中で理解していけたらと思います。

全体的な感想

基本的なことから実務的なところまで幅広くまとめられた本で、大変勉強になりました。
基本的なところであっても実は知らなかったということが多く、良い復習になりました。

特に、10~13章の内容が自分にとってとても役に立ちました。

現実の複雑な問題にどのようにアプローチしていけば良いのか、そのためにどのようなRailsの機能を使って、どのようにコードを書いていけば良いのかということを知ることができました。

ただ、10~13章の内容は字面では理解できましたが実感を伴って理解できたとは言えません。
サービスオブジェクトやconcernなどが、実際に必要となった時に読み返したいと思いました。

Sendagaya.rb#321 参加レポート

はじめに

以前は毎週参加していたSendagaya.rbですが、新生活が始まり心身の余裕がなく、ここ1・2ヶ月は参加しておりませんでした。
しかし、新生活や社内の研修にも少しずつ慣れてきて、心身の余裕ができ始めたので今回参加させていただきました。 sendagayarb.doorkeeper.jp

参加レポートとして話題に挙がったことと、自分の感想をまとめます。

話された内容

参加者の方々が持ち寄ったテーマについてみんなで意見を交換し合うという感じです。
話された内容をピックアップして以下に書きます。

JavaScriptのreduceについて

@tkawaさんから以下の記事を紹介していただきました。 qiita.com

私はそもそも「ループの回数が分からなくて困るケース」ってあるのかなぁと疑問でした。
記事を読んでも、その疑問は拭えず…。

一方で、やはりデバッグのときに処理を差し込めないから、少しだけデバッグが厄介になるかもしれないという意見も上がりました。

JavaScriptの怖い話

@sanfrecce_osakaさんの体験談。

これはその場に衝撃が走った内容でした。

実は…forEachは、emptyをスキップします

つまりどういうことかというと、以下のように配列を定義するとemptyというモノが含まれる配列が作成されます(私はemptyの存在も初めて知りました)。

この時、emptyを含む配列array1に対してforEachを実行すると、emptyはスキップされて、2回しかループが回らないのです…。

let array1 = ['a', ,'c'];

console.log(array1);
arrya1.forEach(element => console.log(element));

//=> ["a", empty, "c"]
//=> "a"
//=> "c"

さらに、怖いことにemptyを含む配列のlengthemptyもカウントされてしまいます…。

let array1 = ['a', ,'c'];
console.log(array1.length);

//=> 3

lengthを信じられないなんて…まあ、怖い…。

感想

久しぶりの参加でしたが、とても楽しかったです。
やはり何回も参加させていただいているコミュニティだと気心知れた感じがあっていいですね。

話題に上がった内容も興味深いものでした。
特にJavaScriptのforEachの話は、知らなかったらハマり倒していたんだろうと背筋がゾッとしました。

また定期的に参加させていただきたいと思います。

Railsガイド読みました

はじめに

私は今勤めている会社では研修期間中でして、シンプルなRailsアプリを開発してレビューをいただくという日々を送っています。
そのレビューをいただく中で、Railsについて「全く知らないことが多い」と感じました。
それはメソッドレベルの話だけではなく、「Railsではこの書き方が推奨されている」などということも含めてです。

そのような「全く知らないを少なくしたい」と思い、今回Railsガイド(日本語訳版)を読みました。

railsguides.jp

皆さんご存知の通りRailsガイドはものすごい量なので、全てを理解しようとはせずに以下の記事で紹介されているインデックスを作るという読み方を心がけました。
今は理解できないかも知れないけど、必要な時に参照できるくらいには頭に入れておこうという感じです。

blog.jnito.com

Railsガイドを読むということは、Railsプログラマーとしては当然のことで、わざわざブログに書くことではないかもしれません。
しかし、自分の中ではなんとか成し遂げたという感じがあるので、この気持ちを残しておきたいと思いこの記事を書きました。

ちなみに、少し前にDashでRailsガイドを検索したいと思いdocset欲しさに電子書籍版を購入していたので、今回は電子書籍版を読み進めました。

読んでみた感想

流石に全ての章に対して感想を書いていては埒があかないので特に勉強になった部分をピックアップして感想を書いていきたいと思います。

特に勉強になったところ

Active Record クエリインターフェイス

私はfindwhereくらいしか覚えていなかったのですが、find_eachrewheredefault_scopepluckなど知らないメソッドや機能を知ることができて良かったです。
また、楽観的ロックと悲観的ロックについては曖昧だったため、その部分にも言及されていて改めて理解できました。

正直な話、データベースへのアクセス・検索についてはあまり理解していなかったところでした。
しかし、とても重要なところだと思うのでこれを機にある程度学ぶことができて良かったです。

Action View フォームヘルパー

いつもViewを書いていて「こういうことをしたいんだけど、どんなヘルパーがあるかなぁ」と、あたりをつけることができずに都度調べて実装するという行き当たりばったりな感じがありました。
しかし、これを機にどんなヘルパーがあるのかが分かり、ヘルパーを調べるときのあたりをつけやすくなったと思います。

また、自分でFormBuilderクラスを定義し、その中でtext_fieldなどを再定義することで自分が使いやすいようにヘルパーをカスタマイズするということをやって良いのだと新しい発見がありました。

Railsセキュリティガイド

セキュリティ関連については本当に暗くて、SQLインジェクション・クロスサイトスクリプティングがなんとなく分かるというレベルでした。
ここでは、様々な攻撃方法があり、それに対してRailsがどのような対策をとっていて開発者はどのようなことをすれば良いのかということが明示されていてとても有り難かったです。

セキュリティについて、ほぼ意識せずともRailsがやってくれていると知り、改めて素晴らしいと感じました。
セキュリティ関連については、まだまだ知識がないのですが、少しは理解できるようになったかなという感じです。

全体的な感想

今回のRailsガイドを読む目的であった「Railsについて全く知らないことを少なくする」ことはある程度達成できたという感じがします。
大まかにRailsでできることがなんとなく理解でき、それらについて頭の中でインデックスを作ることができたような感じがしています。

一方で、理解できなかった部分も多いです。
zeitwerk・初期化プロセス・スレッドなどは理解できず、そういった部分に関しては本当に目を通すだけという感じで読み進めました。

ただ、そのような部分であっても必要になった時に参照できるくらいのインデックスを頭の中に作ることはできたと思います。

そのため、理解できた部分・理解できなかった部分共に、都度該当する部分を参照し直してRailsに対する理解を深めていければと思います。

最後に

今回はまとまった時間が取れたのでRailsガイドを読んでみましたが、総じてRailsでどんなことができるのかということが掴めて良かったです。

しかし、「Railsでこういうことができる」という知識があっても綺麗なコードを書けるようにはならないと思うので、コードを書く力は今後レビューを受けて徐々につけていきたいと思っています。

次は『パーフェクトRails』やAPIリファレンス を読もうかなーと思っています。

ActionCableの概要をまとめてみました

はじめに

少し前の記事で、自分が担当したActionCableを用いた機能実装について解説しました。

docs.koheitakahashi.com

上記の記事を書いているうちに、実装を担当することになった当初の気持ちが蘇ってきました。

  • 「Railsガイド読んでも全然分からない…」
  • 「WebSocketの仕様書を読んでも全然分からない…」
  • 「DHHのデモを見ても、コードを見ても全然分からない…」

と、「ナニモワカラナイ」という状態でした。

そこで、上記のような「ActionCableナニモワカラナイ」という方に向けて自分なりにActionCableの概要をまとめました。
ActionCableを理解するのに少しでも役に立てば幸いです。

また、理解や記述が間違っているところなどがあれば教えていただけるととても有り難いです。

そもそもActionCableとは

RailsでWebSocket通信を実現するためのフレームワークのことです。
RailsとJavaScriptの垣根をあまり感じることなく処理を記述できるのが素晴らしいところだと思っています。

具体的には、Rails側(channel.rb)で定義したメソッドをJavaScript側で呼び出すことができます(CRUDやbroadcastの処理など)。

WebSocketとは

生まれた背景

WebSocketとは、双方向通信を実現するために開発された通信規格です。

HTTPプロトコルで、双方向通信を行うためには一度確立したHTTPコネクションを開いたままにして、定期的にリクエストを送るということが必要でした。

しかし、その方法は本来想定されているHTTPプロトコルの使い方とは異なる、いわゆる裏技的なものでした。

そのため、双方向通信を行うためのプロトコルが開発されたという流れのようです。
HTTP通信で双方向通信を行おうとするよりも低コストだと言われています。

WebSocketコネクション確立までの流れ

WebSocketによる通信を行う前に一度HTTP通信を行い、それが正常に処理されてからWebSocket通信に移行します。このHTTP通信をハンドシェイクと呼びます。

もう少し具体的にハンドシェイクを見ていきます。
まず、ブラウザから、サーバーに以下のようなリクエストを送ります。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

(https://triple-underscore.github.io/RFC6455-ja.html より引用)

そして、サーバーは以下のようなレスポンスを返します。
ここで、ステータスコードが101以外なら、WebSocketに移行しません。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

上記のハンドシェイクが正常に処理されたら、以降のデータのやりとりはWebSocketプロトコル上で行われるという流れになります。

以下はハンドシェイクのイメージ図です。 Image from Gyazo

ActionCableが実現しているWebSocket通信の世界観

ハンドシェイクが正常に処理されて、WebSocketプロトコルに移行した後のデータのやりとりを見ていきます。

ActionCable は pub/sub モデルというメッセージ送受信のモデルを採用しており、そのモデルに則ってデータがやりとりされる形になります。 pub/sub モデルの主要な概念は以下の3つです。

  • サーバーから送られるデータ
  • クライアントであるconsumer
  • 実際にデータがやりとりされる空間であるchannel

Image from Gyazo

ここで、consumerがchannelと繋がることをsubscribeといいます。
subscribeしたら、consumerはsubscriberと呼ばれることとなります。

このsubscriberに、サーバーがデータを送ることをbroadcastと呼びます(正確にはpubsubリンクと呼ばれるものを送っているようですが、私の調査能力ではその詳細を突き止めることができませんでした)。

Image from Gyazo

このようにconsumerがchannelをsubscribeして、そのsubscriberにデータがbroadcastされることで、データがクライアントに送られるという流れになります。

具体的にどのように書くのか

上記にデータのやりとりの大まかな流れを説明しました。
ここからは、上記のようなことをどのようにコードで書いていけば良いのかを説明します。

以下に紹介しているコードの例はRailsガイドや前回の私の記事を参考に記述しています。
そのまま書いて動くコードになるわけではないのでご了承ください。

ハンドシェイクを送る

まず、クライアント側でconsumerを設定する必要があります。

rails newした後のプロジェクトには、app/javascript/channels/consumer.jsに以下のように記述されていると思います。
consumerを特に設定する必要がない場合はここに記述を追加する必要はありません。

// app/javascript/channels/consumer.js
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `rails generate channel` command.

import { createConsumer } from "@rails/actioncable"

export default createConsumer()

その後、アプリケーションの好きな場所で以下のように記述することでsubscriptionを確立しようとします。
今回は、app/javascript/channels/timelines_channel.jsというファイルがあると仮定して、そこに処理を書くならというイメージで説明しています。

subscriptionを確立しようとすることで、初めてハンドシェイクが送られます。

// app/javascript/channels/timelines_channel.js
import consumer from "./consumer"
consumer.subscriptions.create({ channel: "TimelinesChannel" })

WebSocketコネクションを確立する

app/channels/application_cable/connection.rbに処理を記述することで、ハンドシェイクが送られた後にWebSocketコネクションを確立するのか・しないのかを判断させられます。

以下のRailsガイドの例だと、Cookieに保存されているuser_idがDBに保存されている場合はWebSocketコネクションを確立して、それ以外の時は確立しないようにしているのが分かります。

# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private
      def find_verified_user
        if verified_user = User.find_by(id: cookies.encrypted[:user_id])
          verified_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

Railsガイド ActionCableの章 から引用

subscribeしたときの処理

connection.rbにより、WebSocketコネクションを確立するか否かの判断がされ、無事コネクションが確立された後、指定したchannelをsubscribeすることとなります。

ここで、channelの処理を担うapp/channels/timelines_channel.rbが存在と仮定して説明します。

以下のコードのように、subscribeメソッドを定義すると、TimelinesChannelがsubscribeされたときの処理を記述できます。

例えば、以下ではTimelinesChannelがsubscribeされると、過去の分報を10件broadcastすることになります。
また、このstream_fromはどのような意味かというと、timelines_channelのsubscriberにbroadcastしてデータが送れるように道筋を示しているようなイメージです。

Railsガイドによると、

ブロードキャストでパブリッシュするコンテンツをサブスクライバ側にルーティングする機能をチャネルに提供します。 https://railsguides.jp/action_cable_overview.html#%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0 より

ということを行っているようです。

# app/channels/timelines_channel.rb
class TimelinesChannel < ApplicationCable::Channel
  def subscribed
    stream_from "timelines_channel"
    ActionCable.server.broadcast "timelines_channel", timeline: Timeline.take(10) }
  end
end

broadcastする

上記でも触れましたが、以下のように記述することで任意のchannelのsubscriberにデータをbroadcastできます。

以下は、createしたtimelinetimelines_channelのsubscriberにbroadcastしています。

timeline = Timeline.create(title: "分報だよ")
ActionCable.server.broadcast "timelines_channel", timeline: timeline

broadcastされたデータを受け取る

最後にbroadcastされたデータはフロントエンド側で、以下のようにcreateしたchannelの中で受け取ることができます。

以下は、受け取ったdataをコンソールログに表示するという処理です。

// app/javascript/channels/timelines_channel.js
import consumer from "./consumer"
consumer.subscriptions.create({ channel: "TimelinesChannel" }, 
    received(data) {
        console.log(data)
      }
)

まとめ

上記の流れをまとめると以下のようになります。

  1. consumerを設定(JS側)
  2. subscriptionを確立(JS側)
  3. subscriptionが確立されようとしたときにハンドシェイクが送られる
  4. リクエストを受け取ってWebSocketコネクションを確立するかを判断(Rails側)
  5. WebSocketコネクションが確立されたら、subscriptionを作成
  6. subscribeされた時にどのような処理を行うかを記述(Rails側)
  7. データをbroadcastする処理を記述(Rails側)
  8. broadcastされたデータを受け取る処理を記述(JS側)

このように設定や処理を記述することにより、サーバー・ブラウザ間でWebSocket通信が行われます。

この記事を通して、ActionCableが実現しているWebSocket通信の概要が少しで伝わったなら幸いです。

また、自分は上記のように理解してこの記事を書きましたが、理解や記述が間違っているところなどがあれば教えていただけると大変嬉しいです。

参考にさせていただいた資料

追記

  • 2020.11.08 WebSocket と pub/sub モデルの概念を混同して説明していたため修正。

ノートアプリを探して、RubyMineに行き着きました

はじめに

自分はなんでもメモに残しておきたいと思ってしまいまして、自分の日記や、技術的なメモ、ブログの下書きなどで頻繁にメモを作成します。

そのメモをいい感じにとるため、何個かノートアプリを渡り歩いてきました。

ノートアプリを渡り歩いてきて、最近「RubyMineで良いのでは?」とRubyMineに落ち着いてきた感じがあるので、ここらでノートアプリの変遷を振り返ってみたいと思います。

ノートアプリの変遷

VScode

VSNotes - Visual Studio Marketplace

最初の頃はVScodeをコードエディタとして使っており、上記のVSnotesというVScodeのプラグインを使ってメモをとっていました。

特に不満はなかったのですが、コードエディタをRubyMineに乗り換えたこともあり、VScodeとRubyMine の両方を開いておくことが、「統一感がなくて嫌だなぁ」と思っておりました。

また、iPadにApple Pencilを使って手書きでメモをとることも多くなったため、手書きのメモもmarkdownで書いたメモも一緒に管理したいと思うようになり、他のアプリを探し始めました。

Evernote

Evernote

VScodeの次に行き着いたのがEvernoteでした。

何でもノートに残しておけると噂のEvernote。
噂に違わず、Webクリップや手書きのメモも保存できて素晴らしいと思いました。

しかし、手書きメモが付箋のような扱いで、あまり操作感が気に入りませんでした。

また、vimキーバインドを使うためには拡張アプリのようなものを使わなければなりませんでした(marcociaみたいな名前の拡張だったと思うのですが、探せませんでした)。

そのアプリを通して、Evernote内のノートを作成するような感じなのですが、欠点としてそのアプリを通して作成したノートはそのアプリからしか編集できませんでした。
つまり、Evernote本体からそのノートを編集できなかったため、使い勝手が悪いと感じて使うのを辞めてしまいました。

inkdrop

Inkdrop - Note-taking App with Robust Markdown Editor | Inkdrop

プログラマーのためのノートアプリと噂のinkdrop。
こちらも素晴らしいノートアプリだと思いました。

vimキーバインドを使うことができて、シンプルな操作感がすごい良かったです。

また、他の人にノートを共有したいという時でも、発行されるURLを共有すればすぐに他の人が見れるのでとても便利でした。

ただ、inkdropを使っている時に、そもそも手書きのメモはjamboardに書いてそのリンクをinkdrop上のノートに貼れば良いのではと気づきました。

そのため、あまり不満点はなく、長く使わせていただいていたのですが、最近になってAlfredを導入したことがきっかけで辞めてしまいました。

Alfredというアプリは、Mac内のファイルをすぐに検索できるのですが(その他にも色々できますが)、inkdrop内のノートは検索できないということで、他の方法を考えるようになりました。

RubyMine(←イマココ)

3ヶ月以上inkdropを使ってきたのですが、「そもそもRubyMineで良くないか?」と思うようになりました。

そして、作成したmarkdownファイルはicloudで管理すればスマホでもiPadでも見れるのではないかと気付きました。

重いと言われているRubyMineですが、実際にコードを書くためと、メモをとるための2つのウィンドウでRubyMineを開いていますが、今のところそこまでの重さを感じてはいません。

markdownプレビュー機能も素晴らしく、今のところとてもいい感じで使っています。

まとめ

色々とノートアプリを渡り歩いてきましたが、最終的にRubyMineに落ち着いたというお話でした。

ただ、今のところ重さを感じてないというだけで、もっと巨大なプロジェクトを扱うようになれば重くなるのかなぁという懸念もありますが当分はRubyMineで戦っていけそうです。

重さが気になり出したら、また他の方法を模索しようかなという感じです。

『宝石の国』読みましたー

はじめに

唐突ですが、『宝石の国』読みました。
知人に「是非読んでみて」とおすすめされて、「そこまで推すなら…」ということで昨日買って読んでみました。

それが、すごく面白くて今日の午前中で一気読みしてしまいました。

とても良い作品に出会えたと思い、この衝動をどこかにぶつけたいと思ったため、感想を書いみたという次第です。
多少なりともネタバレを含んでいますのでご留意ください。

読んでみて

序盤

1・2巻を読んだ時は、「絵本みたいな雰囲気の漫画だなぁ」と感じました。
この時点では、そこまで引き込まれるような感じはなく、宝石達の掛け合いが中心の日常系の漫画だと思ってました。

漫画の雰囲気が嫌いではなかったものの、この時点ではキャラ同士の掛け合いにおいて、話していることの意味やノリを理解できませんでした。
会話の置いてきぼりをくらっているみたいな感じがありました。

そして、戦闘シーンでは独特な絵柄のせいか、何をやっているのか・何が起こっているのか分かりにくいと感じていました。

中盤

読み進めていくと、主要キャラがどのようなキャラなのかということが分かり始めてきたためか、キャラ同士の掛け合いが理解できるようになった感じがありました。

作品に慣れてきたからか、戦闘シーンでも上記のような分かりづらさをあまり感じなくなりました。

話の展開的には、フォスが強くなっていく・性格が変わっていくというところで、「今後どのようにフォスが変わっていくのだろう」というところがすごく気になっていきました。

また、フォスが謎に迫っていくことで、私自身そこまで気に留めていなかった「宝石の国」の世界の謎が気になってきました。

最新巻らへん

すっかり世界の謎や今後の展開が気になって仕方がなくなってしまい、読むのを止めることができませんでした。

フォスの考えが他の宝石達に届かず、だんだんとすれ違っていく感じがあって息苦しさを感じました。
そして、月人と他の宝石達との間で板挟みになっているという構図も辛いものがありました。

そのような多少の苦しさはあるものの、描写の仕方によるものなのか、都度都度和やかなシーンを挟んでいるからなのか、展開的には重苦しいものなのですが、全体の雰囲気としてはそこまで重苦しさがあるわけではありませんでした。

最新巻の後、フォスはどうなってしまうのか気になってしまいますね…。

総じて…

総じて、とても面白い作品だと思いました。
最初はほのぼの日常系かと思っていたんですが、実はセカイ系でしたという感じで、完全に引き込まれました。

絵柄と世界観がマッチしているからか、全体的に絵本みたいな雰囲気がとてもいい感じだと思いました。 展開もネガティブな展開のはずですが、淡々と和やかに描かれており、そこまで重苦しい感じはなく、読み味としてはさっぱりとしたものでした。

すごくおすすめの本なので、気になる方はぜひ一読下さい!!

執筆後記

最近、私が卒業したフィヨルドブートキャンプの受講生のkanazawaさんのブログと、uetennisさんのブログ を拝見して、ブログを書きたいという欲が高まりました。

kanazawaさんのブログを読んで、「自分のレベルアップのためにも、技術的なことをもっとブログに書いてアウトプットしていきたい」という気持ちになりました。

uetennisさんのブログを読んで、「ブログで何かを発信することは楽しいのかもしれない」「自分の日常生活のことも発信していきたい」という気持ちになりました。

そのため、今後は自分のレベルアップを目指して技術的なことをこのブログに書いていきたいのはもちろんのこと、それに加えて、趣味として今回のように自分の日常のことも書いていきたいと思ったのでした。

Ruby Silverを受験しました

はじめに

この度Ruby Silverを受験しまして、なんとか合格できました。

今はプログラマーとして試用期間中の身なのですが、その期間内にRuby Silverの取得が求められていたため受験させていただいたという運びです。

社内の先輩や同期の方に勉強法から心構えまで色々と教えていただき、なんとか合格できたということで、受験してどうだったのかということを感想を中心に書いていきます。

受験までにやったこと

勉強期間としては1ヶ月ちょっとくらいです。会社の先輩方に教えていただき、以下のようなことをやっていました。

上記の問題を1日50問ほど解き、解説を読む、公式リファレンスを読むということをやっていました。

問題を解いたら、その記録を以下のような形式で残しておきました。試験前日に自分が間違えやすい問題を見直せますし、徐々に点数が上がっていることが把握できるのでモチベーションが保たれるという効果もあると思っています。

## 20200812 RExを解く
- 結果 80 / 100
### 自信がなかった問題
~~~~~
### 間違った問題
~~~~~(問題番号や、どんな問題だったかを思い出せるくらいのメモと、解説を読んで、分かったことを一言添えて)

上記の他には、ネット上にある先人達の「Ruby Silver合格紀」を読んで、出題されそうな問題や、間違えそうな問題を把握するようにしていました。

このようなことを1ヶ月くらい続けていって、コンスタントに90点以上は取れるようになってきたため、満を持して受験しました。

苦手分野(正規表現)の勉強について

私は正規表現を避けて生きてきた節がありまして、とても苦手意識を持っていました。
全く覚えられそうになかったのですが、これを機にある程度覚えようと思いまして、伊藤さんの以下のシリーズの記事を一通り拝読しました。

初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」 - Qiita

一通り拝読してから問題を解いていくと、簡単な正規表現なら分かるようになり、とても良い記事だと思いました。

いざ受験

実際に受験してみると想像以上に分からない問題が多くとても焦りました…。
50問中20問くらいが分からない問題に見えてしまい、「終わった…」と天を仰ぎました。

落ち込みながら、試験に落ちた言い訳を考えていたのですが、落ち着いて見ると「解けそうだぞ」と感じる問題が多いことに気付きました。
そのような問題をなんとか解答でき、最終的には10問くらいは自信がないor分からないけど、後は大丈夫だろうという感じで解答を終了しました。

結果は92点でなんとか合格できました。

受験してみての感想

Rubyを勉強し始めて1年くらいになりますが、自分がいかに雰囲気でRubyを書いていたのかを思い知りました。
お恥ずかしい話、最初に上記のRuby Silverの合格教本の問題を解いた時は3割ほどしか正解できず落ち込みました。

しかし、今回の機会を通じてRubyの基本的な知識を把握できたのではないかと思っています。
加えて、コードの書き方も少し変わったように思います。
具体的には%w%i記法などを使うようになりました。

上述の苦手だった正規表現も少しだけ分かるようになり、「正規表現を使った処理を書いてみようかな」と思えるようになりました。

総じて、今回の受験勉強は私にとっては有意義だったものだと思います。

とはいえ、基本的な知識・文法が備わっているということは綺麗なコードを書けることとイコールではないと思います。
正直なところ、コードを書いて実装するという力はまだまだペーペーなので、その力を伸ばせるように精進していきたいです。