少しだけ新卒を振り返る猫

この記事はマネーフォワードアドベントカレンダー2020🎄の13日目の記事です。 昨日は 「19新卒の自分が「ミッションへの貢献」を感じられるようになった2020年」というタイトルで、安藤さん の記事でした。

note.com

自己紹介

マネーフォワードでエンジニアをしています、たばです。SNSなどのアカウントネームは大体 @cat2koban でやっています。 この記事では、少しだけ新卒エンジニアとして過ごしてきたこれまでの日々を雑多に振り返っていこうかと思います。

入社当初

現在も猛威を奮っている COVID-19 の影響で、入社式はオンラインで開催されたのを覚えています。 PCの受け渡し以外、それまでの入社手続き諸々は全てオンラインで行われました。そのおかげで外に出ることなく、三密を避けた状態で社会人としてのスタートを切ることができました。

こちらの記事にて、入社式の裏側をいくつか紹介しているので良ければこちらも御覧ください。 note.com

研修期間

4月〜7月には大抵リモートで、マネーフォワードのカルチャーについての研修や、情報セキュリティに関する研修などいくつかオリエンテーションが実施されていたのを覚えています。各々が自ら課題を設定しプロダクト開発を行うエンジニア研修も、オリエンテーションと並行して実施されました。エンジニア研修の際、まだあまりコミュニケーションの取れていないメンターや他の先輩に質問を投げることに億劫になっていたせいで、技術のキャッチアップや疑問点の解消に少し手間取ったのを覚えています。とはいえ、後に開かれるチームの夕会を通じて、チームのバックグラウンドを知ることができ、人に対する不安等は解消されていったように思います。現在は週2日で行われている夕会ですが、始めの頃は毎日夕会が行われていました。1日のやったこと・学びの共有など、序盤は全メンバーが持ち回りで自己紹介をしていたのを覚えています。丁度先日、メンターの 4geru さんがチームの夕会について紹介しているので良ければこちらも御覧ください。

note.com

日報を書き始めた

社会人になってからはほぼ毎日、日報を書くようになりました。適宜会議などのメモも載せるようになったり、気づいたこと・学び得たものを所感に記す量も増え、1日に書く日報のボリュームが日に日に増えていったのを覚えています。 併せて最初の頃は、「他人の良いところを真似して自分のものにする」という目的で、毎日退勤後の一時間、同期の日報をまじまじと眺めていました。他の同期はエンジニア研修・それ以外で何をしているのか、1日でどんな学びを得たのか、はたまた何をどうメモに残しているのかなどなど、多くの情報を得ようと会社の esa に張り付いていたのを覚えています。稀にユーモアに富んだ同期の面白おかしい振り返りがあったりして、飽きることなく続けていました。現在は同期の日報を読むことで1時間も時間を取ることはしていませんが、チャンネル内に投稿される簡略化された日報を読む、程度のことをしています。

初めてのタスクアサイ

5月、研修と並行して初めてタスクを任されたのを覚えています。最初のタスクは特に困惑することなく進み、PRの作成、レビューと、スムーズにいきました。そしていざ自分の修正が本番環境に反映されたのを目の当たりにすると、エンジニアとして歩み始めた実感がようやく湧き、期待と興奮で胸が躍ったのを覚えています。

初めての考慮漏れ

初めてのタスクアサインからすぐのことでした。2つほど小さめのタスクをこなした後、ビジネスサイドのメンバーも巻き込む少し大きめの機能追加に関するタスクを任せていただくことになりました。嬉しくなった私は時に遅くまでメンターにお付き合いしていただき、夜遅くまで作業を続けて残ってしまう、なんてことも多々あったのを覚えています。実はこの少し大きめの機能追加のタスク、リリース当日になんと考慮漏れが発覚してしまい、別途修正PRをリリースする必要が出てきたのです。足早に修正し、PRを作ったものの、私はリリースをせずにそのまま休暇に入ってしまい、後に先輩が代理でリリースまで巻き取ってくださったのを覚えています。リリースした機能で問題が起きないか、障害が起きてしまい、もしかすると追加作業の必要があるかもしれないという気持ちで、リリース付近はアプリの様子を見守ることが大切だなと学びました。

