Ich habe hunger

あふりかエンジニア、アフリカ向けのB2BのSaaSを開発する

Rails+Hamlでtextareaに余計なスペースが入っていた件

f:id:sugi511:20170708163821p:plain

DBの中身とか見ても、改行コードが普通に入ってるだけなんだけど、textareaに出力するとこんな感じで余計なスペースが入っていた。 で、controllerに送る時、saveした後、Edit画面で出力する前とか見ても余計なスペースというのは存在しなかったのに、なぜかこれ。 本番環境では起こらないし何だろう、と思っていたら実はHamlの設定だったらしい。 ということで、optionをいじって無事解決。

** 参考

qiita.com

qiita.com

「君は自分の人生を生きているか」

あんまり強い言葉を使うのは嫌なんだけども、30歳を迎え現実に対峙するにもパワーが必要になって来た今、現在考えていることをどうしても文章にしていないとこれから先に同じように自分に問いかけることを避けてしまいそうなので自分自身に問いかける意味も含めて文章にしておきたいと思う(こういうような言い訳を書かないとこういう文章を書けなくなってきたあたり老いてきたのでは、と思ったりもする)。

10歳、20歳の自分にきちんと説明ができるか

区切り自体はどこでもいいんだけども、小学生、中学生、高校生、大学生、大学院生、新社会人と年齢とともにいろんな環境に身を置いてきたし、その都度色々なことを学び色々なことを考えていたと思う。もちろん、今思うと「青臭いなー」とか「バカだったなー」と思うことはたくさんある。が、しかし知らないということは一つの力である、というのはやっぱり思う。で、5年、10年、20年前の自分ともし話ができるのなら、彼らに対して胸を張れるような選択が今できているだろうか。「遊べるのは学生のうちだから」なんてクソみたいなセリフを吐かないだろうか。彼らをワクワクさせるほど熱狂しているものはあるだろうか。

今の自分は楽をしていないだろうか

正直いって少し楽をしていると思う。本当にこれはダサい。今すぐ変えないといけないが、傾向として自分ができる範囲でなるべくことを済ませようとする。ある程度までは多分これで良い。でも、これだと自分の100%を超えない。新しいものを取り入れることを外部環境に任せてしまっている。必要に迫られることがあるなら・・・そうじゃない。本当にやらないといけないのは、集中する場所は決めるべきだが、積極的にいろんなことを取り入れないといけない。CTOという立場だと、どうしても自分がキャップ(上限)になる瞬間が来てしまうので、そこまでには自分がキャップにならないか、キャップになっても良いぐらいきちんと伸びてないといけない。掛け算が大事だ、とか言い訳を最近しがちだけども、掛け算する2要素あれば両方とも伸ばすことをサボって楽をしてはいけない。楽をせず、自分の伸びを楽しんで、それをチームや会社の伸びに転換するという視点を持つべきだと思う。自分で留めないからこそ得られるフィードバックや経験というのもあるはず。

40歳、50歳の自分が振り返っても恥ずかしくないか

どうなるかはわからないけど、10年、20年後には自分はもっともっとすごいやつになっていて欲しい。どういう物差しですごいやつかは正直わからない。でも、30歳の今の自分が羨むような生き方をしていて欲しい。そんな未来の自分が見て、現在サボっていないか、全力を出してなかったんじゃないか、視野が狭かったんじゃないか、と思わないような最善を尽くしたい。今の仕事はすごく楽しいし、特異な環境だし、今の選択だとベストだと思う。思うが故に、本当にベストなんだろうか、情報をシャットアウトしてるだけでは?ということをもしかしたら考えるべきかもしれない。

生きていることを忘れていないか

「生きていることを忘れていないか」

実は「生きている」というのがどういうことかは分からない。精神的な話。何年か前、目の前にある仕様書に沿って本当に世の中のためになるかも分からない、誰の幸せにつながっているのかも分からない、自分が熱狂できるわけでもないシステムを作っていた時は、多分「生きている」とは言えなかった気がする。適当に仕事をして、給料をもらって、友達と適当に飲み会をして・・・楽しかったけど、考えることから逃げて楽をしていたのだと思う。他の人がどうかは知らないが、少なくとも"今の"自分にとっては、誰の幸せを作ってるかも分からないシステムを作ることはもしかしたら良いことかもしれないけど、その状態は非常にカッコ悪いと思うし、本当に自分がやりたいことなの?熱狂してる?という問いを投げかけたいと思う。

常にかっこいい自分に

