グロースエンジニアのブログ

Ruby on Rails エンジニアです!開発に当たって勉強したことをまとめていこうと思います!

レガシーコードの改善は事前に経営陣とスケジュール、リソースの調整をしてから行うと良さそう

 

本書ではレガシーコードを以下と定義しています。

創業期の資金不足や人材不足によって生じたコード上の課題全般を、広義のレガシーコードと定義し、使用します。

レガシーコードへの本って方法的な話が多いが、この本ではそもそも会社は事業計画があって、技術的負債も含めてレガシーコードへの対応は経営陣と協調して進める必要があると書いてあって、僕としては初めて見た内容でこの視点はとても勉強になりました。

 

お金の視点は欠けていて、金銭面で見たときの会社の生存期間(ランウェイ)を計算し、人を●人採用すれば毎月の支出が増えるのでランウェイがこのくらい短くなって...といったことを考えたことがなかったので、それを知れただけでも読む価値があったなと思います。

 

経営陣への3つの提案

レガシーコードへの対応として以下の3つのパターンがある

それぞれのパターンで人を増やすことも踏まえて人件費がどのくらいかかるかを見積もりして、経営陣と相談する

レガシーコードへの対応

レガシーコードと言っても不具合発生率、開発効率、技術的負債、デプロイ頻度など様々なものがあり、今一番困っているもの、改善して効果が大きいものを見極め、それに合わせた採用だったり人の割当をする必要がある

まとめ

技術的な方法としてレガシーコードへの対応をこの本に期待すると違うが、経営陣と会話して何を進めていくのか決めているようなエンジニアには良い本だと思う。

そうでなくても、こういった視点を持って会社を経営しているということが分かってとても勉強になった。

技術的な部分はざっくりとした解説になっているので、そこを自分で埋めていこうと思う。

 

リーンとはフロー効率を優先する絶え間ない改善である

This is Lean という本を読んでとても良かったので忘れないうちにまとめておこうと思う

 

 

リーンとはフロー効率を優先する絶え間ない改善である

タイトルにも書いたけど、これが本書で言いたいことだと思う。

最初にいい例があって、これを頭に入れておくとその後の話が入って来やすい。

 

リソース効率とフロー効率

リソース効率とは、サービスにおいてサービスを提供する側のリソースの効率のこと。

本の例では胸のしこりを見つけた患者が最初に行った病院では結果が分からず、その後複数病院を回って結果が出たのが2ヶ月後という内容。

これは各病院でできることに対してリソースを効率化しているために起こっている。

フロー効率とは、サービスを受ける側のニーズを満たす効率のこと。

胸のしこりがあって乳がん専門の病院に行くと、そのニーズに応えることに特化したリソースが準備されており数時間で結果がわかる。

これはサービスを受ける側のニーズを最短で満たしている。

スループット時間

上記の例で患者をフローユニットと呼ぶ。フローユニットとは、リソースが価値を付加する対象のこと。

このフローユニットがニーズに気づいてから、それを満たすまでの時間をスループット時間と呼び、フロー効率を高めるとこの時間が短くなり、リソース効率を高めるとこの時間が長くなっていくというもの。

リソース効率化によってスループット時間が長くなる

病院の例で患者はニーズを満たすまで2ヶ月かかっている。これは最初のニーズが発生してすぐに解決できないことによって別のニーズ(別の病院に行って検査が必要)が発生している状態。

1つの病院で全て終われば発生しなかったことであり、2ヶ月という期間によって患者は不安な2ヶ月を過ごさねばならないため、さらなるニーズ(不安)を発生させている。

フロー効率を優先する

フロー効率を優先することで患者はすぐに結果がわかり、時間的に早く、メンタル的にも不安な日々を送らなくてよくなる(結果が早く出すぎて心の準備が...という話も本では上がっていた)

開発で考えるとフロー効率はリリースまでの時間の短縮化

ふと自分たちの開発に当てはめてみるとフロー効率は機能リリースまでの時間を以下に短くしていくかだなと感じた。

フロー効率を上げるには、仕様ぎめ、実装、レビュー、リリースまでの時間の短縮と考えると、例えば実装に時間がかかっているのは仕様に曖昧なところが残っているのでは?とか、レビューに時間がかかっているのは Pull Request 自体が大きかったり、タスクの細分化がうまくできてなかったりなど、改善する視点がいろいろと出てくるんじゃないかなと感じた。

まとめ