入社後3ヶ月経っての面談

8月に入って、VPoE の渋谷さんと入社前と後の期待値のズレがないか等についてお話をさせていただく機会がありました。まだ大きな成長は実感できていないが、周りの沢山の優秀な同期・先輩が、自分に対して常に良い刺激を与えてくれる最高の環境であると話したのを覚えています。今も変わらずそのように思っており、個人的にはとても働きやすく、自分の成長にたくさんコミットできる環境だなと思っています。

そして現在

9, 10, 11月と、ひたすらに任されたタスクをこなしつつ、時には自分からも積極的にタスクを取りに行ったりして、入社当初よりも幅広く社内で活動ができるようになったなと個人的には思っています。とはいえレビューの際にかなりの数の指摘を受けたり、ロジックの設計で考慮漏れが発覚してしまい手戻りが起きたり、開発者都合の対応をお客様に案内しようとして指摘を受けたり...と、まだ未熟な部分が多いことを痛感しています。仕事を任されているプロである以上、未熟と感じた部分は放置せずに改善し、より高い質で仕事をこなせるよう努力する必要があるので、ひたすらに経験を積み、失敗を振り返り、繰り返さないためにもどう仕組み化するか、成功時には、良かった点を続けられるようにどう仕組み化するか考える、そのループをこれからも崩さないようにしていきたいなと思います。

終わりに

というわけで少しだけ新卒を振り返ってみました。4月はオンラインでのオリエンテーションがあり、5, 6 月ではタスクを任され始め初めて失敗し、8 ~ 11月の間は少しずつ慣れ始めて、いろんなことに手を出していたなぁという流れをつらつらと書いてみました。実はまだ他に振り返り事項は残されているのですが、より細かく書いていくと「少しだけの振り返り」ではなくなってしまいそうなので、一旦ここら辺で切り上げることにします。また思うことがあればこちらに書いていくと思いますので、よければその時にまた読んでいただければと思います。そして入社初日に描いたブログでこんなことを言っているのを拝見しました。f:id:sorehaedamame:20201213040541p:plain

sorehaedamame.hatenablog.com

楽しめてはいるが、以下2点については少し思うことがあるなと...まぁ体調崩したといっても仕事が影響したわけではなく冬の寒い時期にお腹を出して寝てたことが原因で一度あったくらいなので、それは良いか。

さて!明日のマネーフォワードアドベントカレンダー2020🎄 14日目はまんまるねこさんです。ではお楽しみに〜〜〜!!

mf-advent-calendar-2020

初めての vim プラグイン作成

この記事は Vim2 Advent Calendar 2020 - Qiita の8日目の記事です。 昨日は Hasu さんの 高校生がVimプラグインを作った話 でした。

はじめに

この記事では、アルパカ隊長 さんに教わりながら作成した はじめての Vimプラグインの話を書き記したいと思います。

作ったもの

github.com

複数行選択をしたのちに、 :Ghlink とコマンドを入力すると、選択した行がハイライトされたページへのリンクがクリップボードに保存される、と言うものです。

vim-plug の場合は、vim の設定ファイルに以下の通りに記述するとインストールされると思います。

Plug 'cat2koban/ghlink.vim'

簡単なデモを下に載せておきます。

f:id:sorehaedamame:20201208095052g:plain
ghlink.vim_demo

選択した後に : を押すと、コマンド入力部分に既に '<,'> が入力されていると思いますが、続けて Ghlink と打ちます。

もともと Slack などで質問する際に、複数行ハイライトされた状態のページへのリンクをさくっと取得できるようにしたいなと思ってこう言うプラグインを作ろうと思いました。 まぁ特に調べもせずに、Vimプラグインがどういうふうに作られるのか気になっていたので、車輪の再発明は気にせず学び目的で作成しました。 まだいくつか TODO が残っているので、引き続き実装は進めていこうと考えています。

作るときに便利だったもの

github.com

