がんばるぞ

がんばります

Englishman in New Yorkを耳コピしたのでメモ

www.youtube.com

かっこいいですね。

かっこいいので耳コピしました。

今まで耳コピしたものは、雑にコード譜を書いているだけだったのですが
これからは雑にコード譜を書いた後は共有までしてみようかなと思ったので、ブログにでも載せることにします。 著作権的に怒られたら消します。

そんなに音感は良くないので、合ってる保証はないですけどねっ

drive.google.com

Coverageの計測をxdebugからpcovに変えたら、CIの実行時間が5分の1になった

PCOVなるものを使うと、CIがめっちゃ早くなるという情報を得て、早速CIに導入してみました

pcovとは

超高速にCoverageの計測が出来るドライバーです。
こちら を確認してみると2019/1/16に初めてリリースされた、かなり新しめのプロジェクトのようですね

動作要件はPHP7.1以上です

インストールはpeclもしくはソースからビルド出来ます。僕はpeclでインストールしました。
詳しくはこちら

CI用Dockerコンテナの作り直し

今まではxdebugで計測していたので、その部分をpcovに変更します。
(CircleCIのconfig.ymlで直接xdebugのインストールしている人は適宜読み替えてください)

FROM php:7.3
# 中略
- RUN pecl install xdebug \
-  && docker-php-ext-enable xdebug
+ RUN pecl install pcov \
+  && docker-php-ext-enable pcov

そして、書き直したDockerfileをビルドし直して、DockerHubにあげておきます。

cd /path/to/docker
docker build -t {DockerHubのアカウント名}/php_for_circleci .
docker push {DockerHubのアカウント名}/php_for_circleci:latest

CircleCIのconfigを修正

イメージに先ほどのコンテナを指定しておき、テストの実行方法を指定します。

version: 2

jobs:
  test:
    docker:
      - image: {DockerHubのアカウント名}/php_for_circleci:latest
      # 中略
+     - run:
+         name: test
+         command: php -d pcov.directory=./ -d pcov.exclude=./tests vendor/bin/codecept run --coverage-xml

ポイントは、 php -d pcov.directory=./ -d pcov.exclude=./tests の部分で、 -d オプションでiniの設定をオーバーライドしてます。

pcov.directory は、カバレッジ計測対象のディレクトリを指定します。
ここが指定されていない場合は、カレントディレクトリからsrc、lib、appの順にディレクトリを探し、そのディレクトリ内のカバレッジを計測するようです。*1
つまりデフォルトの状態では、計測対象のディレクトリがsrcでもlibでもappでもない場合はカバレッジの計測をしてくれないことになります。

pcov.excludeカバレッジ計測から除外するディレクトリを指定します。
pcov.directoryにテストコードのディレクトリが含まれている場合は、そのディレクトリのカバレッジを計測してもマシンリソースの無駄なので除外します。 複数ディレクトリを除外したい場合は -d pcov.exclude="~(foo|bar)~" のような書き方をします。

僕は実行時のオプションでディレクトリの指定をしていますが、php.iniに設定を書き込んでも問題ないと思います

おわり

なんとこれだけのステップで導入出来ます。
実質pcovをインストールするだけですね

僕の場合は、ユニットテストが5.5minほど掛かっていたのですが、1minまで短縮されました。
よかったですね。

牛肉について

先日ツイッターのTLで自由研究LTというイベントを見かけて、こんなツイートをしました

ということで、自由研究として牛肉について少しだけ調べたので、結果をまとめました。

和牛って?

和牛とは、以下の4種の牛のことを指す

2003年の段階では、日本で食される品種は黒毛和種が58.7%と圧倒的なシェアを誇っており、それ以外の3種は全て合わせても全肉牛のうち2%程度のシェアとなり 日本で食される高級な和牛のほとんどは黒毛和種となっていることがわかる。*1

また、残りのシェアはホルスタイン種という乳用種が17.5%、ホルスタイン種と黒毛和種の交雑種が21.6%、その他0.2%となっている。

