蚊帳の中の日記

ゆるく生きてます

"相談できる"って素晴らしい

仕事のことで先輩や上司、同僚に相談して、結果、問題を解決できないこともあるけれど、話したことによって自分の頭の中の整理になったり、意外と足したことがないかもって思えたり、なにか対応策を練ることができたりして、自分の心が穏やかになることがこんなにも素晴らしく、気持ちのいいこなのかとココ最近になって再認識できた。そして、そういう環境に身を置かしてもらっているということに改めて感謝したい気持ちになった。

まだ転職して4ヶ月くらいだけれど、会社の風土としても相談しやすい雰囲気が出ているし、相談したら先輩も色々教えてくれる。上の方々も色々とそういった環境づくりに気を配ってくれていて雰囲気があって、とてもいいな。やりやすいなと思った。今日もちょっと困り事をあって相談をさせてもらったのだが、他のエンジニアの方なども巻き込んで色々と解決方法などを講じてくれたりして、とても有難かった。先輩エンジニアの方々も自分の問題点を解決するための提案や今後の進め方を提示してくれたし、本当に感謝だし、同時にもっと頑張らねば!と思えて、なんか勝手に活気が湧いた。

前職で働いていた会社は正直そういった環境はなくて、個人的には仕事の進め方を考えたりすることもきつかったし、メンタル面でも結構きつかった(その会社では新卒で入社仕立てで色々青二才なところもあって、自分の相談の仕方が悪かった面もあるのかも知れないけれど)。メンタル面でキツかったというのは、相談をしても「え?何お前そんな事も知らないの?」「そのくらい自分でなんとかしろよ」という雰囲気が蔓延(少なくとも自分はそう感じた)していて、実際に相談や質問をしにいっても今表現した言葉をそのまま浴びせられることが多かった。個別で言われることもあったのだけど、これを部署会議や全体会議のような人が多くいる前でやられることもちょくちょくあった。
そのくらいで弱音はいてんじゃねーよと思う人もいるかも知れないけど、自分にはそれがひどく耐えられなかった。で、よくあるダメ新卒の負のパターンみたいになって、相談しにくい→抱え込む→仕事が滞る→怒られる→メンタルダメージみたいなことが毎日とまでは行かないけれど、ちょくちょくあった。まあそれ以外のこともあったりして、今の会社に転職を決意したわけ。。。。

ちょっと話がそれた。。。。相談できるって素晴らしい!って話に戻る。本当に相談ができて、みんなで問題点などを共有し、一緒に解決するために考え、行動できるということが如何に心強いと言うか、心を穏やかにするのか再認識する日がここ最近多かったので、言葉に書き留めたくなった次第。これは人任せにするということで楽になるとかではなくて、(一緒に働いている凄いエンジニアの方や上司の方の受け売りなのだが)責任をみんなで共有してみんなで解決の道を探り実行するみたいなイメージ。「一人で抱え込まないで、みんなでやってるんだから相談しましょう!」とか「わかんなかったら聞きましょう!数秒考えてわかんなかったら、すぐ質問したり意見するくらいが良い。意見したり質問することは悪ではない」とか、みんなそういった話を熱を込めて言うし、「こういった考え方ができるのか。。。」と正直、カルチャーショックだった。(転職仕立てだから今だけ優しいだけかな。。。とか思ってしまってたけど(笑)、他の人の雰囲気とかを見てもそういった感じではなさそう。)

こういった相談できたりする環境ができるのは、相談できる人がいるなど環境が整っているからとも言えると思っている。今の自分はほとんど相談して助けてもらっている側の人間。早く実力をつけて、みんなから相談され、解決策を提案したりして指南できるオジサンにならねば!と思った次第である。

render :json でmodelメソッドの処理結果をjsonに追加して返したい

railsでは一般的なやり方なのかどうかわからないけれど、とあるrails apiの処理を読んでいる時にちょっと見慣れないコードがあったのでブログに書いてみる

例えば

def index
  user = User.find(id)
  render json: user
end

これはよく見るコードで、こんな感じでActiveRecordで見つけてきたuserオブジェクトの結果をjson形式で返す。
この場合、Userでnameやらidやら定義されている(?)パラメータしかjsonで返すことができず、「定義されているAttributesだけだとレスポンス受け取り側がわかりづらい事があるかもしれないので、他のAttributesを追加して返したい」とか、ちょっとjsonをイジってから返したいという時にちょっと困る。