便利関数が多数定義されているプラグイン。これからのプラグイン開発では、こいつは必須になってくるのかなぁと思った代物です。ghlink.vim のコードでもその定義された関数を使っていて、便利さを 1行で実感しました。 2行目の s:Prelude.path2project_directory(a:path) の部分が vital の中で定義された関数を呼び出している箇所になります。 とはいえ実際の上の行では vital のインスタンスを作成していたりと、vital の関数を使う前にいくつかすることがあるのですが、それはドキュメントを参照してください。

function! s:current_git_path(path)
  let git_root = s:Prelude.path2project_directory(a:path) # ここで .git の管理するルートディレクトリからの現在のファイルパスを読み込んでいる
  return substitute(a:path, git_root."/", "", "g")
endfunction

ref: https://github.com/cat2koban/ghlink.vim/blob/2be9505c1568c18c47335fc99fabe4325dfffe10/autoload/ghlink.vim#L16-L19

おわりに

自分の中で課題と感じていることを、自分で作ったプラグインで解決する、という経験がなかったので、楽しみながら作ることができました。アルパカ隊長 さんには細かくご教示いただけて、とても感謝しています。あらかたプラグインを作る上での最低限のフォーマットは抑えられたのかなと思っているので、次は TODO をつぶしつつ、新しいプラグインの作成にも目を向けても面白いかもなと思っています。

Macbook で動かしている Rails アプリを IE11 で確認する

環境

windows 環境 (VM) の用意

VirtualBox でも Vagrant でも好きな方を選んで Microsoft の公式ページ から、仮想マシンを立ち上げるためのイメージファイルをダウンロードします。 リンク先の公式ページに行くと、以下の画像のようなボタンがいっぱい表示されていると思います。

f:id:sorehaedamame:20200607230942p:plain

今回は VirutalBox のケースで考えようと思うので、 [VirtualBox >] のボタンを押します。すると MSEdge - Win10.zip なるもののダウンロードが開始されるはずです。 ダウンロードは結構時間がかかります。なのでゆっくりお茶でも飲んで、積み本していた技術書などを消化するなどして時間を潰しましょう。

終わるまで大体3時間ちょっと程かかった記憶...とはいえ、ダウンロードが終わったら設定は楽なのですぐに環境を用意できると思います。 ダウンロードが終わったら解凍して、一旦中身を確認しましょう。画像のように、MSEdge - Win10.ovf と、MSEdge - Win10-disk001.vmdk の二つのファイルがあれば良いです。

f:id:sorehaedamame:20200607232320p:plain

次に[File > Import Appliance] から、解凍したファイルの中にある MSEdge - Win10.ovf を選択します。

f:id:sorehaedamame:20200607231140p:plain

f:id:sorehaedamame:20200607234436p:plain

そのまま [continue] を押せば、あとは VirtualBox が勝手に VM を作ってくれます。以下の画像のように、Win10 環境が作成された様子がメニューから確認できれば、一通り終わりです。

f:id:sorehaedamame:20200607231903p:plain

あとは起動して、パスワード入力画面に Passw0rd! を入力すれば Windows にログインができます。

Windows (VM) の IE11 で Railsアプリを表示してみる

Rails アプリを起動して確認する前に、IE11 ブラウザの検索窓に、 http://(確認したアドレス):(ポート番号)を 入力する必要があるため ifconfig | grep 192 とターミナルで入力し、Windows (VM) 側から Mac 側へ接続確認ができる IPアドレスを確認しておきましょう。

$ ifconfig | grep 192
    inet 192.168.50.1 netmask 0xffffff00 broadcast 192.168.50.255

確認できたら、Rails アプリを起動してみます。下記のコードは、 Procfile と言って、foreman が読み込む設定ファイルのようなものです。著者の環境では foreman という gem を利用してるので、少し起動の仕方が一般のやり方と異なります。この設定ファイルの通りだと、 bundle exec foreman start とすると、puma と, webpack-dev-server が起動します。web: の部分に書かれている --binding=0.0.0.0 の意味については、こちらの qiita の記事 が参考になるかと思います。Macbook で立ち上げた Rails を、 VM 上で開いたブラウザ (今回だと IE11) で確認する際に、設定する必要がある Rails の起動オプションなので、意味を理解しておくと良いでしょう。

web: bundle exec rails server -p 5000 --binding=0.0.0.0
client: sh -c 'rm -rf public/packs/* || true && bin/webpack-dev-server'

