渡り鳥の旅路

元半導体系エンジニア、今Webエンジニアの雑記

軽めのgemをコードリーディングしてみた w/ wataridori

はじめに

この記事で紹介されているgemにとてもても親近感を覚えたので、コードリーディングの練習としてcommit logを最初から読んでみました。

tech.misoca.jp

最近esaの記事移行を試したり、API書いたりしていて、そのあたりの所作を学びたいというのがモチベーションです。

メモ

メモはコミット順に沿っています。

gemspecの記述

gemで使いたいgemの情報はGemfileでなく.gemspecに書く。

add_dependency "hoge", "0.0.1"

https://github.com/misoca/wataridori/commit/41cf71715e77acf3223cf4e0a9771c5440898150#diff-c69a792d7d3d4f44144816b77a532882

リファレンス https://guides.rubygems.org/specification-reference/

参考記事 gemライブラリの依存はGemfileではなくgemspecに記述する理由

テストしやすい書き方をする

以下ではtoken, from, toを渡す先をnewからfrom_teamnameに切り出すことで、 クライアントの差し替えを行い易くしている。

https://github.com/misoca/wataridori/commit/82faabb727bcd94e76542d898f6071cd4acdc83a

CI

ツールが小さいうちに導入するの良さそう

ラッパークラスの導入

ラップしておくと今後の実装で便利らしい →レート制御、リトライ制御 https://github.com/misoca/wataridori/commit/c3dbba1caa916ae9a82cc1e37fdce05b94aaeef7

method_missingもここで用意している(メタプロ感)

ガード節という書き方(リファクタ)

普段使ってるけど名前があったのか。 処理の冒頭に条件判断とreturnを入れて例外処理を完結させる。 ネストが深くなるのを防止できる。

https://github.com/misoca/wataridori/commit/d55361632ea3f3e5ca320409ef7a2e5bb451e20d

参考記事 初心者向け。覚えておきたい 「ガード節」という書き方。

インスタンス変数へのアクセサをきちんと書く

今回はattr_readerだがこんな感じのセット

  • attr_reader: 読み込み
  • attr_writer: 書き込み
  • attr_accessor: 読み込み&書き込み

https://github.com/misoca/wataridori/commit/2a229be5ad7185669c77334f9494679b28ef5fa2

リファレンス https://ref.xaio.jp/ruby/classes/module/attr_accessor

APIのRate Limit (利用制限)

結構最初の方に仕込んでるのでAPI利用時に注意することとしては高めぽい。

esa APIのRatelimitを表すクラスを追加 https://github.com/misoca/wataridori/commit/81ad20c8188891146de51f2683207497f0069f0a

Wataridori::Esa::ClientでRatelimitを考慮するよう機能追加 https://github.com/misoca/wataridori/commit/d22862b254798fbc7a2a7439c2a1af7d06faf141

例) GitHub https://developer.github.com/v3/rate_limit/

参考記事 APIとは?API Rate Limitってなに? WebAPIを設計するうえでの利用制限(Rate Limit)について調べた

テストの可読性を上げる

https://github.com/misoca/wataridori/commit/2cc1ba07a1e80a285f17182e59a477d56a8d61d9

ページネーションへの対応

https://github.com/misoca/wataridori/commit/8ebf6a70f3ddf76ea8a03b04eb1514d35b879314

なるほどこういう書き方をするのね 仕様としてnext_pageがないとnullが返ってくるのでそこでloopが終わる(loop処理はあとでリファクタされてました)。

     def list_posts(category, per_page)
       posts = []
       page = 1
 
        loop do
         res = from_client.posts(posts_params(category, page, per_page))
         posts += res.body['posts']
         page = res.body['next_page']
         break unless page
       end
 
        posts
     end

Hashie gemの導入

ハッシュをより便利に。 https://github.com/intridea/hashie

参考記事 ぼくのおすすめGem その2

ロガーでスクリプト実行内容を標準出力

何をやっているかをわかるようにする。 https://github.com/misoca/wataridori/commit/68f8f8d0158647e15a1e5fd44b6f159bd07ead47

コマンド追加とREAD ME追記

処理の改善

  • コピー処理をページごとに実施することでメモリ効率を改善
  • yieldの使い方要復習

https://github.com/misoca/wataridori/commit/23d7a0a93b38687d4ba9a7332d8a0768834a367f

データのまとまりは構造体にする

ここでもhashieが活躍 https://github.com/misoca/wataridori/commit/637553181956be2b678fcbfca9945cc5781961ad

参考記事 構造体を使ったプログラム

共用体というのもあるらしい。

リンクの書き換え用にnokogiriを導入

https://github.com/misoca/wataridori/commit/b255e92817c55fe085b95ba900ba8777bc5804af

https://github.com/misoca/wataridori/commit/80a2c018dabb4ca1a2b217e2d8ae7dfc4bf5ba76

nokogiri gem

こんちゃんさんが言ってたprivate accessorや↓

https://github.com/misoca/wataridori/commit/80a2c018dabb4ca1a2b217e2d8ae7dfc4bf5ba76#diff-04c30e2e12fac45633edb2fc268a2d1cR37

複数コマンド対応の書き方

https://github.com/misoca/wataridori/commit/448973083708bc87b44cd9ea20483bbaf4548db6

retry処理の導入

retrieble gem

https://github.com/misoca/wataridori/commit/dea92a14e7b44ceec415bb764555a893bd305027

まとめ

普段はある程度形ができたリポジトリのコードを読むことが多いのですが、公開されるまでの流れを把握できる規模のコードを読むのはひよっこエンジニア的にかなり勉強になりました。

たまたま「名前に親近感を持った」という興味で読み始めたのですが、こういうOSS貢献しているMisocaさん素敵だなぁと思いました。