2013年9月5日木曜日

関西Ruby会議05でのプレゼンの製作について

■概要


先日、関西Ruby会議05が開催されました。大変面白く為になる一日でした。実行委員 / スタッフの皆様、スピーカーの皆様お疲れ様です!

さて幸運にも、そのイベントで招待講演をさせて頂きました。公での40分・100人超という、私にとっては未体験ゾーンでのプレゼンです。

当日のプレゼンの出来は、自分ではわかりませんが、それなりに工夫をして作ったのは間違いないので、吐き出せるものは吐き出しておこうと思い、このエントリを書きはじめました。

少し長いですがお付き合い頂ければと思います。

ちなみに当日の発表資料はこちらです。合わせて御覧頂けたら幸いです。









■きっかけ


2013/05/12 12:15。その時私は生駒山麓公園という所で、子供とアスレチックをしておりました。



すると突然、実行委員の @agilekawabata さんからTwitterのDMが届き
「関西Ruby会議(08/31)にて講演どうですかー?」
ときたので
「お、イイですね!させて頂きます。」
と軽い気持ちで答えてしまいました。

その時、まさか招待講演という重責とはつゆ知らずでしたが、受けてしまったので何とかしようと考えました。
正気ですか?」と叫びたくはなりましたが。

■書籍


以前よりRuby会議やその他のカンファレンスでの素晴らしい発表を見て、プレゼンをするという事に興味を持った事もあり、社内では過去三年ぐらいプレゼン勉強会を主催しています。元々社内で「プレゼンテーションZENが面白い」といった所、賛同してくれる人がおり勉強会に発展しました。

読まれた方も多いと思いますが、上記の「プレゼンテーションZEN」という書籍が
(出来ているかどうかは別にして)私のプレゼンスタイルに与えた影響はかなり大きいです。



後もう一冊非常にオススメなのが、ナンシー・デュアルテの「ザ・プレゼンテーション」です。根底にある物は同じように感じますが、また異なった視点でプレゼンを語っており、本当に為になる一冊です。













いずれの本も「スライドの作り方/Power Point(keynote)の使い方」といったテクニックより、
  • 何故プレゼンをするのか?
  • 誰の為のプレゼンであるか?
  • 論理 vs パッション
  • ストーリーで語る事の重要さ
  • どのようにすれば印象に残るか? ...etc
といった部分が多く語られており、本当に素晴らしい書籍だと思います。未読の方は是非読んで欲しいな~と思います。

■製作


5月には講演が決まったのですが、その後色々ありまして、話のプロットを考え始めたのは、8月の上旬に早めの夏休みをとり家族で旅行した後です。

そこから通勤や休みの日に構成を作って行きました。この段階では全て頭の中で考え、ある程度まとまってからiphoneのメモにテキストを作成しました。

上記の書籍でも語られていますが、最初の段階からデジタルな世界で考えるのは、あまり良くないように感じます(雑音が多いですから!)。ゆっくりネットの無い状態で、心の声と向き合う時間を持つ事が大切だな~と今回痛感しました。

...

その後また色々あって、実際にスライドを作成し始めたのは、2013/08/23の夜からです。何と本番の一週間前です!かなりヒヤヒヤしました。

過去の経験から100枚前後のスライドが必要になるので汽車犬のように作成しました。









ただこれも過去の経験から、私のスタイルと(高くない)スライドの精度なら、話が決まっていればスライド製作はあまり時間がかからないというのもありました。
土日と断続的に作業を続け、日曜の夜にはα版が完成しました。

そこから昼休み、夜等にシャドープレゼンを繰り返し、しゃべりとスライドを馴染ましていきました。
この練習の過程で、120枚ぐらい作ったスライドから優先度の高いトピックを残し、最終的には93枚
のスライドになりました。

このシャドープレゼンの過程では、

  • トピックの取捨選択
  • スライドを俯瞰してのトピックの順番の決定
  • しゃべりと馴染まないスライドの、分割 / 統合 / 破棄の実施
を行ないα版が、β版ぐらいにはなりました。

発表直前まで、スライドは微調整しました。特に小さいフォントを大きくし、見やすくというのを心がけました。

