ベルリンのITスタートアップで働くジャバ・ザ・ハットリの日記

日本→シンガポール→ベルリンへと流れ着いたソフトウェアエンジニアのブログ

英語圏のITスタートアップにおいて日本人であることの唯一のメリットを転職で活かす方法

もうぶっちゃけて言ってしまえば英語圏のITスタートアップで働く場合に日本人であることのメリットなんてほとんど無い。日々の業務で実感できることなんて皆無だ。ほとんどの情報は英語で発信されているし、会議もランチ中の会話も英語。ジリ貧状態の日本市場と同じように昔は存在したかもしれない日本語話者のメリットも低下しっぱなし。その代わりに英語の重要性だけが急上昇を続けている。

そんな中で本当に日本人であることのメリットだな、と実感できたことはこれ。

Rubyを作ったまつもとゆきひろ氏が日本人であること。

これは応募書類の技術欄に「Ruby」と書いた場合に限られるが、転職の面談時に意外にイケる。全ての日本のRubyに関わるエンジニアはまつもと氏に感謝しなければならない。

例えばリネオル・メッシという世界最高のサッカー選手がアルゼンチン出身というだけで「アルゼンチン人=サッカー上手い」の印象が人々に刷り込まれている。アルゼンチンにいるその辺の普通のオッサンがみんなサッカーが上手い訳ではない。ちゃんとサッカーのトレーニングをしたモンゴル人の方が普通のオッサンより上手いはず。でもメッシ効果による「印象」というものがあって、仮に今日の草サッカーの対戦相手がアルゼンチン人(普通のオッサン)となると、「何?アルゼンチン人?そいつ上手いのか?」と警戒することになる。それと同じこと。

まつもと氏が日本人であることを活かすには面談の際にこう言うのだ。
「ご存知のようにRuby作者のMatz(まつもと氏の英語名)は日本人なんだよね。もちろんRubyの言語仕様やドキュメントは英語だけど、それ以外の本当に興味深い内容が本人から日本語で発信されてるんだ。例えばMatzの思想や言語仕様に採用される前段階のアイデア考え中みたいな話があるんだよ。それらは未来を予想してて参考になるんだよねー(ただし「日本語が読めれば」という余韻を残す)」

今までこの話をして食いつかなかった非日本人のエンジニアは居ない。彼らにとって漢字かな混じりの言語は私達にとってのナメック語みたいなもんなのだ。とにかく意味不明で神秘的ですらある。
f:id:tango_ruby:20160712144616j:plain
そんな意味不明な言葉で書かれた内容からRuby言語の未来が分かる、なんて言われたら「オレはそんなの読めないし想像もできない。一体なんなんだよ?」となるに決まっている。

で、その次にまつもと氏のインタビューの中から自分のお気に入りの一節を引用すればOk。例えばこんなの。

「エンジニアの未来が袋小路に陥らないよう「多様性」の重要性を言い続ける」(前編)Ruby言語開発者 まつもとゆきひろ 氏 |ギークアカデミー |IT・Web業界の転職ならDODAエンジニア IT

多様性が許容できなければ、Rubyも許容できない、ということがあります。すでにPerlがあるのに、なんでRubyを作るんだ、と言ってくる人もいるわけですから(笑)。
その上で、多様性の重要さを考えると、まずエンジニアという種族は局所最適化を求めがちです。でも、それによって大局的に危険な袋小路に陥ることがある。われわれの心理が、放っておくと「選択と集中」や局所最適化に向かってしまう傾向にある。私自身もそうです。
新しい試みの大半はうまくいかないわけです。だから多様性はコストです。でも、どの試みがうまくいくのかは事前には分からない。「このサービスは必ず成功する」とはいえない。
放っておくと集中しちゃう。だからこそ反対の事を大声で言わないといけない。

ホントのところはこれと同じ話は英語版でも出ている。でもそんなのいちいち指摘する奴はいない。日本語話者のメリットを最大限誇張して活かすのがポイント。
まつもと氏の考え方をインタビュー記事で読むと、どれもが独創的で面白いから、上記のような話は2,3個すぐに用意できる。それらを英語で話せるようにしておけばOk。何社か面談を受けて同じ話を繰り返せば漫才師のネタ合わせみたいに話が洗練化されて上手くできるようになる。

ということで「英語圏のITスタートアップにおいて日本人であることの唯一のメリットを転職で活かす方法」でした。

<追記>
なんとご本人から「ご活用ください」と。ありがとうございます。
ご本人に読んでいただけるのなら、こんな軽いのじゃなくて、もっとRubyの思想に深く踏み込んだ内容を書くべきだったかも。。。
f:id:tango_ruby:20160714114957p:plain:W400



tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com


