Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

Code as Communication

概要

システム開発者にとって、地味に重要なスキルであるサンプルコードを書いて説明する力。
今までも重要でしたが、今まで以上に必要とされる機会が増えているように感じます。

ここ最近になって必要とされる頻度が増えてきたと思われる場面ですが、

などがあります。

太古の時代からのサンプルコードの出番

参考までに、昔から必要になっていた場面です。
どこまでを昔、どこからを最近とするか判断が難しいですが。
まぁ、だいたいで。

  • コーディング規約の例
  • ライブラリの実装例
    • 広く利用される OSS の利用方法を伝えるためのもの
      • 対ユーザー
      • 対貢献者
    • チーム内で利用する ライブラリ の利用例
  • API Document の Examples

どんな利益があるか?

  • 口頭や文章のみでコミュニケーションするよりも、伝わりやすい
  • OSS への貢献時など、英語が苦手でも意図を伝えやすい
  • 口頭などに比べ、細かい齟齬が発生しにくい
  • 実行可能

良いサンプルコードとは?

  • 出来る限り単体で実行可能であること
  • 意味のあるモデル
    • 説明対象がある程度複雑になった場合に、現実のモデルを割り当てて説明する
    • モデル化するまでも無い小さなコード片は例外
  • 伝えたい用途をカバーしている
  • 実用へのイメージがしやすい「おもちゃのプログラム」ではなく「限りなく本物に近いプログラム」
  • 必要最低限の実装
    • サンプルコードが伝えたいこと以外を混ぜない
  • 本題とは関係ないライブラリなどを利用する場合
    • チーム内など、省略しても伝わる場合は省略
    • 伝えたい相手のスキルレベルや背景が不明の場合は補足コメントや情報元へのリンクを付ける
  • コメントによる補足
    • コードによるコミュニケーションのためのコメント
      • 開発時につけるコメントとは異なる
  • コーディングスタイル
    • 言語の一般的な作法にできるだけ合わせる
  • 見た目
    • シンタックスハイライトを適用する
    • インデントをそろえる
    • インデントを深くし過ぎない
    • 普段と同じ可読性への注意。サンプルコードも可読性が低ければ、理解するのに時間がかかる。
  • ある程度複雑な内容を扱う場合は、コードの前に前提条件などの仕様をまとめて記載する。

※悪いサンプルコードについては、良いサンプルコードの反対を想像してください

Ruby のサンプルコードの Tips

ちょっとした内容です。

出力内容を # => output のフォーマットで記述する

主に 1 行で済む処理の場合に使います

puts "hOgE".upcase     # => HOGE
puts "hOgE".downcase   # => hoge
puts "hOgE".capitalize # => Hoge

__END__ をファイルに見立てる

  • Code
def output_upper_from_file(file)
  puts file.read.upcase
end
output_upper_from_file(DATA)

__END__
header1,header2,header3
column1_1,column1_3,column1_3
column2_1,column2_3,column2_3
  • Output
HEADER1,HEADER2,HEADER3
COLUMN1_1,COLUMN1_3,COLUMN1_3
COLUMN2_1,COLUMN2_3,COLUMN2_3

上達するには

素振りする

  • 技術ブログへのエントリ作成
  • ちょっとしたライブラリの作成

やっているうちに、「こうしたほうが伝わりやすいのでは」という方法が身に付く。
ただし、「より良くする」という意識が普段からあることが前提。

また、サンプルコード用のモデルをすぐに思いついて、実装に結び付けられるかどうかは、
普段からどれだけサンプルコードを書いているか、という点への依存が大きいように思います。
例える力。メタファ力にもつながる。

説明する相手を作る

  • 後輩
  • 弟子
  • ブログ、技術エントリの読者

コードで説明する癖をつける

今まで意識したことが無い人は、開発中のやりとりで
そういった場面がないか意識する。

サンプルコードを読む側の心構え

  • サンプルコードである、という前提を忘れない
    • 普段は守る作法も、サンプルコードの場合は事情により守らないことがある。 サンプルコードが伝えたい内容から脱線しすぎない
  • サンプルコードが分かりにくい場合は率直にそのことを伝え、改善案を示し、ブラッシュアップする
    • サンプルコードの価値が上がる
  • 誤ったサンプルコードへの指摘をする
    • 特に、検索上位の技術記事などは多くの人が目にするため、誤ったままだと 誤解して覚える人が現れてしまう。

具体例

株式会社 黒の組織の 工藤 さんと 服部 さんのやりとり

工藤 さんと 服部 さんが Ruby のコードの記述法に関してチャット上 ( Slack ) で雑談している。

服部: @工藤 RubyEnumerable#map を使う時、レシーバーのメソッドを呼ぶだけなのにブロックを呼び出すのが面倒やねん。
服部: @工藤 ええ方法あるか知っとるか?工藤。おい工藤?聞いとんのか、あー、工藤?
工藤: @服部 バーロー、そんなんじゃおめぇの言いてぇことが伝わらねぇんだよ。
服部: @工藤 せやかて工藤・・・・あー、ほなサンプルかこか。
工藤: パラパラを踊りながら待機中
服部: @工藤

print ('a'..'z').map { |e|e.upcase }.join # => ABCDEFGHIJKLMNOPQRSTUVWXYZ

服部: @工藤 これを短く書きたいっちゅーのがワイの希望や。
工藤: @服部 なんだ、そんなことかよ。
工藤: @服部

# &:upcase は 「暗黙の to_proc」。分からなかったらここを見てね => http://qiita.com/tbpgr/items/bf2df9df2ecf75cc3d2e
print ('a'..'z').map(&:upcase).join # => ABCDEFGHIJKLMNOPQRSTUVWXYZ

※ 服部 が map(&:upcase) の書き方を知らない時点で、 暗黙の to_proc について知らないと判断。
コメントで補足している。

工藤: @服部 ほらよ。
服部: @工藤 おー、ほんまか!いや、ワイもホンマは知っとってんけどな、ど忘れしてもうてな。
服部: @工藤 ほなまたあとで。
工藤: @服部 おう。
工藤: @服部 (強がりやがって、 to_proc の情報見に行くくせに)
光彦: なんで服部さんは江戸川くんのことを工藤って呼んでるんでしょうね。怪しい・・
光彦: (顎に手を当てて考え込む光彦)

話題を広げる

サンプルコードに特化した話題って、意外と耳にしないので
いろんな人が考えること、ノウハウを聞いてみたいです。