起動が確認できたら、早速 windows で確認してみましょう。

f:id:sorehaedamame:20200608003730p:plain

アプリのログイン画面が表記されていますね。著者が用意したアプリはログイン画面が用意されてあるのでこのようなページが最初に表示されていますが、バニラな状態の Rails アプリで試したりすると、おなじみ「Hello Rails」などのメッセージが表示されていることかと思います。

以上が、 Macbook で動かしている Rails アプリを IE11 で確認する方法でした。

coc の環境に neosnippet を導入

経緯

スニペット機能を提供してくれるプラグインを使ったことがなくて、この土日で何か良さげなのないか探していました。 そしてとあるお方に、僕は neosnippet を使っているよ!と伺い、該当リポジトリ周辺を漁っていると neosnippet-snippets なるものと一緒に使うと、導入から直ぐ楽にスニペット機能が使えそうなので、早速使ってみようと考えました。

github.com

github.com

導入

とはいえ、以前に coc.nvim を入れていたので、 一緒に使うにはどう設定するんだろう... deoplete は別に必須ではなさそうだけど、入れたほうがいいのかな....という考えもありつつ、調べてみると、 coc.nvim 用の補完ソースがいくつかある以外、特に deoplete + coc.nvim に関する記載は見当たりませんでした。(というか似たようなインターフェースを持つプラグインなので、一緒に使うこと自体レアケースと思っていますが....)

github.com

注意書きはあるものの、 deoplete 入れずにこれでできそうなので、ひとまず neosnippet から入れてみて、あとは CocInstall :coc-neosnippet として導入を進めました。

" vim-plug を使用しています
call plug#begin('~/.vim/plugged')
...
...
Plug 'Shougo/neosnippet.vim'
Plug 'Shougo/neosnippet-snippets'

call plug#end()

...
...
" ==============================================
" neosnippet 用の設定                                                                    {{{
" ==============================================

" Plugin key-mappings.
" Note: It must be "imap" and "smap".  It uses <Plug> mappings.
imap <C-k>     <Plug>(neosnippet_expand_or_jump)
smap <C-k>     <Plug>(neosnippet_expand_or_jump)
xmap <C-k>     <Plug>(neosnippet_expand_target)

" SuperTab like snippets behavior.
" Note: It must be "imap" and "smap".  It uses <Plug> mappings.
"imap <expr><TAB>
" \ pumvisible() ? "\<C-n>" :
" \ neosnippet#expandable_or_jumpable() ?
" \    "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
smap <expr><TAB> neosnippet#expandable_or_jumpable() ?
\ "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"

" For conceal markers.
if has('conceal')
  set conceallevel=2 concealcursor=niv
endif

" ==============================================
" neosnippet 用の設定                                                                    }}}
" ==============================================
:source ~/.config/nvim/init.vim
:PlugInstall 

こんなところで、スニペットを開くまで確認できました。 ( GIF ではないですが :pray: )

f:id:sorehaedamame:20200524223520p:plain

for まで入力すると、上の画像のように候補が出てくるので、 Ctrl + n で下に降りて行って... Ctrl + k とすると、以下のように展開されます。

f:id:sorehaedamame:20200524223532p:plain

んーちょっと確認してないのであれなんですけど、neosnippet-snippets から for という単語から候補が呼び込まれてるだろうと信じてます。。。

Ruby で配列の要素を展開して別の配列に格納する

TL;DR

pry[0]> arrayA = [1, 2, 3,]
pry[1]> arrayB = [4, 5]
pry[2]> arrayA.push(*arrayB)

=> [1, 2, 3, 4, 5]

経緯

配列の中に要素を展開して入れて欲しいときはどうしたら... ある時ふとそんな気持ちになりました。

pry[0]> arrayA = [1, 2, 3,]
pry[1]> arrayB = [4, 5]
pry[2]> arrayA.push(arrayB)

=> [1, 2, 3, [4, 5]]

そこでいろいろ調べてみるとこんな記事が見つかりました。 一番上の記事は、 ruby 配列 要素 展開 [検索] とかで調べた記憶があります。

