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

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

RubyのblockやProcを分かったつもりになっていて見事にハマった

反省した。RubyのblockやProcを分かったつもりになっていて、しょうもないところでハマった。自戒を込めてブログに残しておくことにした。

$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin15]

例1

def method_1
  if block_given?
    puts 'Yes'
    yield
  else
    puts 'No'
  end
end

method_1 { puts 'I am a block' }

つまりmethod_1にI am a blockの出力というブロックを渡して、ブロックが有ればYesと共にそれを出せと。
method_1にはブロック引数が無いが、この例のようにそれが問題になることもなく、yieldすればちゃんと実行される。

実行結果

$ ruby block_sample_1.rb
Yes!
I am a block

例2

def method_1
  if block_given?
    puts 'Yes :method_1'
  else
    puts 'No  :method_1'
  end
  method_2
end

def method_2
  if block_given?
    puts 'Yes :method_2'
    yield
  else
    puts 'No  :method_2'
  end
end

method_1 { puts 'I am a block' }

blockが渡されたmethod_1からmethod_2を呼び出す例。

実行結果

$ ruby block_sample_2.rb
Yes :method_1
No  :method_2

渡されたblockはmethod_1まで。method_2には到達していない。

例3

つまり&引数名にしてブロックをProcオブジェクト化して渡す必要がある。その対策後のコード例がこれ。

def method_1 &block
  if block_given?
    puts 'Yes :method_1'
  else
    puts 'No  :method_1'
  end
  method_2 &block
end

def method_2
  if block_given?
    puts 'Yes :method_2'
    yield
  else
    puts 'No  :method_2'
  end
end

method_1 { puts 'I am a block' }

実行結果
これでしっかりblockがProc化されてmethod_2にまで到達していることが分かる。

$ ruby block_sample_3.rb
Yes :method_1
Yes :method_2
I am a block

例4

def method_1 &block
  if block_given?
    puts 'Yes :method_1'
  else
    puts 'No  :method_1'
  end
  method_2 plus_one 1, &block
end

def plus_one number
  number + 1
end

def method_2 number, &block
  if block_given?
    puts 'Yes :method_2'
    puts number
    yield
  else
    puts 'No  :method_2'
  end
end

method_1 { puts 'I am a block' }

実行結果

$ ruby block_sample_4.rb
Yes :method_1
No  :method_2

method_2にまでブロックが到達していない。これでハマった。とくに例3と変わったことをしているようにも思えない。ただdef plus_one numberを加えただけで、そこにblockはまったく関係無さそう。なぜmethod_2にまでブロックが到達しないのか、しばらく分からなかった。

見つけた答えがこれ。

例5

def method_1 &block
  if block_given?
    puts 'Yes :method_1'
  else
    puts 'No  :method_1'
  end
  method_2 plus_one(1), &block
end

def plus_one number
  number + 1
end

def method_2 number, &block
  if block_given?
    puts 'Yes :method_2'
    puts number
    yield
  else
    puts 'No  :method_2'
  end
end

method_1 { puts 'I am a block' }

実行結果

$ ruby block_sample_5.rb
Yes :method_1
Yes :method_2
2
I am a block

例4との違いはここの()だけ。

  method_2 plus_one(1), &block

つかれた。。。

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

Railsの生みの親、DHHのロックな発言に惚れた

Railsの生みの親であるスゴ腕エンジニアでしかもプロのカーレーサーで、イケメンで、嫁さんは超美人で、もう金も才能も成功も全部持っていってしまっているDHHのイキな発言が心に響いた。

元ネタはこちら。
https://hashnode.com/ama/with-david-heinemeier-hansson-cizf90u8w000ro353hnz8v4f5

私なりの意訳

= 質問者の投稿 =
なんでエンタープライズ向けの製品はASP、.NET、Javaのプラットフォームに偏ってるんですかね?なんでエンタープライズ向けでRails、Node.js、Pythonなんかの素晴らしいフレームワークを使った製品って出て来ないんでしょうか?近々これらの状況に変化はあるのでしょうか?


= DHHの回答 =
エンタープライズ向けの製品って技術的な優位性だけで決まるって訳じゃないんだよ。長期的なサポートとか、なんかあった時の言い訳や責任逃れのしやすさとか。売り込むにもそれを本当に必要としている人に売り込むんじゃなくて、そこから遠い所にいるマネージャー様に売り込む必要があったり。
そういう状況だと「ここはIBM製品を買っておけば、誰もクビにならずに済む」ってなるんだ。そんな基準では技術的優位性なんてちっとも重要でなかったりする。重要なのは箱にオラクルやマイクロソフトのマークが付いているってことなんだ。
まー彼らは自由を愛する俺達とは違うってことだね。

Rubyの顔がまつもとゆきひろ氏になっているようにRailsの顔はDHHになっている。そうなると単にコードを書くことだけが仕事ではなく、その思想や態度がRubyやRailsのコミュニティに影響する。

DHHのこうした発言に「あ、おもしろ」と思う人がRailsプロジェクトなんかに賛同してRailsが活気付いていく。

「おたくの製品はエンタープライズ向けにはちっともウケてませんね。ダメねー」なんて突っ込まれても「あんなダサい連中は放っとくに限るわ」とロックンローラーみたいな受け答えをする人がRailsのリーダーであることってまーまー幸運なことだな、と。
並の人間なら「いえいえ、エンタープライズのお客様にもご満足いただけるようにRailsのサポート体制も強化中でして、、」とやってしまうだろうが、我らがRailsのDHHはイケメンゆえにそんなダサい発言はしないのだ。惚れました。その調子でいってください。