この問題を、今回見つけた見慣れないコードが解決しいた。以下、サンプル。

def index
  user = User.find(id)
  render json: user, methods: [:auth?]
end

Userのモデルにdef auth?が定義されていて、その結果をrenderで返すjsonに加えている処理になっていた。

こちらのサンプルだと、auth?で真偽値を返すメソッドで{.....user attribute..... , auth: true }みたいに追加される。 最初見たときのこのメソッドがfalseだったらrenderが実行されないとか、そういう処理なのかな???とか思っちゃたりして挙動がはっきりわからなかったので困惑した。 自分をメンターしてくれてる先輩エンジニアにも相談して、railsのコード読んでどこに定義されてるのか探してみたけど、ぱっと見つからなかった(TODO: これは後で探そう)。

ググったりrailsドキュメントでもrenderにmethodsオプションはない。stackoverflowにはちょっと関連の記事はあったけど。

stackoverflow.com

こっちはちょっと話題が違うかもだけど、同じような感じでmethodsオプションを利用している。

stackoverflow.com

モモンガ本でマークエディタを作ってみた

会社でVue.jsを勉強していて、「firebaseとかと連携してSSRみたいなサービスも作ってみたいんですよね〜」って話したら、モモンガ本っていうのがあると聞いて、休みの日を利用して作ってみた。vue.jsでドキュメントとか見ながら学習するのも、ちょっとずつ飽きてきてたのでちょうどよかった。

booth.pm

↓ こんな感じでスタイルとか雑で、色々できてないところもあるけど、googleログインによる認証機能とか、firebase raletime databaseを使ってメモの保存とかも最低限はできた。

ドキュメントの復習にもなったし、ちょうど課題問題みたいなのも入って勉強になりそう。仕事終わりはコイツを育てつつVue.jsの勉強を進めて行きたい。

Rubyのsuperキーワード

よく親クラスを継承したサブクラス内のメソッドで、superを使っている。用途としては親クラスにある同名のメソッドを呼び出すためのキーワードなのだけど、Rubyを触り始めて間もない自分にはなんだか見た時に「なんだっけ」ってなるので、備忘録して用途など残しておいた。

superキーワードは親クラスの同名メソッドを呼び出す(オーバーライドされてる)

class Dog
  attr_reader :name
  
  def initialize(name)
    @name = name
  end
end

class Bulldog < Dog
  attr_reader :sex
  
  def initialize(name, sex)
    super(name, sex)
    @sex = sex
  end
end

instance = Bulldog.new('ブルちゃん', 'オス')
instance.name #=> "ブルちゃん"
instance.sex #=> "オス"

こんな感じで同名のメソッド(ここではinitialize)の親クラスを呼び出す事が可能(もうちょいい言うと、オーバーライドしているメソッドで親クラスのメソッドを呼ぶって言ったほうが正しいのかも)。もちろん、メソッド名が違ったら、superが親クラスから同盟メソッドを探し出せなくてエラーになる。 結構このsuperというキーワードに親クラスの処理が入っているので、最初見た時に「何だこれ?なにをしてるんだ??」って面食らう時が個人的に多かった。最近は慣れてきて、「あー親クラスの処理をcallしてるんだな。詳しくは親クラスを見ろってことか」となり、親クラスの調査をしだすようになれた。

今回の場合、親クラス(Dog)のinitializeメソッド子クラス(BullDog)のinitializeメソッド引数が異なるので、super(name, sex)とキーワードに引数を渡す必要あった。 しかし、親と子の引数が同じ個数なら、superと引数無しで書けば、親のinitializeが呼び出される。つまり、superとだけ書いてあったら、メソッド名と引数の個数が同じ親クラスのメソッドが呼ばれとんのやなと覚えておく。これも慣れるまで個人的にちょっと時間がかかった。

...省略...
class Bulldog < Dog
  attr_reader :sex
  
  # これでclass Dogのinitializeが呼ばれる。
  def initialize(name)
    super
  end
end

instance = Bulldog.new('ブルちゃん')
instance.name #=> "ブルちゃん"

※ あと、子クラスにattr_reader :name, :sexって書かなくていいのか?と思うかもしれないが、親クラスで定義しているので不要。これは継承が関連してると思う。

super()は引数無しで親クラスを呼ぶ