qiita.com alpaca.tc scrapbox.io

結論

push する配列に splat operator (*) なるものをつけてあげるだけで良さそう

pry[0]> arrayA = [1, 2, 3,]
pry[1]> arrayB = [4, 5]
pry[2]> arrayA.push(*arrayB)

=> [1, 2, 3, 4, 5]

coc.nvim と vim-endwise でちょっとだけハマった

TL;DR

github.com

環境

Plug 'itchyny/lightline.vim'
Plug 'ryanoasis/vim-devicons'
Plug 'scrooloose/nerdtree'
Plug 'previm/previm'
Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'tpope/vim-endwise'
Plug 'neoclide/coc.nvim', {'branch': 'release'}

経緯

勧められたのもあり、気になっていた coc.nvim と呼ばれるプラグインを使い始めたところ、ちょっとだけハマったことがあったので、記録しておこうと思います。 今思えば、公式リポジトリの README を雑に読みながら動かした事が原因だったなと ... :(

github.com

どこでハマったのか

公式の README には丁寧にも、 example-vim-configuration なるものがあります。 !important とコメントがあるのですが、そこを読まずに内容を丸々コピペして、動かしてみたら、 vim-endwise で設定されているキーマップと、以下のコピペした一部分の設定内容が、コンフリクトを起こした次第です。

コピペした内容の一部

" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current   
" position. Coc only does snippet and additional edit on confirm. 
" <cr> could be remapped by other vim plugin, try `:verbose imap <CR>`.   
if exists('*complete_info')   
  inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"  
else  
  inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>" 
endif

vim-endwise のコード ~/.vim/plugged/vim-endwise/plugin/endwise.vim+133

if !exists('g:endwise_no_mappings')
  if maparg('<CR>','i') =~# '<C-R>=.*crend(.)<CR>\|<\%(Plug\|SNR\|SID\)>.*End'
    " Already mapped
  elseif maparg('<CR>','i') =~? '<cr>'
    exe "imap <script> <C-X><CR> ".maparg('<CR>','i')."<SID>AlwaysEnd"
    exe "imap <silent> <script> <CR>      ".maparg('<CR>','i')."<SID>DiscretionaryEnd"
  elseif maparg('<CR>','i') =~# '<Plug>\w\+CR'
    exe "imap <C-X><CR> ".maparg('<CR>', 'i')."<Plug>AlwaysEnd"
    exe "imap <silent> <CR> ".maparg('<CR>', 'i')."<Plug>DiscretionaryEnd"
  else
    imap <script> <C-X><CR> <CR><SID>AlwaysEnd
    imap <CR> <CR><Plug>DiscretionaryEnd
  endif
  autocmd endwise CmdwinEnter * call s:teardownMappings()
endif

何が起きたか

Enter を押すと改行されずに complete_info()["selected"] != "-1" と言う文字列が入力されるようになりました。

解決方法

解決方法としては、被ったマッピングの設定を解消してあげるだけで良さそうです。今回、私は ただただ公式の README からコピペしたマッピングの設定 を一旦削除することで対応しました。 削除しなくても、 以下のような設定を追記するだけで、コンフリクトの解消ができるみたいです。

let g:endwise_no_mappings = v:true
inoremap <expr> <Plug>CustomCocCR pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
imap <CR> <Plug>CustomCocCR<Plug>DiscretionaryEnd

とりあえずコピペした内容を消して、vim-endwise 側の設定も触らず、公式の wiki にあった以下の設定と、コピペしていたマッピング以外の設定を入れておきました。

Completion with sources · neoclide/coc.nvim Wiki · GitHub

" coc.vim -------------------------------------------------------
set hidden
set nobackup
set nowritebackup
set cmdheight=2
set updatetime=300
set shortmess+=c
set signcolumn=yes

inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
" ---------------------------------------------------------------

そして、補完候補が見れるようになりました。 Tabで一個下の候補を選択できて、Shift を押しながら Tab で一個上の候補を選択できるようになりました。

f:id:sorehaedamame:20200510010642p:plain

あとはコピペした設定が実は何をしようとしていたのか等を見つつ、 coc.nvim の設定を充実させていけたらなと思っています。