A5って?

A5とは、牛が市場で買取価格のランク付けをされる際に用いられる記号である。

A5ランクを獲得することで、その牛は高く買い取られることになる。
Aと5でそれぞれ評価のポイントが違い、Aは歩留まりで、5は肉質の評価となる。
詳しくは後述するが、A5ランクとはつまり、 「たくさん肉が取れて脂肪がたくさん含まれている牛」 のことだ。

歩留まりについて

歩留まりとは 「牛一頭につき、どれだけの肉が取れるか」 という基準のことである。
多く取れる方からA、B、Cと3段階で評価される。
牛乳の生産を目的とされる乳用種などはだいたいがBかCランクとなり、Aランクを取ることができる牛は肉用種であることがほとんどである。

肉質の部分について

肉質の良い方から5、4、3、2、1と5段階で表される。
また肉質と一言でいっても、評価ポイントはいくつかある。

  • 肉の色艶
  • 肉のキメや締りの良さ
  • 脂肪交雑(いわゆるサシ)の量
  • 脂肪の色艶

これらを総合的に評価して結果を決めることになる。
これらの評価基準の中で注目したいのが脂肪交雑(以降サシ)だ。

サシについて

サシとは、筋肉の中に含まれる脂肪のことである。

サシの量はBeef Marbling Standard(以降BMS)という基準によって評価され、 ナンバー12からナンバー1の12段階があり、数値の大きい方がサシが多く評価が高いということになる。

肉質の評価で5を獲得するためには、BMSナンバー8以上を獲得する必要があるが、ナンバー8の牛肉のサシの割合はどれくらいかというと、なんと 5割を超える。

実はBMSが要求するサシの割合は年々増加しており、1996年の段階ではBMSナンバー8に必要なサシの割合は30%強であったのに対し、2004年の段階で50%を超えている。
たった8年の間に20%も増加していることがわかる。 *2

サシが増えることで肉の風味が良くなるが、ある一定の割合を超えると、いくら増えても味に対して ポジティブな効果が期待できない 事が指摘されている点に注意が必要だ。

なぜ黒毛和種がこんなに多いのか

乳用種のホルスタイン種と、ホルスタイン種と黒毛和種の交雑種を抜いた、和牛だけのシェアを計算すると、9割以上が黒毛和種ということになる。

なぜこんなにも黒毛和種がシェアを取っているのかというと、理由はサシにある。

肉質の評価基準でサシについて触れたが、和牛4種のうち、最もサシがつきやすいのが黒毛和種なのだ。

牛の買い取り価格を上げるためにはA5ランクを獲得する必要があるが、黒毛和種以外で現在のBMSナンバー8以上を取ることは難しいため、 黒毛和種以外を育てても儲けにくい という背景があるのだ。

まとめ

昔のA5に比べて現在のA5の肉はとっても脂肪が多い!

A3やA4くらいの方がおいしそうな気がする!

黒毛和種以外も食べてみたい!

ahiru.yakiniku #1 を開催しました

日頃から焼肉を奢れという脅迫を受けている僕ですが 6/21(金)にとうとうahiru.yakinikuという、焼肉を(割り勘で)食べるだけのイベントを開催しました。

話したこと

  • エンジニアのコミュニティは最高
  • コミュニティ運営はむずい
  • 吉祥寺.pmはすごい
  • 先輩焼肉エンジニアのSさんに一度挨拶をしたい
  • laravel.shibuya をもっと盛り上げたい
  • BEAR.Sundayはいろんな可能性に気づかせてくれるフレームワーク
  • オブジェクト指向のハードコアってなんだったんですか
  • まつぴーさんとはまこさんはヤバイ
  • nさんもだいぶヤバイ
  • 転職の時くらいはwishlistは公開してほしい
  • でも誕生日に毎年wishlistを公開されるのはちょっとキツイ
  • Symfonyはもう1回くる
  • カンファレンスのチケットはもう1万円くらいにしてもいいんじゃない