フロー効率という視点を得たことで、自分の開発フローをどう改善すると良くなるか考える新しい視点が加わった気がする。

あと、本の最初の例がそれ以降の話の全ての具体例になっていて理解しやすい構造になっていたのも良かった。

開発体制をもっと良くしていくためにチームメンバーと共有してもっといいチームにできるようにしていきたい。

 

 

factory_bot 再入門

Railsを始めてはや数年、最初のころに factory_girl の勉強をして、それ以来必要に合わせてちょっと調べて終わりって感じで過ごしてきた。

最近Railsを始めた人に、「Railsチュートリアルとかeveryday railsとかやって、開発してるプロダクト見ると書き方が違ってる」って話を聞き、そう言えばその辺の知識って古いまま(と言っても2,3年前?)更新されてないな...と思って読み直すと結構知らなかったことが多かった。

なので、ざっとまとめてみる。

まとめる内容は全部ここに書いてるので、こちらを見るとよいかと!

github.com

attributes_for

これも地味に知らなかった。

# Returns a hash of attributes that can be used to build a User instance
attrs = attributes_for(:user)

Aliases

Factory に alias が付けれる

factory :user, aliases: [:author, :commenter] do
  first_name    "John"
  last_name     "Doe"
  date_of_birth { 18.years.ago }
end

factory :post do
  author
  # instead of
  # association :author, factory: :user
  title "How to read a book effectively"
  body  "There are five steps involved."
end

factory :comment do
  commenter
  # instead of
  # association :commenter, factory: :user
  body "Great article!"
end

はい、知りませんでした...

ポリモーフィックとか使ってるのをちょいちょい見るので、これ使うとわかりやすくなるかな〜とか思ったり。

Transient Attributes

ちょいちょい見て、わかってるようで分かってなかった。 

この例はわかりやすくて、理解できた。

factory :user do
  transient do
    rockstar true
    upcased  false
  end

  name  { "John Doe#{" - Rockstar" if rockstar}" }
  email { "#{name.downcase}@example.com" }

  after(:create) do |user, evaluator|
    user.name.upcase! if evaluator.upcased
  end
end

create(:user, upcased: true).name
#=> "JOHN DOE - ROCKSTAR"

Inheritance

いつも trait を使ってたけど、こういうのもあるのか。一回で書けるって意味ではいいのかもな。

factory :post do
  title "A title"

  factory :approved_post do
    approved true
  end
end

approved_post = create(:approved_post)
approved_post.title    # => "A title"
approved_post.approved # => true
factory :post do
  title "A title"
end

factory :approved_post, parent: :post do
  approved true
end

Associations

alias を使えばいいけど、こういう書き方もある。

factory :post do
  # ...
  association :author, factory: :user, last_name: "Writely"
end

Sequences

こうやって別個に定義できるってのは知らなかったな。

# Defines a new sequence
FactoryBot.define do
  sequence :email do |n|
    "person#{n}@example.com"
  end
end

generate :email
# => "person1@example.com"

generate :email
# => "person2@example.com"
factory :invite do
  invitee { generate(:email) }
end
factory :user do
  email # Same as `email { generate(:email) }`
end

んで、aliasも定義できる

factory :user do
  sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
end

# will increase value counter for :email which is shared by :sender and :receiver
generate(:sender)

Linting Factories

Lint ってよくあるけど、factory_bot でもあるって知らなかった。

「うるせー!」 って言いたくなることもあるけど(笑)

FactoryBot.lint

まとめ

これ以外にもいろいろ紹介されてたけど、基本的なところはこんなところかなと!

gemも定期的に見て、機能とか確認していかないとダメだなというのが今回の気付き!

github.com

【mastodon】bundle install でエラーが出たのでメモしておく

mastodon がちょっと前に流行ってコード読もう読もうと思ってそのままにしていたので、時間取れるときに読もうと思って bundle install したらエラーになったのでメモ。

mastodon のバージョンは 2.3.2 

Failed to locate protobuf

current directory:
/mastodon/vendor/bundle/ruby/2.5.0/gems/cld3-3.2.2/ext/cld3
.rbenv/versions/2.5.0/bin/ruby -r ./siteconf20180326-69724-1yq4plx.rb extconf.rb
Failed to locate protobuf

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/mastodon/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/cld3-3.2.2/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in
/mastodon/vendor/bundle/ruby/2.5.0/gems/cld3-3.2.2 for inspection.
Results logged to
/mastodon/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/cld3-3.2.2/gem_make.out