super()と呼ぶと、親クラスの同名メソッドを引数なしで呼び出すことになる。 多分、これはほとんど使う機会がない気がするのだけど一応メモ。

追記 こちらの記事の「super vs super()」に、親クラスの引数は引き継ぎたくない時に使えるかも。 (話逸れるけど、この記事の翻訳元の最初の章のコード、あまり良くない気がした。親クラスと子クラスの処理が変わらなければ、そもそも子クラスにsuperとかメソッドの再定義をする必要がない。チェリー本 p.243を参照すればわかる)

追記2 最近知ったイディオム何だけど、Rspecでletやsubjectオブジェクトの中身を「ちょっとこのexampleでは変えたい」って時に、super()を便利そうだった

# 引用元:http://rspec.info/blog/2013/02/rspec-2-13-is-released/

describe Array do
  let(:numbers) { [1, 2, 3, 4] }

  context "when evens are filtered out" do
    let(:numbers) { super().reject(&:even?) }
  end
end

super.tap{}のイディオムが便利そう

superというよりtapメソッドを利用したイディオムだと思うので、少し表題とは逸れる気がするけれど、gemのコードを読んでる時によく見るイディオムがあった。便利そう。

さっき言った方にsuperはスーパークラスの同名のメソッドを呼び出す際に使うが、それを呼び出した返り値を色々いじりたいという時に、tapを使うと「あ、superで返ってきた値をいじってるんだな。。。」とわかりやすいコードになるかも。

class Hoge
  def hoge
    1 + 1
  end
end

class Fuga < Hoge
  def hoge
    super.tap do |result|
      @result = result + 1
    end
    
    puts @result
  end
end

fuga = Fuga.new
fuga.hoge # => 3

(あんまりいい例じゃないけど).tapを使わないときはsuperで返した値をなにか変数にいれるかして、色々処理を書かないといけないけど、このtapを使えば、superを入れておくローカル変数を減らすこともできるし、tap内にsuperの返り値を変更する処理をまとめることができて少しコードの見通しが良くなる効果もありそう。「あーsuperで返ってきた値変更したいな〜」って時に便利。

参考文献

開発中にいろいろ思い込みが激しいのをどうにかしたい

開発してるときに、とある機能やライブラリなどを調査して、「なるほど!〜〜になってるから、〜〜みたいに実装すれば良さそう!」とかなって、いざ開発してみると「あれ??動かない。。。なんで。。。〜〜の通りにやってるのに!」とか、「〜〜してるんだから間違いないはず」って結構思い込むことがある。 これで時間食って、改めてよく見てみると単純な間違いに気づく。疑問を常に持って、よく見れば回避できそうなのに。。。

で、最近この類の問題から脱却しようと思って以下を実践している。

「本当か??」と自問自答を3回〜5回唱える

とある実装をして満足せずに、一旦やり終えたら自分のやったことが間違ってないか?おかしな勘違いをしていないか自問自答するのだ。「ほんまか?」と口にだすのも良さそう。

勝手な印象だけど、いままで会ってきた出来る先輩エンジニアの方々の行動に目を向けてみると、「ほんとか?」っと口に出したりして、自分の行いを再確認しているパターンが多い。実装や頭の中の再整理にもなるし、個人的に開発の良い習慣になっている気がするので続けていきたい。

Vueチュートリアル 3日目

https://jp.vuejs.org/v2/guide/components-registration.html

  • コンポネントの登録
  • 復習:コンポネントは名前付きで再利用可能なvueインスタンス
  • そのままVue.component({...})とかするとグローバルなインスタンスの登録になる。しかし、グローバルだとwebpackなどのバンドラーみたいな機能を使っている時に使わない場面で余計にインスタンスを読み込んじゃうみたいなことが起きるのでよろしくない。
  • グローバルではなくローカル登録を心掛ける。こんな感じ
  • ちなみにcomponentの命名はキャメルケースでも、パスカルケースでもどちらでもいいけど、パスカルケースで書くと、実際にcomponentを使うときキャメルとパスカルどちらでも使えるようになる。まあ迷うから基本的にキャメルケースに統一したほうが良いと思うけど。
  • ローカル登録されたコンポーネントは、他のサブコンポーネント内で使用できない。。。らしい。
var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}
  • モジュールシステムもある(小並感)。

https://jp.vuejs.org/v2/guide/components-props.html

  • propsはキャメルケースで書いて、実際に使用するときはケバブケース。