なんかもっと色々話した気がしますが、もうだいたい忘れました。

開催してみて

直前の参加者のツイートを見て、穏やかじゃない雰囲気を感じましたが

めっちゃくちゃ楽しかったです!!!!

*1

やっぱり大好きな人たちと話すのは本当に楽しい! 楽しいことは何回でもやりたい!!

というわけで#2もやります!

ahiru-yakiniku.connpass.com みんな参加してくれよなっっ!!

*1:奢ってないです

Laravel Meetup Tokyo #12 にて登壇してきました。

かなり今更ですが、 Laravel Meetup Tokyo #12というイベントで登壇してきました。

Eloquentに別れを告げるタイミングについて考えたというタイトルで20分ほど話をさせていただきました。

登壇の反応はTogetterでまとめましたので、よければみてください。 togetter.com

スライドはこちら speakerdeck.com


なぜ話そうと思ったのか

EloquentはLaravelで使われるActiveRecordベースのORMです。

ActiveRecordは様々なORMで採用されていると思いますが、やはり有名なデザインパターンなだけあって非常に便利です。

しかし、便利な一方で批判的な意見も存在します。

その中の多くは「アプリケーションコードを複雑な仕様に耐えられるような設計にすること」に挑戦する人たちから発せられているように思います。

そこで、ActiveRecordの「得意な領域」や「批判されている側面」をそれぞれ整理して どういった場合にActiveRecordは有効なのか、またどういった場合にActiveRecordを採用すべきでないのかというのを一度自分の中で整理したいと思ったからです。

ActiveRecordの話なのですがLaravelの勉強会だったのでEloquentを例に挙げさせていただきました。

どんな内容だったのか

別れを告げるタイミングということで、自分が思う「Eloquentの辛いところ」をピックアップして それが本当にEloquentに別れを告げる理由になるのか考えてみるというスタイルでいきました。

おおまかにはスライドを見ていただければという感じなのですが、結論としては

純粋なドメインオブジェクトが必要になったら、別れを告げる必要があるのではないか

ということになりました(僕の中では)


純粋なドメインオブジェクトとは何かという説明の前に、ActiveRecordの制約について説明します。

ActiveRecordの制約の1つに「データベースのテーブルあるいはビューと1対1で作成する」というものがあります。

つまり、ドメインオブジェクトのプロパティはテーブル設計と密結合な状態になるということです。

usersテーブルにnameカラムとemailカラムがある場合は、対応するActiveRecordのクラスには必ずnameプロパティとemailプロパティがあるみたいな意味ですね。

これによってActiveRecordは非常に早い開発スピードを得ているわけですが それは同時に、テーブル設計に影響を受けないドメインオブジェクトを作成することが出来ないことを意味します。

これを「純粋でないドメインオブジェクト」と定義して、その逆に「テーブル設計から独立した(疎結合な)ドメインオブジェクト」のことを「純粋なドメインオブジェクト」とスライドの中では呼んでいます。(この呼び方が適切かどうかは微妙なところですが)

単純なCRUDだけでは済まないような複雑なアプリケーションがあった場合に、テーブルorビュー=ドメインオブジェクトというような設計では どうしても複雑な実装にならざるをえなくなってしまったり

「テーブルAのa,b,cカラムとテーブルBのd,eカラムを合わせてモデルAとしたい」というような状況が発生した場合はActiveRecordの責務を越え、対応が非常に難しくなると思います。

なので、

  • ドメインロジックをよりシンプルに実装するため
  • テーブル構造と一致しない概念(ドメインオブジェクト)が存在する場合
  • ドメインオブジェクトから永続化周りのロジックを切り離したい時

などの理由を背景に純粋なドメインオブジェクトが欲しくなった時がEloquent(ActiveRecord)とお別れするタイミングなのではないかと思いました。

話してみて

設計を学んでいる人からするとおそらく当たり前であろう結論になったので、本当にこの内容で登壇をするか少々悩んだのですが 実際に話してみると「勉強になった」という声をそこそこいただけたので、話してよかったなあと思いました。