An error occurred while installing cld3 (3.2.2), and Bundler cannot continue.
Make sure that `gem install cld3 -v '3.2.2'` succeeds before bundling.

`gem install cld3 -v '3.2.2'` をやってみたけどダメで、調べたら protobuf なるものが必要みたいで、 `brew install protobuf` をやったら通った!

 つづいてこちら

ERROR: could not find idn library!

current directory:
/mastodon/vendor/bundle/ruby/2.5.0/gems/idn-ruby-0.1.0/ext
/.rbenv/versions/2.5.0/bin/ruby -r ./siteconf20180326-5783-ruj5ss.rb extconf.rb
checking for -lidn... no
ERROR: could not find idn library!

  Please install the GNU IDN library or alternatively specify at least one
  of the following options if the library can only be found in a non-standard
  location:
    --with-idn-dir=/path/to/non/standard/location
        or
    --with-idn-lib=/path/to/non/standard/location/lib
    --with-idn-include=/path/to/non/standard/location/include

*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=.rbenv/versions/2.5.0/bin/$(RUBY_BASE_NAME)
	--with-idn-dir
	--without-idn-dir
	--with-idn-include
	--without-idn-include=${idn-dir}/include
	--with-idn-lib
	--without-idn-lib=${idn-dir}/lib
	--with-idnlib
	--without-idnlib

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/mastodon/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/idn-ruby-0.1.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in
/mastodon/vendor/bundle/ruby/2.5.0/gems/idn-ruby-0.1.0 for inspection.
Results logged to
/mastodon/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/idn-ruby-0.1.0/gem_make.out

An error occurred while installing idn-ruby (0.1.0), and Bundler cannot continue.
Make sure that `gem install idn-ruby -v '0.1.0'` succeeds before bundling.

これも brew install libidn したら通った。

 

第57回 Ginza.rbに行ってきた!

今回は【ディスカッションプラットフォーム Discourse のソースを読もう!】というテーマでした。

github.com

 

今回も忘れないうちにメモしたことをまとめます。

 

Discourseとは?

オープンソースとして公開されている掲示板やチャットが使えるディスカッションプラットフォームで、現場感のあるコードとのこと!

フロントは Ember で作られている。

スピードを気にしていて、○○族な人が作ってるらしい。

勉強会メモ

メモした内容をざっと記録していく!

lib にいろいろ詰め込んてる

アプリとは切り離して動くコードがここにある。

lib/freedom_patches ってのがあって、これを自分たちのアプリでも作って、公開できるやつは公開していくのはいい方法。

discourse/lib/freedom_patches at master · discourse/discourse · GitHub

コントローラーで require している

スピードに気をつけているので、必要に合わせてコントローラーなどで require している

discourse/app/controllers at master · discourse/discourse · GitHub

モデルに置けないものを services に置いてる

処理系のメソッドをここにまとめて定義している感じ

discourse/app/services at master · discourse/discourse · GitHub

環境変数のデフォルト値を上げてパフォーマンスを上げてる

discourse/bench.rb at master · discourse/discourse · GitHub

pluck, present?, blank? を早くしてる

discourse/fast_pluck.rb at master · discourse/discourse · GitHub

discourse/performance_fixes.rb at master · discourse/discourse · GitHub

その他

- Gemfile も Discource 自身が作っているものがあり、スピードを気にして使っている

 

- 参考にするのはどのサイトが良い?

-> 過去の歴史を見るという意味で readmine

GitHub - redmine/redmine: Mirror of redmine code source - Official SVN repository is at https://svn.redmine.org/redmine - contact: @jbbarth or jeanbaptiste.barth (at) gmail (dot) com

 

-> mastodon

GitHub - tootsuite/mastodon: Your self-hosted, globally interconnected microblogging community

 

-> discource は現場感があっていい

GitHub - discourse/discourse: A platform for community discussion. Free, open, simple.

 

TracePoint がキテるらしい

まとめ

頑張って話を聞き逃さないようにメモ取ってたけど、理解しようとして考えてて取りきれてない部分が結構ある気がする...

でも、今回も自分の知らないことがたくさん聞けて学ぶことも多かった。

少しでも内容を理解して自分の力にできるように、今後も参加していこうと思います!

第56回 Ginza.rbに行ってきた!

ここ数ヶ月続けて Ginza.rb に参加しています。