はっきり言う。コードレビューが嫌いだ。そしてその理由が分かった

だいたいどこでもコードレビュー絶賛中だ。「コードレビューで知識を共有できる」「クオリティが上がる」「開発者が成長できる」といいことずくめみたいに言われている。そうしたメリットを分かった上で言う。

コードレビューが嫌いだ。GitHubにあがったPRを黙って見て、そこにコメントを書き込む形式のレビューはOk。むしろ好きかもしれない。本当にクオリティは上がるし、貴重な成長の機会でもある。ここで言ってるコードレビューとは面と向かって、話しながらやるレビュー。アレが嫌い。

あの種類のコードレビューはとにかく疲れる。レビューが終わった瞬間なんて疲労困憊でもうその後、働く気にもならないし、コードエディタなんて観たくもなくなる。そして本書を読んでその理由が分かった。

すべての疲労は脳が原因 (集英社新書)

すべての疲労は脳が原因 (集英社新書)

本書より

研究によれば4時間、体に不可を与える運動を続けても、実は筋肉や肝機能などにはほとんど影響しないことがわかっています。では疲れていないのになぜ「体が疲れた」と感じるのか。その答えは「脳の自律神経の中枢」にありました。

実のところ疲労とは何かはまだよくわかっていないらしい。
ただ今まで疲労は筋肉を動かして出る乳酸が原因だといわれていたが、これは間違い。疲労の原因は筋肉ではなく、体内でもっともエネルギーを消費する器官、脳なのだ。集中して作業するときは、体をコントロールする自律神経に負荷がかかり、活性酸素が増えて酸化物をつくるのが原因。

これで私がコードレビューが大嫌いな原因が分かった。とにかく疲れるのだ。頭をフル回転させて、他人のコード(たまにクソコード)を読み、それを言葉に最大限気を使いながら説明していくのだ。これが本当に疲れる。そこまでエネルギー使ってやる意味あんのか?といつも思う。

このサイトはとても有用だ。
コードレビューで気をつける言葉や行い - macotox’s blog

否定しない
def get_name(name)
 @user.find(name: name)
end
☓:getは軽量なアクセッサとして使うのが常識なのでやめて下さい。
◯:findしてることが分かるメソッド名が良いです

もうここに書かれていることは大いに賛成でその通りだ。で、もしこれを英語圏の職場でこの言語レベルで気を使いながら英語で指摘するところを想像していただきたい。だいたい非ネイティブにとってみたら普通の英語の会話ですら、ある程度の負荷が脳にかかっている。それを「常識なのでやめて下さい」じゃなくて「分かるメソッド名が良いです」というレベルの差異に注意して英語で言え、と。上記のようなコードレビューにおける言葉使いの注意点については英語のブログでもよくある。やはり英語圏でもコードレビューでえらい気を悪くして、職場の空気が微妙になることがもちろんのようにあるのだ。
さらにそれだけじゃない。そうして英語しゃべりながら、わずかに残った脳内領域を使って、そこでコードのこと考えて指摘しろ、と。普通に黙ってコードをタイプするだけだったらサラッといくけど、この状況でやれと言われるのが本当にキツい。
また妙に相手がコードレビューにノリ気(もしくは本心がイヤでも表面上ノリ気を見せるタイプ)だともうしばらく放置した死体みたいな状態になってレビューしている。

自律神経がフラフラになって脳を酷使してまでやることかね?使うエネルギーに伴う疲労の割にメリットが少ない。メリットがあるのは分かっている。指摘しているのはメリットの有り無しではなく、そのエネルギー効率の低さだ。コードレビューってエネルギー効率が悪くね?
とにかく私はコードレビューが嫌いだ。この「嫌い」という感情だけははっきりさせたい。ハッキリさせたからといってコードレビューの数が減るとは思えないが、書いた。

もし同じご意見をお持ちの方がいらっしゃったら本書を読んで論理武装をした上で「コードレビュー嫌いだ!やめー!理由は疲労というものはだなー」と言ってみてください。

すべての疲労は脳が原因 (集英社新書)

すべての疲労は脳が原因 (集英社新書)


tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com



初心者でもカンタンにRailsの中身のコードをコードリーディングする方法

ここで言う「Railsの中身のコード」というのはRailsを使ったRailsアプリのコードのことではない。Railsそのもののコード。DHHが書いたRailsのコード。$ rails new AppNameとかのコマンドが動く仕組みが書かれたコードのこと。
これって職場の同僚と英語で話しててもいっつもゴチャゴチャと説明が要る。RailsアプリのコードとRailsの中身のコードを区別してそれが一発で分かってもらえる表現があったら教えて欲しい。