また、設計の話はマサカリがすごく飛んでくるイメージだったので結構ビビりながらの登壇だったのですが あまり飛んでこなかったのでホッとしました(マサカリを投げてもらって勉強したかった気持ちもちょっとありましたが)

機会があればまた何か話したいと思います。


おわり

トゥギャッター株式会社に転職しました

2019/4/1からトゥギャッター株式会社というところで働いています。
前職はWebアプリケーションの受託開発をやっていましたが、次は自社サービスの開発をしていきます。

誰?

吉田あひるです。
今まではWebアプリケーションの受託開発を営んでいる会社に勤めていて
設計・開発・テストを一人でやってました。
PHPが大好きです。

なぜ転職したのか

技術力をもっと上げたかったのが一番です。
前職では技術力を伸ばすという面で少しだけ問題があって

  • 技術の話を出来る人がいない
  • 業務量が多く、プライベートで勉強する時間があまり取れない

という点が悩みでした。

開発環境や開発組織がある程度成熟している会社では勉強しなくても業務の中で自然と身につくようなことでも
前職では自発的に勉強しないといけなかったりで、そこらへんがどうしたもんかなあと思っていました。

具体的にはGitlabを運用するために実践Gitlabのような本を読んだりですね、まぁそういう本を読むのはそれはそれである程度楽しいので良いのですが
もっと知りたいことが山ほどある中で、かなりもどかしい感情を抱いていました。

そういった中でトゥギャッター様とご縁があり、話を伺ってみると

などですね、単純に楽しそうだなと思ってしまい、ぜひ僕を仲間に入れてくださいという感情を抱くことになりました

このままだと前職がアレな会社だと思われそうなのでフォローしておくと
前職は人間関係がおそろしく良好で、やりたいことはなんでもやらせてくれるような非常に良い会社でした。

なので、僕が「技術力は自分のペースで上げつつ、楽しみながら生活を送りたい」というような願望を持つ人間であれば転職することはなかったかなと思います。
僕はなるべく早く技術力を上げる必要があるので転職という手段をとりましたが、今でも前職は大好きです。

働いてみて

社風

まだ働いて1週間程度ですが、自由だなと思います。
1週間で2回もお花見をしました。お花見大好きか

大学生エンジニアのアルバイトの人たちは全員フルリモートで働いてます。すごいな。
木曜日はリモート推奨日なので、僕もリモートで働いてます。

あとは文化に造詣の深い人が多そうだなという気がしてます。
僕はエンジニアになってからプログラミング関連の情報以外何も学んでいないので、何らかの文化に触れなければという気持ちになっています。

残業ですが、定時から1時間後までにはほぼ全員帰ってるような感じです。
残業が無くなったのでプライベートの時間が増えるかと思いきや、通勤時間が9倍(往復20分->3時間)になったので、家にいれる時間はあまり変わってないですww
ただ、通勤中に読書ができるので、勉強時間を増やすことには成功しました。やったね。
通勤中にエンジニアの基礎力に繋がるような知識を蓄えようと企んでます

まだ1週間しか働いていないので、社風に関して語れることはほとんどないですが、第一印象としてはこんな感じです

技術面

社員のみなさんはもちろんなのですが、大学生のアルバイト(インターン?)の方々もかなり優秀でビビってます。
Webエンジニアを募集している各社、Togetterでバイトしてる大学生はめっちゃ優秀なのでチェックしておくといいですよ

開発環境ですが、モダンな環境にしていこうという気持ちがみんなにしっかりあって、なおかつそれぞれが実際に行動しているという状況がすごく居心地が良いです
僕目線ではすでにだいぶモダンに感じますが、まだまだ改善できるところは確かにあるかなという印象です。

10年もの歴史があるサービスなので、歴史的事情でモダンにしきれていない部分などもあり、そこらへんのアンバランス感も楽しいです。
解決するべき課題がある状況は、エンジニア的には遊び道具がたくさんあって嬉しいなという気持ちになります