自分とのレベルが違いすぎて圧倒されることが多いんですが、このままだと本当にただ参加しているだけになってしまうので、振り返りもかねて学んだことを記録して行こうと思います。

今回のテーマ

【第56回 もうすぐやってくる!Rails5.2の細かいところも見ておこう 】ということで、資料はこちら!(公開してもいいということだったので大丈夫なはず!)

Rails 5.2

内容については上記資料を見た方がいいです。

各ページの青いところはリンクになっていて関連するPRなどに飛べるので分かりやすいと思います。(さすが、あの方の資料!)

以下、自分用のメモ。
知らなかった機能などはざっとどんな機能か調べてリンクを貼ってます。

(間違いなどあればご指摘いただけるとうれしいです!)

Action Cable

- hostとかportとかを設定できるようになった

使ったことないけど、今後機会があれば思い出せるようにメモ。

Action Mailer

- Mailer ごとに delivery job を設定できる

`delivery_later` したときに呼ばれるjobを自由に設定できるってことかな?

rails/message_delivery_test.rb at 2b35826389005bdb0af85a4ebb1f0ec213174d13 · rails/rails · GitHub


- email preview にlocaleが選べるようになった

preview 機能自体を知らなかった...。

ActionMailer Preview のススメ - Qiita

RailsのAction Mailer Previewsについて | 日々雑記

Action Pack

- cache key と cache version(updated_at)を分けて管理し、 cache keyを再利用可能に

Rails の version up のときに、load default にするとあれするので気を付けてね!とのこと。

ローカルで試すには設定が必要っぽい。