やっぱり年齢とともに体力的にも落ちてくるし、奥さんも子供もいるといわゆる守るべき存在というのもいるし、どうしても保守的な行動をとりがちになるし思考もそうなりがちだが、何歳になっても謎の万能感に包まれていた小学生高学年〜中学生の自分が憧れるような、60〜70歳だろうが死ぬ直前だろうが常に自分がカッコよく生きるために全力を尽くしてきたよな、と未来の自分が振り返れるように今を全力で生きたい。

30歳の自分は今。

25歳の年で社会に出たので多分社会人5年目。半年以上関わった会社でいうと正社員・業務委託で6社ぐらい。今は2015年7月からジョインしたアフリカインキュベーターという会社でCTOをしている。

「MAKE EVERYDAY PURCHASES CONVENIENT」

これを旗印にアフリカの流通にITでどうやって食い込んでいくか、僕らがやらなくてもいつか時代がアフリカを押し上げるとしても、僕らの会社がどれだけそれを加速させられるか、というところが面白いと思ってやっている。どうしてもBtoBを支える部分になるが、日本でやるよりももっと効果があるし、ワイヤレスからインターネットが始まる彼らの社会にどうやってフィットしたものを作るかというのは日本とは別の課題だ。ここら辺を本当に解決できた先にある社会の礎になるような商習慣を作る手助けになれば、流通の基礎を作られるなら、それはどれだけ素晴らしいことだろう。まぁ、しかしながら当たり前を作った人は感謝されない。でも、作ったと胸を張れるだけの適切な自意識があればいいんじゃないかな、とも思う。

あと、うちの会社に関わってくれてる人が大好きだ。社長はいわゆるスーパーエリートなんだけども、本当に賢くてぜってー追いつかねーって思ったりもするが人間的なとこも十二分にあったり、こういう人と仕事をできるというのは本当に幸せで、偶然だったし、2年前の自分にこのチャンスを逃さなかったのはGood Job!って親指を立ててやりたい。リモートでエンジニアしてくれてる人も、現地でゴリゴリ営業してる人も、限られた時間を使って現地にいったインターンの人たちも、本当に尊敬のできる人ばかりで幸せな環境に偶然身を置くことができてるんだな、と思うとやっぱりこの人たちに恩返しをしないといけないと思うし、できれば杉山と働いたこの時間は本当に価値があった、とか幸せだった、みたいに10年後に語れるようにしたいな、と思う。

綴ってみて思ったけど、今のところしんどいこともあるが全体評価としてはすごく楽しいが、少し楽してる部分もあるので、10年後の自分に「あの時の自分はダメだったな〜」なんて語らせないように頑張ろうと思う。と、書き始めると無限に続くので、先の謎の表明で終わることにする。

OS X El Capitanでrailsを再インストールしようとしたらeventmachineでエラーが出て原因がopensslっぽい

rbenv install 2.1.8
bundle install

みたいな感じで進めてたら

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

(中略)

compiling binder.cpp
In file included from binder.cpp:20:
./project.h:116:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
         ^
1 error generated.
make: *** [binder.o] Error 1

make failed, exit code 2

(中略)

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


こんな感じのエラーが出て、何やらopensslがダメらしい。

> El CapitanではOpenSSLヘッダが提供されなくなっている

という話が合って何やらこれが原因らしい。

qiita.com

opensslからlibresslに乗り換えようかな、と思って乗り換えてみたけど、あんまり問題としては解決しない。

export PATH=/usr/local/opt/openssl/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$LD_LIBRARY_PATH
export CPATH=/usr/local/opt/openssl/include:$LD_LIBRARY_PATH

qiita.com



結局のところ、.bach_profileに上記のPATHを通すことでなんとか動くようになりました!
あー、かれこれ5-6時間詰まってた気がする。

DateRangePickerでRangeでなく単日、時間を選べるようにするときのオプションメモ

  $(selector).daterangepicker(
    "singleDatePicker": true,
    "timePicker": true,
    "timePickerIncrement": 5,
    "autoUpdateInput": false,
    locale: {
      format: 'MMMM D, YYYY HH:mm'
    },
    (datetime) ->
      $(selector).val(datetime.format('MMMM D, YYYY HH:mm'))
  )

空欄も許可するような場合には、autoUpdateInputをfalseにしておかないといけないが、falseにするとカレンダーを表示してApplyを押しても反映されないので、callback部分でセットするようにした。

今回ここで引っかかったのは、フォーマットを結構変えているので、フォームに事前にvalueがセットされている場合にdaterangepickerでセットしているformatに従わない場合、「Invalid date」みたいな感じになるので、