tango-ruby.hatenablog.com
tango-ruby.hatenablog.com
tango-ruby.hatenablog.com
tango-ruby.hatenablog.com

重大なシステム障害時における心構えをイタリア人エンジニアから学んだ。自信を持って笑ってるヤツは強い

緊張する重大な局面ほどその人の本性が垣間見れる、ということで「重大なシステム障害時における心構え」というものを同僚のイタリア人エンジニアのDから学んだ、という話。

現在の勤め先のベルリンのITスタートアップのエンジニアチームは全員の国籍が異なる多国籍チームのため、いろんな出来事のリアクションやらが妙に異なることが多い。同僚のDはイタリア人で映画スパイダーマン(サム・ライミの方)のハリーを演じていたジェームズ・フランコ似のイケメン野郎だ。

(ジェームズ・フランコってこれ)

Vanity Fair [Italy] No. 36 2013 (単号)

Vanity Fair [Italy] No. 36 2013 (単号)

Dはいつ見ても陽気に笑っているし、なんか調子がよくてよくしゃべる。

先日そのDの担当する箇所から問題が出た。問題が発覚したのは社内ではちょっと有名な女のクレーマー客のひとりからのメールだった。その客からのメールがこんな感じだった。

「おたくのウェブサービスを使っていたら今回という今回は本当に残念なことがありました。ボタンをクリックしたら見たことも無い他の客の名前やメールアドレスが出てきました!どういうことですか?これは他の客にもあたしの決済情報とか筒抜けになってて見れるってことじゃないの?!情報漏えいヨ!どうしてくれるのよ!」

問題の内容もイヤな内容だが、よりによって第一発見者がこのクソ客とは運が悪いなー、という感じだった。それを知ったのは朝で何人かのエンジニアが集まって話し合い、ちょっと陰鬱な空気になっていた。そしてどう考えてもこの該当コードを書いたのはDだった。その時Dはまだ出社していなかった。

その後、30分ぐらいしてまだ何も知らないDが「チャオ」とか言いながら、さっそうとオフィスに現れた。みんなが問題の内容と例のクソ客について説明した。するとDは例のジェームズ・フランコみたいな笑顔でしかも机を叩いて笑ってこう言ったのだ。
D「あっはっは!あのクソ客が情報漏洩だって吠えてんのー!?最高だな!例によってあの客とはなー!ひゃっはっはー!」
他一同「。。。」

それまで深刻に問題について話し合っていた他一同はバカらしくなって、しばらくの沈黙の後、Dにつられて一緒に笑ってしまった。
シリアスな状況の中でその原因を作ったかもしれない当事者にこんな笑顔で笑い飛ばされた時の気分をご想像いただけるだろうか?

f:id:tango_ruby:20170410205447p:plain

そうなのだ。深刻に話し合ったところで何も解決しないし、気分が滅入るだけだ。普通に考えて決済情報を自社で管理するようなサービスなんて作らないし、その客が言うような情報漏洩なんてありえない。結局DがキャッシュとCDNの不具合を見つけて修正した。

普段のDを見ていて、ヘラヘラ笑ってはいても誰もがDの技術力に信頼を置いていた。今回の問題はDに言えばきっと解決するだろうし、他のエンジニアが無駄に手出しをするよりも、Dに頼むのが最も手っ取り早く解決するのは誰もが分かっていた。

そういう信頼というのは問題に直面した際の態度にも出るな、と感じた。もしDに問題を報告した際にDがさも申し訳なさそうに(彼の性格からありえないが)「すっ、、すみません。。」なんて言ってたらこっちも余計に不安になってDのコードを手分けして見直していたかもしれない。

誰だってそうだが、Dにも仕事に限らずいろんな問題に遭遇することがあると思う。カノジョに浮気がバレたり、車を壁にぶつけたり、注文したピッツァが不味かったり。そんな時にDは例の堂々とした態度で、たまには笑い飛ばして解決しているのだろう。全部がうまくいかなくても、そういう堂々とした態度は重要だと思う。

誰でも頼み事があった時にビクビクしたヤツには頼みたくない。堂々として信頼のおける人にこそ頼みたい。エンジニアである以上、信頼というのは基本は技術力によるものだ。しかしそれだけではなく普段の態度も意外と重要だ。どんなに技術力が優れていても態度が堂々としていないと不安になってしまう。逆に堂々としているとなにかと重要な頼み事が舞い込んで来て、そういう重要事項をこなす内に経験値も上がって本当の技術力も付いてくる。

とにかく「自信を持って笑ってるヤツは強い」そう感じた1件だった。

それともうひとつ。バグを作ったヤツが笑うのは場合によっては周りの怒りを買う行為にもなる。「てめーバグ作ってなに笑ってんだよ、このボケ」と。しかしDはその独特のキャラで切り抜ける術を身に着けている。
キャラが合ってない人が問題に直面した際に笑い飛ばしてごまかそうとするのは決しておすすめしない。だいたい日本人の私はDのように重大バグをイタリア風に笑い飛ばすことなんてできないし。

tango-ruby.hatenablog.com
tango-ruby.hatenablog.com
tango-ruby.hatenablog.com
tango-ruby.hatenablog.com