既にご存知の方はたくさん居ると思うがそのRailsの中身のコードというのが巨大でなかなかにレベルが高い。初心者では読むのも一苦労でそこが遠ざけてしまう原因にもなっている。それでも優れたコードをコードリーディングすることはエンジニアにとってとてもいい勉強になるのでオススメ。

いかにコードリーディングが重要かは、いろんなブログなんかで優秀なエンジニアの方々が再三強調されている。

例えば

まつもとゆきひろのハッカーズライフ:第10回 ソースを読もう (1/2) - ITmedia エンタープライズ

ハッカーとしての能力を身に着けるのに優れた方法は、実際にコードを書くことと、ほかの人の書いた優れたソースコードを読むことだと思います。特にコードを読むことは普段あまり強調されませんが、他人のソースコードはいろんな意味で知恵と知識の源です。考えてみれば、わたし自身も他人のソースコードをたくさん読んで学んだように思います。

プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き) - Qiita

熟練したプログラマだと、「何かあったらコードを読む」を習慣づけている人も多いです。
gemやフレームワークのコードを読むのは初心者の人には敷居が高いかもしれないが、こうしたスキルものちのち必要になってくるはず。早い内から慣れておく方が良い。

ペアプログラミングして気がついた新人プログラマの成長を阻害する悪習 - Qiita

なぜ、フレームワークのコードを調べないのか、問うたところ、「むずかしそうだから。早く終わらせたいから」ということらしかった。確かにフレームワークは複雑化していたり、全体を把握するのが難しいところはある。
しかし、それを読んでいくなかで、言語機能やライブラリを理解したり、知識が広がっていく。
この心理的抵抗を取っ払いコードを読んでいくことで、問題が早く解決するという経験をさせることが重要だ。


そうそう。とにかく質のいいコードを読みましょう、と。

カンタンにRailsの中身のコードをコードリーディングする方法

今回はRailsモデルのValidationの中身がどのように実装されているかをコードリーディングする。これはまつもとゆきひろ氏も言うように「全体を通して読む必要はありません。面白そうなところをつまみ食いして」にならっている。全部読むとか無理だし、モデルのValidationだったら、ほぼみんな知っていて馴染みがあると考えて選んだ。

class User < ActiveRecord::Base
  validates :name, length: { maximum: 30 }
end

とした場合にどうやってnameの長さが30未満だけを受け付けて、30以上だとエラーを返しているのかを見る。

Railsをフォークして自分のアカウントに入れる

1. Railsのリポジトリーのページへ行く
GitHub - rails/rails: Ruby on Rails

2. 右上にあるForkボタンを押す。
f:id:tango_ruby:20160628224245p:plain:W400

3.すると自分のアカウントにRailsが入ってくる。
f:id:tango_ruby:20160706130020j:plain:W300


4. クローンしてローカルに入れる。
自分のアカウントに入れたRailsで左上にある緑のボタンを押す。
git@github.com:<自分のアカウント名>/rails.gitをコピー
f:id:tango_ruby:20160701184627p:plain:W400

$ git clone git@github.com:<自分のアカウント名>/rails.git

とするとローカルにRailsが入ってくる。

5. これから読むつもりのモジュールのREADMEを確認しておく。できればIssueなんかも確認しておくを尚よし。
今回はActive Model
f:id:tango_ruby:20160701205554p:plain:W300

確認用のRailsプロジェクトを作る

1. Rails new する

$ rails new CodeReading

2. 以下のようなフォルダ構成になっているはず

..
|+CodeReading/
|+rails/

3. CodeReading/Gemfileを編集する
pryで処理を止めて確認するのでpryを入れる。
railsはpathを設定して先ほど入れたローカルのrailsを参照するようにする。バージョンは最新版。

# Gemfile
source 'https://rubygems.org'

gem 'rails', path: '../rails'
gem 'pg'
gem 'pry-rails'
gem 'pry-doc'
gem 'pry-byebug'
gem 'byebug'

4. bundle installする

$ bundle install

5. Userモデルを作る

$ rails g model User name:string

6. Userモデルを編集してValidationを入れる
validatesの前にbinding.pryを入れて止まるようにしておく。

class User < ActiveRecord::Base

binding.pry
  validates :name, length: { maximum: 30 }
end

これで確認用のプロジェクトは完成。

コードを読む

1. rails cを実行して、そこからテキトーなnameの入ったuserを作成すると、binding.pryで止まる。

$ rails c
[1] pry(main)> u = User.new(name: 'sample name')

From: /app/models/user.rb @ line 4 :

    1: class User < ActiveRecord::Base
    2: 
    3: binding.pry
 => 4:   validates :name, length: { maximum: 3 }
    5: end

2. step で中に入ると、ローカルに入れたRailsの該当コードに行く。

[1] pry(User)> step