■今回取り入れて良かった事


今回社内のような、良く知っている人向けのプレゼンでは無いので、レビューしてもらう事が重要だと思いました(ex. 面白くない冗談、内輪受けのネタに走っていないかとか)。

まずβ版の段階で、妻(非IT)にスライドを見てもらいながら話そうと思っている事を説明しました。
これは"かなり"効果がありました。

意味不明な写真や、気持ち悪い色使い、良く分からないトピック等、沢山の指摘をしてもらいました。また「以前聞いた話では、タイムゾーンの話と英語の話が印象的だった」というアドバイスをもらいコンテンツに含める事にしました。










また社内のプレゼン勉強会のメンバーには、実際のプレゼンをみてもらいました。
ここでも本当に重要な指摘をしてもらいました。意味不明な写真や語彙について、沢山のアドバイスをもらいました。こちらもスライド/構成/喋りの精度を上げていくのに効果がありました。

森田くん、寺島くん、酒井さん、本当にありがとう。

反省点としては、このレビューをもっと早く受けていれば、もっと改善できた所です。
スケジュール管理がなっていない自分に反省です。

■練習


前述のようなバタバタしたスケジュールでしたが、プレゼンの練習は、通しで何度も行ないました。
概ね5日間で、10回ぐらい通しはしたと思います。また最初の~10分を上手く乗り越えれば、後は
何とかなると思い、冒頭は少し重点的に練習しました。

私は、喋りに対して苦手意識があるので(特にアドリブ)、練習する事により、その不安を払拭する事ができると感じます。またとっさの問題発生時にも、練習により対処方法の平均点を向上できるとも思います。

滑舌を少しでも改善したり、言い難い言葉を他の言葉に置き換えたり、間を考えたり ...etc
スライド製作より、練習という過程の方がよっぽど大事だな~と今は感じます。

また練習すると「次のスライドの内容を少し話してからページ切り替え」が出来るようになります。
これは結構良いテクニックだと思います。

# もっと早く準備します。反省。

ちなみに本番のプレゼン時間は発表者用ツールによると37.5分でした。だいたい練習通りでの終了となりました。

■構成


プレゼン全体の構成は、もっと上手くできるようになりたいです。今回40分という尺を頂いたので、トピックのバランスや順番については、もっと工夫ができたはずと悔やんでいます。

ただ要所要所で考えた事もあるので書いておきます。

・冒頭の話方

プレゼンは、最初の10~20秒で聴衆の印象が決定するというのを聞いたことがありますが、残念ながら私は、最初から笑いを取るのは上手くありません。

だから危険な賭けをするよりは、普通の話題で初めて、少しずつ空気を温める作戦にしたいと考えました。

恐らく私のことは知らない人がほとんどなので、冒頭では、まず皆にとって共通の話題をチョイスし
(ruby言語/Ruby Kaigi)少しでも一体感を作りたいと考えました。また実行委員/スタッフの方々への謝意を伝えたかったので、これも話題としてチョイスし、拍手という体を動かす行為をしてもらう事により、少しでも空気をほぐそうと考えました。

・自己紹介










今回は自己紹介を冒頭に持ってくる構成はやめようと思いました。
40分間あるので、そこそこゆったりと時間が使える事もありますし、最初から「オレがオレが」という
構成にしてしまうと「誰の為のプレゼンか」を自分自身見失ってしまいそうな気がしたからです。

自己紹介に家族の写真を使うのは好きです(自分の中でのお約束にしてます)。人物像・状況を言葉で伝えるよりも、簡単に伝えられると考えています。

・Railsコントリビュータになるまでの話

ここは今でも構成上どうだったのか悩んでいる部分です。
というのも冒頭~Railsコントリビュータになるまでの尺が、何度練習しても10分強になるからです。
人によっては、ここまでで飽きてしまうのではと恐れました。

最初は15分かかる内容だったので少しスライドを捨てました。少し長いとも思いましたが、ストーリー仕立てという事もあり(編集しにくいので)そのままにしておきました。

・思い出のコミットの話

今回Ruby会議という事もあり、聴衆の層が分かりそうな気もしますが、中々分かりかねる部分もありました。

