the industrial

ブログと言うより自分のためのメモ以外の何モノでもないです。でも読んでくださってありがとうございます。

FactoryBotが「Failure/Error: config.include FactoryBot::Syntax::Methods」で読み込めなかった話

Rails4からRails5にアップデートをする際、重要ロジックのテストを書いていないことに気づいた。

そこで、改めてRSpecを使おうと思いいろいろ調べている中で、テストデータ作成ツールに FactoryBot を利用することに。

しかし、いくら試せど下記のようなエラーが・・・。

Failure/Error: config.include FactoryBot::Syntax::Methods

NameError:
  uninitialized constant FactoryBot
# ./spec/rails_helper.rb:63:in `block in <top (required)>'
# ./spec/rails_helper.rb:33:in `<top (required)>'
# ./spec/services/xxxxxxs/xxxxxx_service_spec.rb:1:in `require'
# ./spec/services/xxxxxxs/xxxxxx_service_spec.rb:1:in `<top (required)>'
No examples found.


Finished in 0.00052 seconds (files took 12.32 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

原因は、Gemfileの定義で下記に様にしていたから笑

group :development do
  # テスト関連
  gem "rspec-rails"        # rspec本体
  gem "factory_bot_rails" # テストデータ作成
end

rails_helper.rbでは

ENV['RAILS_ENV'] ||= 'test'

としているため

group :test do
  # テスト関連
  gem "rspec-rails"        # rspec本体
  gem "factory_bot_rails" # テストデータ作成
end

が正解。

しょぼいことでハマって疲れた笑

ScalaとRubyのコレクションで使える.mapについてちょっと調べてみた

突然ですが

先日、後輩くんがこんな実装をしました。

_nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

_divisible = _nums.select{ |n| n % 2 == 0 }

p _divisible
# [2, 4, 6, 8, 10]

_multiplied = _divisible.map {|n| n * 100 }

p _multiplied
# [200, 400, 600, 800, 1000]

実際はプロダクト上に実装したコードと少し違いますが、要件としては「コレクションの中から該当するものだけにしぼり、処理を施して新しいコレクションにする」という感じです。

さらにこれを「select」と「map」をつなげ、最終的には下記のような形となりました。

_nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

_multiplied = _nums.select{ |n| n % 2 == 0 }.map {|n| n * 100 }

p _multiplied
# [200, 400, 600, 800, 1000]

実は私、2年ほど前までScalaを書いていたのですが、上記のような書き方で結構実装した覚えがあります。

Scalaについて

Scala(スカラ(SKAH-lah[1])はオブジェクト指向言語関数型言語の特徴を統合したマルチパラダイムプログラミング言語である。 引用:Wikipedia - Scala

独学で2年、業務で2年ほどScalaを書いていた私ですが、詳しいScalaについてのお話はなるべく避けていきます・・・笑

ですが、例えば上記のコードをScalaで実装すると、こんな感じになるかと思います。

val nums = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val multiplied = nums.filter { n => n % 2 == 0 }.map { n => n * 100 }

multiplied.map(println)

どうでしょう?

ほぼ同じ様に書けるんですよね。

Scalaの場合はパターンマッチというのがmapの関数内部に適用出来ますので、例えばこんな感じに書けます。

val nums = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val multiplied = nums.map {
  case n if n % 2 == 0 => Some(n * 100)
  case _ => None
}.flatten

multiplied.map(println)

SomeとNoneはOption型というものでして、値がある場合Some、ない場合はNoneという子のオブジェクトで表現することにより、nullを徹底的に排除したプログラミングが出来るといったものです。※表現間違っていたらスミマセン

最後にOption型のコレクションに対して.flattenすると、Noneの要素が排除され、Someの要素が残り期待する結果が取得できます。

まあ、実際このような書き方をするのであれば、最後に書いたcollectメソッドを使います。

まとめ

Rubyを書きはじめた当初はあまり興味のなかった私ですが、こういった様にScalaと同じ様にプログラミング出来るのが意外でして、最近ではRubyも楽しいと感じるようになりました。

RubyのArray.mapの実装

さて、ここからは完全に余談です。

気になったのでRubyのArray.mapの実装を見てみました。

多分下記だと思っているのですが・・・スミマセン、github上でざっと見た感じですので憶測も含んでます!

https://github.com/ruby/ruby/blob/trunk/array.c#L2730-L2763

簡単に説明させていただくと、対象のArray内要素の件数分forでループし、同じく指定したブロック処理(rb_yield_force_blockargで、.map{ |n| ここの箇所 })を実行して新しいArray(コレクション)に詰めて返却するというもののようです。

一報、Scalaの.mapは、例えばcollection/immutable/List.scalaで見ることが出来ます。

https://github.com/scala/scala/blob/2.13.x/src/library/scala/collection/immutable/List.scala#L222-L236

簡単に解説すると、要素の先頭から順に受け取った関数(.map(A => B))に渡して処理を実行する感じですかね。

ちょっと詳しく説明しだすと終わらない気がするのでこの辺で・・・笑

collectと言えば・・・

さらに余談ですが、RubyのArray.mapはcollectの別名なんですね。

https://github.com/ruby/ruby/blob/trunk/array.c#L6449

実はScalaにもcollectというメソッドがありまして、先述の例題を実装しなおすと

val nums = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val multiplied = nums.collect {
  case n if n % 2 == 0 => n * 100
}

multiplied.map(println)

と書くことが出来ます。

どうでしょう?記述量がぐっと減ったように感じませんか?

家で作業スペースを作った話

最近奥さんと相談しまして、家でも作業できるように「ぼくがかんがえたさいきょうの家作業スペース」を作りました!

デスクは奥さんが好きなメープル色の、120cm☓70cmの幅があるローデスクです。

ディスプレイはLGの27UK850で、付属のTYPE-CポートをMBPにつなげるだけで、MBPに電源を供給できるというスグレモノです。こちらはなんといただきもの。ありがとうございます。

f:id:omiend:20180915230604j:plain

つなげるとこんな感じですね。

f:id:omiend:20180917221603j:plain

作業をしてみましたが、これだけでもなかなかの空間です。

f:id:omiend:20180916011113j:plain

ですが、やはり物足りないものがあります。

そう、それはキーボード。

板前さんが使う包丁の用に、エンジニアである僕にも大好きなキーボードがあります。

それがコレ。Happy Hacking Keyboard(HHKB)です。

f:id:omiend:20181002171718j:plain

会社で使っているものですが、ちょっと厚みがあるので都度家に持って変えるのは大変なのです。

はい、家用に買ってしまいました笑

f:id:omiend:20180922171118j:plain

家用のHHKBは黒色です。クールですね。

もちろん無刻印(英文字)です。

とても気に入っております。

さらに、家の作業スペースがある場所はWi-Fiが届きにくいため、中継機というものを購入。電波はバリ3に(し語)

iPadも脇において、なんか出来る人風に見えます。(見えるだけ)

f:id:omiend:20180926231043j:plain

少し殺風景なので、昔どこかの雑貨屋さんで購入した猫の置物をおいてみます。

f:id:omiend:20181002174453j:plain

名前はまだありません。

ちなみに中身はろうそく。

火はつけたことありませんが、どうやら口から火を吹く作りですね(違)

f:id:omiend:20181002174503j:plain

そんなわけで、やっと家でも会社の環境と遜色のない作業スペースを作ることが出来ました!

f:id:omiend:20180929001411j:plain

会社の僕のデスクと見比べても、ほとんど同じような環境になりました。

f:id:omiend:20181002171730j:plain

家で作業していても、結構はかどります。

そして、PS4も配置し、ディスプレイにガッチャンコワールド笑

f:id:omiend:20181002174616j:plain

結構仕事頑張っていて、なかなかドラクエ11がクリア出来ませんが、自分だけのスペースというのは良いものですね。

粘膜人間

粘膜人間 (角川ホラー文庫)

会社のパイセンと小説の話をしていて、京極夏彦をお勧めしたら代わりにお勧めしてくれた作品。

 

まあとにかくドギツイホラーで、描写(文字だけど)がグロい。

 

河童が出てきたりとファンタジックな要素もありつつ、なかなか楽しめた。

 

しかし、グロい文書は最早読まなくてもいいんじゃないかと少し飛ばした笑

 

次作も借りてるので楽しみ。

コーヒーと旅

コーヒーと旅

大好きなTV番組「キンシオ(TVK)」で活躍する、絵描きさん、キン・シオタニ先生の、「コーヒー」と「旅」を題材にした一冊。

文章が自由過ぎて、まるでキンシオを観ているかのような感覚で個人的におおいに楽しめた。

聲の形

 

 

映画『聲の形』Blu-ray 通常版


何だかんだ眠れず、録画してたものを鑑賞。

 

すげえ良かった。

 

ぼろ泣きするほどじゃないけど、各々の複雑な心情が上手く表現できて、日本文学を一冊読み終わったような感じ。

 

うーん、人間失格みたいなニュアンスがあるのかな。

 

NHKが放送するのもなんだか納得笑