From: /rails/activemodel/lib/active_model/validations/validates.rb @ line 105 ActiveModel::Validations::ClassMethods#validates:

    104: def validates(*attributes)
 => 105:   defaults = attributes.extract_options!.dup
    106:   validations = defaults.slice!(*_validates_default_keys)
    107:
    108:   raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
    109:   raise ArgumentError, "You need to supply at least one validation" if validations.empty?
    110:
    111:   defaults[:attributes] = attributes
    112:
    113:   validations.each do |key, options|
    114:     next unless options
    115:     key = "#{key.to_s.camelize}Validator"
    116:
    117:     begin
    118:       validator = key.include?('::'.freeze) ? key.constantize : const_get(key)
    119:     rescue NameError
    120:       raise ArgumentError, "Unknown validator: '#{key}'"
    121:     end
    122:
    123:     validates_with(validator, defaults.merge(_parse_validates_options(options)))
    124:   end
    125: end

これで/rails/activemodel/lib/active_model/validations/validates.rbの104行目にvalidatesが定義されていることが分かる。詳しく見るなら直接validates.rbのファイルをエディタで開く。

104: def validates(*attributes)
105:   defaults = attributes.extract_options!.dup
106:   validations = defaults.slice!(*_validates_default_keys)

105行目の処理はattributesにextract_options!をして、柔軟な引数の指定に対応できるようにしている。
例えば今回のattributes はこのようになっている。

[1] pry(User)> attributes
=> [:name, {:length=>{:maximum=>30}}]

これにextract_options!を実行すると{:length=>{:maximum=>30}}となる。
extract_options!の定義元に行くとソースコードはこれ。

class Hash
  # By default, only instances of Hash itself are extractable.
  # Subclasses of Hash may implement this method and return
  # true to declare themselves as extractable. If a Hash
  # is extractable, Array#extract_options! pops it from
  # the Array when it is the last element of the Array.
  def extractable_options?
    instance_of?(Hash)
  end
end

class Array
  # Extracts options from a set of arguments. Removes and returns the last
  # element in the array if it's a hash, otherwise returns a blank hash.
  #
  #   def options(*args)
  #     args.extract_options!
  #   end
  #
  #   options(1, 2)        # => {}
  #   options(1, 2, a: :b) # => {:a=>:b}
  def extract_options!
    if last.is_a?(Hash) && last.extractable_options?
      pop
    else
      {}
    end
  end
end

ここでやってることはとても単純。配列の最後の要素がis_a?(Hash)かつ instance_of?(Hash) なら、配列の最後の要素(Hash)を取り出す、そうでなければ空の Hash を返す。

そうして取り出したハッシュをdupしてdefaultsに代入している。dupする理由は後でdefaultsを変更した際にそれがattributesに影響しないようにするため。

105:   defaults = attributes.extract_options!.dup


106行ではslice!を使ってvalidationsとその条件式を分けている。

106:   validations = defaults.slice!(*_validates_default_keys)

_validates_default_keysの内容は下の方のコードで定義されている。

protected
 
  # When creating custom validators, it might be useful to be able to specify
  # additional default keys. This can be done by overwriting this method.
  def _validates_default_keys # :nodoc:
    [:if, :unless, :on, :allow_blank, :allow_nil , :strict]
  end

つまりご覧のように条件式が付いていたら分ける、ということだ。
今回の例でもし条件付きにして

validates :name, length: { maximum: 3 }, unless: "name.nil?"

としていたら、attributesに条件がHashになって入ってくる。
そして106でslice!すると

[1] pry(User)> validations
=> {:length=>{:maximum=>30}}
[2] pry(User)> defaults
=> {:unless=>"name.nil?"}

とみごとにvalidationsとdefaultsにそれぞれが代入されて分かれる。

108,109行では読んで字のごとく、attributesやvalidationsが空だったらArgumentErrorをraiseしている。

108:   raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
109:   raise ArgumentError, "You need to supply at least one validation" if validations.empty?


と、これをずっとやっていけばどうやってvalidateしてるのか分かる訳だが、こんな解説をずらずらとblogに書いてもなんかウケなさそうな気がしてきたのでこの辺でやめとく。(実はもっと奥の方まで解説するつもりだったけど、キリがないし辞めたわ。普通にコードが読める人だっら解説なんてウザいだけだし)

とにかく言いたいのはこうして気になる箇所をpryで一旦止めてひとつひとつ定義元に遡ってみていけば、なにも分からないことなんてないよね、ということ。Railsはレベルが高い!とか言ってもやっぱり可読性が十分に考慮された素晴らしいコードなので意味不明なことはまずない。

ということで「初心者でもカンタンにRailsの中身のコードをコードリーディングする方法」でした。

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com