dateTimePicker = (selector) ->
  unless $(selector).val() == ''
    datetime = moment($(selector).val()).format('MMMM D, YYYY HH:mm')
    $(selector).val(datetime)

  $(selector).daterangepicker(
    "singleDatePicker": true,
    "timePicker": true,
    "timePickerIncrement": 5,
    "autoUpdateInput": false,
    locale: {
      format: 'MMMM D, YYYY HH:mm'
    },
    (datetime) ->
      $(selector).val(datetime.format('MMMM D, YYYY HH:mm'))
  )

こんな感じにしておいた。
こういう感じにしておくと、1ページに複数のカレンダーUIが必要になっても、dateTimePickerに突っ込んでOKになるので割と便利。

Railsでmigrationする時にundefined method `to_sym'

出たエラーはこんな感じ

NoMethodError: undefined method `to_sym' for {:default=>true, :null=>false}:Hash

migrationはこうしているだけ。defaultをfalseからtrueにするだけ。

  def up
    change_column :questions, :enabled, default: true, null: false
  end
||<    

と思ったけど、ただのケアレスミスで、:booleanって書くの忘れてただけだった。

>||
  def up
    change_column :questions, :enabled, :boolean, default: false, null: false
  end


change_column_defaultを使えば良いケースだ。
change_column - リファレンス - - Railsドキュメント

めっちゃでかいリリース(の作業)が終わった

昨年のこの時期もリリース前でバタバタしていた。この1年で結構でかい新規機能投入を含むリリースを少なくとも6回はしている。それでも、まだまだ機能が足りない、ここがバグがある、通信が遅い、データの同期の問題がある、などなど仕方ないものも含め、お客さんに提供は出来ているものの、僕ら自身が目指す世界を実現するためにはソフトウェアとしてまだまだだった。

さっき、ここ1年の中で一番大きいリリースを終えたばかり。日本は夜中の2時だけど、アフリカだと20時頃。ログは全く動いてなかったし、日本とは違って土曜の夜にもなると業務アプリケーションいじってる人は誰もいないんだなーとか思いながら、Enterを押して、アプリケーションのデプロイにDBのmigrationを走らせて、必要なrakeタスクも実行してデプロイ完了。

今回のリリースは、ホントにハードだった。事の発端は4-5月ぐらいで、結構なハイペースでリリースを繰り返していたがアフリカの通信の状況、現地スタッフのアプリケーションの想定のしない使い方、通信が遅過ぎてどうにもならないとか、ソフトウェアとして限界を迎えようとしていた。毎日起こる問題にデバッグをして再現性を見つけて潰しては、また新たなissueが発見される・・・。1年弱走り続けて負債もたくさんあるし、継ぎ接ぎで作って来たアプリケーションなので仕方ないと言ってはいけないのかもしれないが、仕方ないことだと思ったし、いつかどうにかしないといけないけども日に日に積まれていく新機能の提案に対して立ち止まって負債を返済するなんてなかなか意思決定はできなかった。

5月に入ったぐらいかな。代表と話していて、結局ソフトウェア的にはゼロから再度開発をして、必要であればDBや通信を扱うライブラリごと変えてしまうぐらいのことが必要だと思う、という話をして、一旦新規機能の開発や営業を止めてもらって、ゼロから開発し直すことになった。本当に、あのタイミングで良かったと思うし、代表の胆力を見た気がした。カッコいいよね。

そこから、データの同期のアルゴリズムを試行したり、DBのライブラリとの相性を試したりと色々しながらまた新機能も載せながら、かれこれ3-4ヶ月もかかってしまったけど良い物が出来たと思う。ホント、みんなありがとう。Web側も、今回ので色々な機能が乗っかったし、複雑さも増したけども、テストもある程度書けるようになってきたし、それによる恩恵も受け始めてるので、完璧であることは求めないけども、勘所は押さえつつ開発を進めていけたら良いなぁ。とはいえ、やや開発者としてレベルアップが求められている感じがしているので、色んなことを吸収して組織に戻して、さらにそれを共有してとSECIモデルを良い感じに回して行きたいよね。

「あのタイミングでの意思決定で良かった!」と言えるようにするには、ソフトウェアだけではないけども、そう言えるだけの材料は揃ったと思うので、ここからはエンジニアも含めてどんどんと事業を進めていって、ふと後ろを振り返った時にそう言えるだけの結果を出せるように頑張っていこう。

Develop the future of Africa with technology and strategic management