Vue.component('blog-post', {
  // camelCase in JavaScript
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
<!-- kebab-case in HTML -->
<blog-post post-title="hello!"></blog-post>
  • prop validation 超便利そう。defaultとかrequiredとか型バリデーションとかカスタムバリデーターみたいなのとか。
  • passing static <sample title='hoge'></sample>
  • dynamic props <sample v-bind:title='post.title'></sample> もしくは<sample v-bind:title="post.title + 'by' + post.author.name"></sample>。こんな感じで文字列連結みたいにもかける。
  • one-way data flowの英語がよくわからない、、、??
  • prop validationは、componentインスタンスを作る前にバリデーションをする。そのため、dataとかcomputedみたいなインスタンスオプション内ではdefaultvalidator関数は使えないことを覚えておこう。
  • Non-Prop Attributesの節はメリットが良くわからなかった。和訳も上手くできなかった。また読み返す。

https://jp.vuejs.org/v2/guide/components-custom-events.html


やっとcomponentとかが使い方わかってきた気がする。 簡単なTODOアプリを作成しながら学んでいる最中。これをfirebaseとか連携すればちょっとしたTODOアプリは実使用できそうだけど、いかんせんfirebaseがまだわかってないのでそっちも勉強してみる所存。 PracticeVue/test/todo at master · kayawari/PracticeVue · GitHub

Vueチュートリアル 2日目

今日はイベントハンドリングコンポネントの基本まで行きました。

https://jp.vuejs.org/v2/guide/events.html

  • イベントハンドリングはv-onディレクティブ
  • v-on:click='hoge'みたいにかける。hogeの部分はメソッドでもいい。ちょっとした実行分も書けるけど冗長になるので基本的にメソッドに切り出すのが無難だと思う。
  • $eventでDOMイベントを取れる。
  • イベント修飾子なるものが、非常に便利そうな匂いを醸し出しているけれど、まだよくわかっていない。あとイベント修飾子passiveがまだよくわかっていない。
  • キー修飾子もある。
  • HTMLにこういうリスナを書くことはHTMLのテンプレートを眺めていれば「どういったイベントが発生するのか」わかりやすくなるという主張はなんとなく納得できた。

https://jp.vuejs.org/v2/guide/forms.html

  • inputやtextareaみたいな入力内容のバインディングv-modelでできる。(勝手にv-inputとかが良いじゃないのか?なんでもmodelなんだ?と思ったけど、もっと勉強すればわかってくるのかな?)
  • textarea以外に、checkbox, selectboxなどにも使えて、valueバインディングすることもできる。
  • 修飾子.lazyは使えそう。
  • あと地味に修飾子numbertrimは、入力内容の余計な情報のトリミングに非常に役立ちそうな予感がした。

https://jp.vuejs.org/v2/guide/components.html

  • componentの基本として、componentは名前付きの再利用可能なvueのインスタンスだということ。なので、hogeってcomponentを作って、一つのHTMLにhogeタグを3つ作ってもそれぞれ独立したインスタンスだということ。これは重要なことだと思う。そのhogeがなにかミュータブルな値を保持するコンポーネントだとして、インスタンスが別なので値を共有することはないということになる。
  • dataには関数でなければいけない
Vue.componet('hoge', {
  data: function () {
    return {
      count: 0
    }
  }  
})

dataオプションの中は関数でないといけない。

  • componentは利用に当たりグローバルで登録するのと、ローカルで登録するの2種類がある。いままでの書き方はすべてグローバルな登録。
  • componentはツリー構造になっている。
  • 子のコンポネントに値を受け渡したいときはpropオプションを利用する。
  • 単一ルート要素???
  • イベントとメッセージは親のコンポネントに送ることができる。使いみちがぱっと思い浮かばなかったけど、リストをいっぺんに変更するとかそういう場面で使えそう。
  • 親コンポネントにイベントを送出する場合は$emitメソッドがいいらしい。
  • componentでv-modelの使い方
  • 動的コンポネント
  • tableの中で使うtrみたいな特殊なケースで使われるタグ内でcomponentを使う場合はisを使う。
<table>
  <tr is="blog-post-row"></tr>
</table>

こういったケースが関連しているのが、文字列テンプレート、単一ファイルコンポーネント、scriptタグ。。。。らしい。よくわかってない。


ここまでできたので、Todoアプリでも作りたい所存。