そん中で、私の活動の成功/失敗やコミュニティーという部分が、外から見た時に分かりにくいと思うのと、少しはテクい話しをしないと納得頂けない方もいるのではと思いましたw










ちなみに練習時の指摘を元に「rubyは知っているが、rails/githubについて名前は知っているが深くは知らない」という人に合わせ、語彙の変更をしました(うっかりプルリクとか言った気がしますが...)

・まとめ

好きなプレゼンなので、是非「マッド・カッツの30日間チャレンジ」の話を紹介したかったのと、自分自身の見解や、これからコミュニティーやってくる人への話をしたいと思いました。










少し説教臭い語り口だったと思うので「どうかな?」とも思いましたが、これぐらいの方が選んだ話の終わりとしては適当かなとも思い話の結末といたしました。









■最後に


自分なりには、持てる力を注ぐ事ができた講演ではありました。
次機会があれば、反省点を踏まえ、もっと上手くなりたいな~と感じました。

皆さん聞いて/読んで頂きありがとうございました。

2013年8月18日日曜日

ActiveRecord::Core.generated_feature_methods が何をしているか?

今日参加させて頂いたKobe Rubyist Meetup 1stで話題になった、
ActiveRecord::Core.generated_feature_methods の意味が良く分からない問題を追跡してみました。

■疑問


@sutetotanuki さんより下記のコードの意味が分からないとの質問がありました。
以前から私も良く分からないコードだな~と思っていたのですが、理由を良く知りませんでした。
 97       def generated_feature_methods
 98         @generated_feature_methods ||= begin
 99           mod = const_set(:GeneratedFeatureMethods, Module.new)
100           include mod
101           mod
102         end
103       end
moduleをその場で生成しincludeしているだけ。何の役に立つのか?

■調査した結果


generated_feature_methods を呼び出しているのは、少し上の initialize_generated_modules メソッド とassociations/builder系 と nested_attributes.rb です。

まず initialize_generated_modules メソッドは

activerecord/lib/active_record/core.rb より
 91       def initialize_generated_modules
 92         super
 93
 94         generated_feature_methods
 95       end
となっており、generated_feature_methods を呼び出す前に、さらに上位のメソッドを呼び出しており、 その中で@generated_attribute_methodsが生成されています。

activerecord/lib/active_record/attribute_methods.rb より
 62       def initialize_generated_modules # :nodoc:
 63         @generated_attribute_methods = Module.new { extend Mutex_m }
 64         @attribute_methods_generated = false
 65         include @generated_attribute_methods
 66       end
これにより generated_attribute_methods が返すModuleは、generated_feature_methodsが返すModuleより継承ツリー上、必ず上位になります。

一方でassociations/builder系 と nested_attributes.rbでは、アクセサを生成する為のmoduleとして利用されている事がわかります。

activerecord/lib/active_record/associations/builder/association.rb より
 85     def define_accessors(model)
 86       mixin = model.generated_feature_methods
 87       define_readers(mixin)
 88       define_writers(mixin)
 89     end
これにより属性用のメソッドは、アソシエーション用のメソッドより継承ツリーでは上位で生成される。言い換えるとアソシエーション用のメソッドが優先して呼び出されるようにしたいという意図が見えると思います。

実際、関係がありそうなコミット
を見てみると、そのようなコミットコメントが書かれています。
Instead of generating association methods directly in the model
class, they are generated in an anonymous module which
is then included in the model class. There is one such module
for each association. The only subtlety is that the
generated_attributes_methods module (from ActiveModel) must
be forced to be included before association methods are created
so that attribute methods will not shadow association methods.
 テストケースには、さらによく分かるコードが残っています。
333   def test_association_methods_override_attribute_methods_of_same_name
334     assert_equal(developers(:david), computers(:workstation).developer)
335     # this next line will fail if the attribute methods module is generated lazily
336     # after the association methods module is generated
337     assert_equal(developers(:david), computers(:workstation).developer)
338     assert_equal(developers(:david).id, computers(:workstation)[:developer])
339   end
なるほど!深い理由がある事が分かりましたw