開発中のコミュニケーションですが、Togetterでは各人にtimesと呼ばれるSlackのチャンネルが用意されていて、開発中に感じたことを適当に呟きます
詰まったりしたときや、なんでこここんな実装になってるんだ?みたいな疑問を呟くと他のエンジニアが反応してくれたりして非常に良い仕組みだなと思いました。
業務版Twitterみたいな感じですね。
もともと独り言が多いタイプなので、僕のtimesが一番活発になってます

あとは技術の話が出来るようになったり、設計についての議論が出来るようになったのがすごく嬉しいです。
一番設計に関心がありそうなエンジニアの方がフルリモートなので、うまいことコミュニケーションを取っていきたいなと思っています

まとめ

まぁとりとめもない感じでまとめも特にないんですが
今の所とても楽しいです。

受託開発とやることが異なりすぎてわからないことだらけですが
とにかく手を動かしながら調整していくのが性に合ってると思うので、何も考えずに手を動かしていこうと思います 。

重要な宣伝

Togetterは現在Webデザイナーを募集しているらしいので、全人類応募してください。


P.S.

関係ないですが、僕は吉田で、社長も吉田なので
誰かが社長の吉田さんを呼ぶと高確率で僕が反応してしまって困っています。誰かなんとかしてください。

何回も反応してしまうので反省している図
何回も反応してしまうので反省している図


P.S. P.S.

wishlistを公開してほしいという奇特な方がいるようなので公開します・・・!ありがたい・・・。
https://www.amazon.jp/hz/wishlist/ls/39ZZSAV18ZJQB?ref_=wl_share

おわり

Circle CIでIlluminate\Contracts\Container\BindingResolutionExceptionが発生する

Circle CIで、全てのテストが通っているのにCIが落ちるエラーが発生しました。

#!/bin/bash -eo pipefail
./vendor/bin/phpunit

PHPUnit Pretty Result Printer 0.25.1 by Codedungeon and contributors.

PHPUnit 7.5.7 by Sebastian Bergmann and contributors.

/* 省略 */

Time: 6.08 seconds, Memory: 36.00 MB

OK (155 tests, 234 assertions)

Fatal error: Uncaught Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Debug\ExceptionHandler] is not instantiable. in /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 962

Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Debug\ExceptionHandler] is not instantiable. in /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 962

Call Stack:
6.0873   36298904   1. Illuminate\Foundation\Bootstrap\HandleExceptions->handleException() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:0
6.0878   36328616   2. Illuminate\Foundation\Bootstrap\HandleExceptions->renderForConsole() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:87
6.0878   36328616   3. Illuminate\Foundation\Bootstrap\HandleExceptions->getExceptionHandler() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:101
6.0878   36328616   4. Illuminate\Foundation\Application->make() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:159
6.0878   36328616   5. Illuminate\Foundation\Application->make() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:757
6.0878   36328616   6. Illuminate\Foundation\Application->resolve() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Container/Container.php:619
6.0878   36328616   7. Illuminate\Foundation\Application->build() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Container/Container.php:671
6.0878   36328728   8. Illuminate\Foundation\Application->notInstantiable() /home/circleci/lec/vendor/laravel/framework/src/Illuminate/Container/Container.php:800

調べてみると、どうやらcodedungeon/phpunit-result-printerのAnyBarなるものがenableになっていると発生するエラーのようでした。 参考

なので、laravelのルートディレクトリにphpunit-printer.ymlを作成し

options:
  cd-printer-hide-class: false
  cd-printer-simple-output: false
  cd-printer-show-config: true
  cd-printer-hide-namespace: false
  cd-printer-anybar: false
  cd-printer-anybar-port: 1738
markers:
  cd-pass: "✓ "
  cd-fail: "✖ "
  cd-error: "⚈ "
  cd-skipped: "→ "
  cd-incomplete: "∅ "
  cd-risky: "⌽ "

のようにすることで解決しました