キャッシュは、デフォルトではproduction環境でのみ有効になります。ローカルでキャッシュを使ってみたい場合は、対応するconfig/environments/*.rbファイルでconfig.action_controller.perform_cachingtrueに設定します。

Rails のキャッシュ: 概要 | Rails ガイド

- eager_load = true の場合、サーバー起動時に各コントローラーのactionを読み込むようになった

- encrypted cookies に AES-256-GCM を使用

より堅牢なものになった
Rails側で良いようにしてくれる(自動で書き換える)
勝手に古いcookies を新しいものに書き換える

- protect_from_forgery がデフォルトになった

- signed/encrypted cookiesに有効期限を知っていできる

- key の rotation ができるようになった

# ここで新しいものを指定
Rails.application.config.action_dispatch.signed_cookie_digest = "SHA256"

# ここで古いのを指定
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
  cookies.rotate :signed, digest: "SHA1"
end

- System test に headless chrome driver, headless firefox driver が入った

- デフォルトの mime type が追加された

- header が変わった
以下の3つが追加された


  "X-Download-Options" => "noopen",
  "X-Permitted-Cross-Domain-Policies" => "none",
  "Referrer-Policy" => "strict-origin-when-cross-origin"

Action View

- srcset を指定できるようになった

- 画像の alt の自動生成を削除

- form_with に id 属性を追加するようになった
capybara のテストなどで必要ということで追加された 

Active Job

jobを実行する際にオブジェクトをシリアライズ、デシリアライズしてる。
それを自分で定義できるようになった

Active Model

- length validatorにProc, Symbolが渡せるようになった
これにより、条件を指定して最大文字数とかを調整できるようになった

- Active Record にあった attributes API が Active Model 配下に移動
Active Record のものを使うのは問題ない
Active Model のものは public ではない

(Rails で public api ってのは docs にあるかどうか)

Active Record

- Descending Indexが指定できるようになった(MySQL 8.0.1以降)

- sqlite3 で boolean を t/f から 1/0 に修正
t/f で保存していた場合、手動で変更する必要がある

- order と pluck に生 SQL はダメ
Arel.sqlメソッドでラップしないとだめ

- fixtures でまとめてクエリーを実行するようになった

- SQLが発行された場所が log に出るようになった
デフォルトは開発環境のみ

- MySQL の bulk true があったけど、 PostgreSQL でもできるようになった

- PostgreSQL の foreign tables をサポート

- Errorクラスが増えてる

https://y-yagi.github.io/presen_rails_5_2_part2/#/47

- その他、 Active Record はこれを見ると良い
http://kamipo.github.io/talks/20180215-tdtech/#/title

Atcive Support

- Date#prev_occurring、Date#next_occurringメソッドが追加された
前の曜日、次の曜日を取得するメソッド

- ActiveSupport::Cache::Store に write_multi メソッドを追加
Redis adapterだとMSETを使うようになるので、一個一個書き込むよりはやい

- ActiveSupport::Testing::TimeHelpersをincludeしている場合、テストの後処理で自動でtravel_backが呼ばれるようになった
Rspec はどうするのかわからない

Railties

- rails new 時の Gemfile に bootsnap を追加

--skip-bootsnap でスキップできる

その後の飲み会

今回は知った人が多かったので飲み会にも参加!

自分の開発経験にはない話がいっぱい出てきて、とても勉強になった。前に一回参加したときも感じたけど、こういう中での話にも知らないことがいっぱい出てくるので聞いてるだけで楽しい!

また参加します!

2017年を振り返って

今年は一年マルっとフリーランス プログラマーとして活動した年だった。

周りの人には言っているが、リサーチをやっていたときには全く考えていない働き方だし、こんなに楽しく仕事ができるようになったのも想像してなかったので、今の気持ちを整理したいと思う。

フリーになりたてのころ

正確には、去年(2016年)の10月からフリーになった。

当初はリサーチ業界から転職してプログラマーとしての仕事は2年くらいで不安しかなかった。

  • こんなんで仕事できるの?
  • コード理解できるかな?
  • コード書けるかな?

この時期は、まだプログラマーなりたてだし...って自分に言い訳をしてたのもあった。

一年を振り返った今の気持ち

この一年で合計3社さんとお仕事させてもらって、不安は少しずつ減ってきた。

それぞれの会社さんで実装面で相談にのってもらったり、知識不足のところは教えてもらったり、たくさんの人に助けてもらって、それまで「俺にできるのか?」って思ってたことでも「何とかできそう!」って思えるようになってきた。

今でも不安な気持ちはあるし、アウトプット出せてないときは本当に申し訳なく思う。だからこそ、もっと勉強しないといけないと思うし、期待されて、その期待以上のものを出すプログラマーになりたいなと思う。

いつからこんなに勉強することが楽しくなったのか、自分でも不思議なくらい本を読んだりコードを書くようになったのも事実で、まだまだ楽しく仕事できるな〜って感じている。

(それぞれの会社でお世話になった方々、ありがとうございました。)

反省点

性格的に怖がりで失敗したくないので、今ある知識の中で何とかしようとする部分が多かった。

でも、一回経験しておくと二回目以降に安心して手が動くという経験を何度もしたので、新しく勉強したものを「何でそれがいいのか?」という部分をちゃんと理解しつつ、実際のプロダクトのコードで使っていくようにした方がよかった。

来年やること

フロントとインフラ

あれこれ他の言語に手を出さず、自分で意図的に Rails だけやってきたのでここは強みだと思う反面、他の言語とかフロント、インフラ周りになるとなかなかアウトプット出せないなって感じた...

フロントと最低限のインフラ知識は必要だなと思うので、この辺りは自プロダクトも含めて埋めていきたい。

RubyRails

そして、 Rails 周りのインプットを増やせば増やすほど、こんな書き方できるのか!こうやって model を分けるのか!とか新しい発見が多くて、もっと知っていい感じのコード書けるようになりたいと思った。

なので、本やサイトから RubyRails 周りのインプット・アウトプットは今後も続けつつ、OSSのコードを読んでいろんな書き方を学びつつ、OSS貢献もやっていきたい。

また、人が多いところが苦手で勉強会とかにあまり参加していなかったので、来年は参加する機会を増やしていこうと思う。

ブログ

今年は全く書いてなかった。

こんなこと書いてもな〜...って思うこともあったけど、今でも昔の記事読むと、しょーもな!って思うことで悩んだりしてたみたいなので、作業ログ的に記録を残しておくと、「この当時はこんなことで悩んどったんだな」とかあとあと振り返りがしやすいかなと思う。

自分の記録を残すって意味でも、もう少し何かしら書いていこうと思う。

自プロダクト

自分のプロダクトとして Growth Support を作った。いいプロダクトになると思っているので開発を進めてさらにいいものにしていきたい。

また、くだらないサービスもどんどん作って公開していきたいと思う。その過程で知識不足なフロントとインフラを埋めていければいいと思っている。

まとめ

そんなこんなで、今年はとても楽しい一年だった。

やることもたくさんあるし、知りたいこともいっぱいある。まだまだプログラマーとして楽しい日々が送れそうなので、来年はもっと楽しい一年にしたいと思う。