YAPC::Japan::Online 2022に参加した

何年ぶり? というほど久しぶりにYAPC::Japanに参加しました。2018年の沖縄、2019年の東京に続いて3回目。YAPC::Asiaを含めると2013年から数えて6回目。

yapcjapan.org

今回はコロナ渦での開催ということもあり、オンライン。これが2,000円ぐらいの破格だったので迷う間もなく申し込みましたが、当初分はきっちり完売したようで何よりでした。

ではざっくり、振り返ります!



DAY1 (2022/03/04)

スタートはたしか18:50で、最初の乾杯が19:25ぐらいでしたが、この日は珍しく日中の仕事がかなり立て込んでしまったのでオープニングには間に合わず、乾杯直前にようやくログイン(Discordに)。YouTube Live見ながら乾杯しながら、その数時間前に届いていたperlbrewを飲みました。

今回はノベルティも飲食物も自宅に宅配される仕組みで、最高でしたね・・感染リスク、ほぼゼロ! ライス入りのスパイシーな丸ごとチキンは大変おいしく、何種類もあったオードブルやシチューもいい感じでした。とくにオードブル(というかおしゃれなツマミ)はビールが進みましたね・・今回はラムネとビールを1本ずつにしたので(ラムネ珍しかったので)、「ビール2本でも良かった・・」と思いましたが、まあ自宅なので普通に常備しているものを2本目として飲みました。

ゲスト対談

最初のゲスト対談、前半は見れなかったですが、それでもすごく良かったです。とくに昔語りをするわけでもなく、今この時の話をしているのに、空気だけはなんだかやけに懐かしい(笑)。うずらさんの喋り回し(というのか)はいつも通りで一気に「YAPCに帰ってきた!」(自分が)という感じになりました。

トーク

トーク編では@dankogaiさんの正規表現トークを聞けたのがよかったです。副音声のPerl入学式チームによる解説もあり、とくに@xtetsujiさんは正規表現や数学に大変詳しいので、その辺の相性も良かった気がします。

www.slideshare.net

懇親会・アンカンファレンス

トーク編の後は懇親会。すでに結構飲んで気分良くなってしまっていたので、最初は「懇親会の前につぶれるんじゃないか・・」とやや不安でしたが、実際はあまり飲みすぎることもなく各アトラクションを堪能しました。たぶん、オフラインだったらもっと周りの勢いに乗って飲んでしまっていたかな・・と。

Perl入学式主催のクイズ大会、充実していてよかったです。ぼくが回答するなら1問につき45分ぐらいほしかったと思いますが(笑)。参加者さん出題者さん、おつかれさまでした。

アンカンファレンス部屋もちょいちょい覗いて、ここでも久しぶりのYAPC感。まったり技術の話をしているのを良い距離感で聞けて、しかもオンラインなので資料も音声も明瞭。途中入退出が他の人の邪魔にならないのも良い感じでした。

ぜんぶ見終わり飲み食い終わり、オフラインだとその後に宿まで帰る手間がありますが、それもなく即自宅なのもオンラインの良いところ。沢山の知らない人たちと直接会って喋って得られる鮮烈な体験や、記憶への焼きつき方は薄れますが、それでもオンラインならではの良さを実感しました。

DAY2 (2022/03/05)

通常、連日開催する系のITカンファレンスだと2日目のスタートは午前からで、前日の懇親会で飲みすぎてキツい・・となりがちですが、この2日目は13:30からのスタートで大変助かりました。

しかし前夜、「あんまり飲まずに済んだ」などと思っていましたがじつは結構な二日酔いになっており(笑)、やはりお祭りだけあって普段に比べたらしっかり飲んでいたんだな・・と。オフラインだったらどうなっていたか・・。

トーク

2日目は結果的に、ずっとA会場のトークを聴いていました。といってもがっつりライブを見るという感じではなくて、リアルタイムの発表と裏トーク会場を行き来しながら自宅のタスク(家事とか)をしたりという感じ。オンラインでなければできない所業。

白方さんのコアモジュールの話はPerlっぽくてとてもよかったです。副音声のてつじさん、@shironekoさんによる話も聞きながら、より楽しめました。
argrath.ub32.org

その裏トーク、野球の解説なんかと違って解説も本編もどっちも「喋り」なので、両方同時に聞くというのはなかなか難しいですが、それでもこういった「メインの発表以外の場」が用意されているのは良い感じだと思いました。トーク後に登壇者自身の補足みたいのが聞けるのもいいですね。

続いてアナグラさんの発表、スタートと同時にピザが届いた(アナグラさん宅に)のはウケました。しかしそれを見越して「ピザ受け取り中」のスライド&コードも用意しているのがさらにすごい(笑)。

ちょうど同じ頃にウチにもピザが到着して、ほんとに来た(笑)と驚きました。宅配ピザなんてもう何年も自分では頼んだことがなかったですが、久しぶりに食べたらかなり満足。「特うまプルコギ」というメニューでした。

ちなみに、ピザハットの「ハット」はHatではなくHutだと初めて知りましたね・・(LTスポンサートークでの小ネタ)。何十年もHatだと思っていましたが。さらにちなみに、このピザハットさんのLTも最初は長めの公式CMが流れ出して、もしかしてこれだけで終わり・・? と思ってしまいましたが、その後の発表も良い雰囲気で結構熱心に聞きました。

話を戻して、アナグラさんの発表は自分にはレベルが高くて、雰囲気でやることすらできなそうなので資料を見て勉強したいと思います。
speakerdeck.com

ベストトークを取ったまかまかさんのトーク、よかったです。40分が短く感じました。あのサクサクしたテンポを保ちつつ、Acme大全の制作に関わる部分では叙情的な展開もあり、しかし湿った感じに染まるわけでもなく懐かしさと乾いたユーモアみたいなものが横溢した良い時間だったと思います。
speakerdeck.com

具体的なところだと、初期の一升瓶ラッパ飲みの表紙イラストのモデルがまかまかさんだったという話があって、「へえ〜!」と思ったり。こういう一つひとつのディテールが刺さるというか。
「この頃は年金問題が流行ったので・・その流行りを取り入れて」とかでもその都度ウケました。あと、「マルチ中毒」の元ネタはわかりましたが(昔出した自分の本の版元が「マルチチュード」とかをやっているところだったので)、「Acme::rion」は元ネタを知らず、わからず・・でも、Discordではそこがかなり盛り上がっていたので結局面白かったですね。

この「元ネタを知らないのに面白い」というのがすごくて、ハイコンテキストなのにコンテキストを共有していない人にもちゃんと面白さが届いているのが不思議です。YAPCのLTだと周りの人たちの反応がヴィヴィッドにわかるので、余計にこういう現象が起きるのかもしれないですが、オンラインでも同様にそれが体験できたのでそれもまた不思議な面白さでした。(発表者に反応が届きづらいのはつらいところですが)

あと、元々は批評系の同人サークルに間借りしていたという話も案外Acme大全の本質に触れるところのように思われ、Acme大全には真面目な批評的な観点の記事も欠かせない要素としてあるので、そういう何というかまかまかさんの批評的な物の見方というか、社会に対する論理的な意思表明のあり方みたいなものがAcme大全に表れているのかもしれないなあ、なんてことを思ったりもしました。

キーノート

本編最後のSongmuさんのキーノート。ご自身の経歴とともにこれまでのPerlYAPCとの関わりを振り返りつつ、現在の仕事を踏まえて今後を見据えるような内容でした。とくに、Launchableに関わる川口さんとの話などは新鮮なところが多くて、この発表の核心になっていると思いました。落ち着いた雰囲気で過去と未来を提示する、まさにキーノートという感じでしたね。
junkyard.song.mu

LT

LTはどれも「さすがYAPCのLT!」という感じでよかったですが、個人的には「Perl詩」(Perl Poem)が大変味わい深くてよかったです。
speakerdeck.com

深さと重さ、軽さと広がり、これらが同居してしまうのが文学の面白さで、紹介されたいくつかのPerl詩はたしかにその域に達していましたね。「プールでひと休み」の意外すぎる作者改題も必見。
たぶん、ベストLTはこれが最後まで競ったのでは? と思いましたが、実際のベストLTになったgugodさんの発表も非常に面白かったので、納得。こちらも笑いあり、頓知あり。考えたこともないことを考える時間でした。
github.com

配信のすごさ

見聞きした発表は以上ですが、今回非常に印象的だったのはとにかくオンライン開催ならではの配信で、そのクオリティがすごかったことですね。登壇者はみな遠隔地からそれぞれ参加していたと思いますが、同じ会場で発表しているのかと思うぐらいスムーズで、これは本当にスタッフの皆さんに脱帽でした。発表者が喋っている表情(動画)が画面右上に入ったり、Twitterハッシュタグ付きツイートが下の方に流れてきたり、という仕掛けもすごい仕上がり、かつ安定感。最後のLTなんてオフラインの方がよほどトラブルがあるのでは(笑)と思うぐらいスムーズな進行で驚きました。

配信については以下に関連ブログがありました。ありがとうございました。
godan09.hatenablog.com

アフターショー

終わってからしばらく裏トークAチャンネルPerl入学式を中心とした感想戦をまったり聴いていたら、いろいろ昔のことを思い出したのと、ちょうど話もひと段落したような感じだったので挙手してスピーカーに入れてもらって、あれこれ感想を述べました。この時間、自分にはとても貴重で、なぜならもうこんなふうに界隈の皆さんと直接声を交わせる機会なんて、次はいつ来るかまったくわからないので。

Perl入学式10周年

そこでも話題に出ましたが、考えてみたらPerl入学式って今年で立ち上げから10周年。すごい! ぼくが初参加したのは2年目の2013年で、趣味のプログラミングを本格的に始めたのもその年から。となると、ぼくの趣味プログラミングも来年で10周年! といっても、ぼくの場合は10年続けたというよりは単に「やめないままそろそろ10年経ってしまいそう」というだけですが・・。

Perl入学式やYAPCでは、これがなければまったく接点がなかったような人たちとの出会いがあり、その人たちは当時から今に至るまでずっと楽しそうに(もちろん見えないところでは大変な苦難も多くあるだろうけど)生き続けていて、それを見ていたら自分もやはり同じように精力的に活動したいと思うのが必然で、結果的にカンファレンスにも参加するし、自分用のプログラムを書いてみたりもするし、という。それで気づいたら10年経ってましたね。

YAPCらしさ

あと、裏トークAチャンネルで感想を話しているときに、「オンラインでもやっぱりYAPCだと思った」という話をしたら、「そのYAPCらしさってなんでしょうね」と聞かれ、ん〜、あの最初っからまったりした感じというか、「水曜どうでしょう」を見てるときみたいな、友達の家で深夜まで飲みながらダラダラ結論の出ない話をしているような心地よさもあれば、逆に技術トークを聴いてるときのあのついていけない感じ、知らない話を体全体で浴び続けるその刺激が「自由」とか「未来」への期待を感じさせたりもするっていうところかなあ・・みたいなことを言いました。

後から思うと、それはそれで全部本当なんだけど、もう少し簡潔に言ったらやっぱり「人」というか、月並みかもしれないですが、その会場(オンラインでも)で出会ったり、面識はないけど勝手に知っているその人を見かけたり、あるいはその勝手に知ってる人が別の有名な人と言葉を交わしている、その何でもないような会話をしばらく近くで聞いてみるとか、そういう一人ひとりの「人」や「場所」、そういう魅力がデカいというか、うわ〜こんな人が、こんな考え方が世の中にはあるのか〜・・という驚き、音もなく、目にも見えないけど明らかに感じる不可逆なショックというか、やっぱりそういう場がもたらす何かっていうのが「YAPCらしさ」なのかなあ、という気もします。(ぜんぜん簡潔じゃなかった!)

いや〜それにしても、おかげでまた一気にプログラミングのモチベーションが高まりました。今までもそんなにモチベーションが落ちていたわけではなく、機会があればいろいろ作ってはいましたが(最近は自分用のブックマークレットばっかりですが)、さらにグッと一段階、気持ちが高まった感じです。自由への志向が強まったというか・・やっぱりプログラミングは自由への道。やりたいこと、やれることの選択肢を増やす道。もっと時間を注ぎたい・・。

なんて落ち着いたところで、今回もこのような機会を実現してくれたスタッフの皆さん、登壇者・参加者・スポンサーの皆さん、ありがとうございました。また会いましょう!

LT解題 - YAPC::Tokyo 2019

先週土曜に開催されたYAPC::Tokyo 2019でLTをしてきました。

yapcjapan.org

イベント全体の感想は別途まとめる予定ですが、その前に自分の発表について、覚えているうちに書いておきたいと思います。

目次

登壇スライド / 録音

まず発表資料というかスライドはこちら。

speakerdeck.com

手元で録音しておいた音声ファイルもSoundCloudにアップしておきました。

soundcloud.com

声、めっちゃ震えてるんですよね・・(笑)。しかもその震えがなかなか止まらないというか、むしろ後半に行くにしたがって増してくる感じすらあり、軽く絶望を感じながら、でもしょうがないのでそのまま最後までやりました。

たしか沖縄で発表したときも、「うわー、なんか緊張がむしろ増してくるじゃん!」と思ったものですが、つまり「話しているうちに落ち着いてくる」とか、「緊張するのは最初だけ」みたいなことは少なくともぼくの場合はナイようです。

とはいえ、やはりトータル的には、沖縄とどっちが緊張したかと言ったら今回の方が緊張しましたね。

これについてはその後の懇親会でsongmuさんもおっしゃっていましたが、たとえばメイントークって20分とか40分とかあるけど、それを見ているのは「そのトークを見にきている、全体からすれば一部の人たち」に過ぎなくて、でも本編LTってその時点でカンファレンスに残っている人全員が見ているもので、べつにその発表を見たくて集まったというわけじゃない、ある意味予備催眠率ゼロの厳しい目を持った人たちなので、そこで発表する方がよっぽどハードル高い、自分だったらまずメイントーク経験してから本編LTに挑む、みたいな話を聞きました。

いやほんと、心の底から同意です。喩えてみるならメインのトークは自著を書くようなもので、本編LTは雑誌や新聞に寄稿するようなものですね。自著は元々それに関心がある人が買ってくれるけど、雑誌やとくに新聞の場合、自分ではなくその媒体に付いたお客さんなので・・いろいろ厳しい!

プロポーザル / 何を提供できるか

イベント当日は1/26で、LTの締切りは1/22だったのですが、ぼくが申し込んだのはたしか1/21の夜とか、そのぐらいだったと思います。

プロポーザルはこんな感じでした。

# 自走するプログラミング入門者の探し方
 
プログラミングの初心者には、自らモチベーションを高めて学習を進めていける人と、そうではない人がいるようです。その二者を分けるものは何でしょうか?
 
私は長い間、ITとはまったく関係ない仕事をしていましたが、2013年のYAPC::Asiaで行われたPerl入学式に参加したことをきっかけに趣味のプログラミングに没頭するようになり、気がつけばYAPC::Okinawaで登壇を果たし、ついにはIT企業に就職していました。
 
私は冒頭に挙げた二者の中では前者にあたると思いますが、自分にどのような特徴や傾向があったのかと考えると、それは「アウトプットすること」だったように思います。LTでは自分の実体験を軸に、これについて発表したいと思います。

これは手元にあったメモなので、最終的に送った内容そのままではないかもしれないですが、大体こんな感じでした。

なぜこのテーマを選んだのか? と言ったら、一番の理由は、ぼくがYAPCの参加者(おもにエンジニア)に何らかの価値として渡せるものは何かと考えたときに、このネタぐらいしか思い浮かばなかったからでした。

LTで発表する内容は、ぼく一人が満足すればいいカラオケみたいなものではなくて、聞いている人が「ああ、この話を聞いてよかった」と一瞬でも思えるものであるべきでした。でも、ぼくは何か役立つ技術トピックを持っているわけでもありませんし、そもそもそういう知識も経験もありません。

だったら申し込まなければいいのでは、という気もしますが、後述の理由で申し込むこと自体はもう決まっていて、だったらとにかく「自分は持ってるけど他のYAPC参加者が持っていない何か」を探さなきゃ、となって結果的にこの話題に行き着きました。

少なからぬYAPC参加者がこのネタに興味を持つだろうと思った理由は、たとえば id:papix さんのこの記事を読んだからでした。

papix.hatenablog.com

そーだいさんも書かれていました。

soudai.hatenablog.com

こちらの方も時間をかけて考えをまとめてらっしゃいました。

blog.3qe.us

(時系列がバラバラですみません)

それらを読みながら共通して思ったのは、どれもが当然のことながら、プログラミングを「教える側」からの考えであって、「教わる側」が何を考えているのか、とくには、自走する初心者が何を考えているのか、感じているのか、何に突き動かされているのか、という点については、その立場の違いから原理的に(構造的に)触れられないのだな、ということでした。

であれば、プログラミングを「教わる側」のぼくがその欠けたパズルのピースを埋めることには一定の意義があるはずで、それをすれば多少はコミュニティの役に立てるのではないか、喜んでもらえる可能性があるのではないか、と思ったのでした。

応募するまで

少し時間を遡りますが、じつのところ、今回のYAPCでLTをするなんていう気持ちはまったくありませんでした。前夜祭のLTソンで発表する気すらなかったです。

(だって、忙しかったので・・)

でも、YAPCのチケットを買ったとTwitterでつぶやいたその日ぐらいから、 id:magnoliak さんから「LT募集してますよ」という煽り・・ではなくご案内を何度か頂いて、反射的には「ムリです!」という気持ちでいっぱいでしたが、ただお腹の底の底のところで、「んーしかし、magnoliaさんやスタッフの皆さんがこれだけ全力を投じているこのイベントに対して、しかもそのmagnoliaさん本人から応募を勧められているのに、やらないって選択肢があるのかなあ・・いや無理だけど、無理なんだけど、でもなあ・・」という逡巡が、何度押さえつけても戻ってきて、なかなか「やる」とも「やらない」とも決められないまま、とりあえずネタを考えてみておく、という日々を過ごしました。

そして最終的には、上述のとおり締切りの前日になって、「とりあえず」というつもりで一旦プロポーザルを書き始めてみたら思いのほかサラサラ内容がまとまって、それを見ながら「まあ、よく考えたらそもそも一択か」と思って応募に至りました。

この際には、せっかくやるなら前夜祭の方ではなくて、「毒を食らわば皿まで」という言葉もありますように、ぜったい怖すぎてマジやばいとは思いながら、応募するだけなら何も損はしないのだから、と思って本編の方に申し込み、その際に「駄目だったら前夜祭の方で」というオプションを付けておきました。

しかしこの、「応募するだけなら何も損はしないのだから」というのは、「タダより高い物はない」という言葉もありますように、恐ろしい誘い文句でして、それから発表までの間は何度も「あれ、これ万一選ばれたらかなり大変では? え、なんで応募したん? なんで??」という後悔にそれはもうさいなまれたものでした。

なんというか、プロポーザルは持ち前の調子の良さであたかも崇高なネタがすでに用意されているかのように悠然と書いてしまったものの、実際には具体的な内容はまったく固まってなくて、もし選ばれたらその場に見合うだけのガッツリしたものをその瞬間から一気に作らなければならず、いやいや、会社に通いながらそれは無理じゃん、って無責任じゃん、ってかなりマズイ、かなり・・とかなんとか、ただひたすらエネルギーが落ちていく感じでした。

果たして、LTの選考結果が発表されるのはイベント本番の2日前、1/24のお昼すぎでしたが、「LT採択が云々」という件名のメール通知が目に入ると同時に頭の頂点からこめかみに向けてイヤ〜な汗がズワッと降り出してきて、「今は見たくない・・というか落ちていてほしい・・」などと思いながらエイヤと開いたら採択されていて、ひえ〜マズイ! けど嬉しい! けど絶対失敗する! などの恐怖と混乱に包まれながら、でも同時にぼくのプロポーザルを見て期待を感じてくれた運営の人たちの顔も浮かんで、ああそうだ、その人たちの期待に応えなければいけないんだ。と、あちこちぶつかりながらなんとか覚悟を決めました。

構成の練り方

すでにプロポーザルを書いた段階で大きめの方針は決まっていて、どんなトピックを入れるかということも思っていたよりはスムーズにリストアップできたのですが、大変だったのはその筋道を整理することで、いくら考えても話がうまくつながりません。

それもそのはずで、これは上記のpapixさんたちのブログとは逆方向の性質ゆえというか、ぼく自身はプログラミング初心者の視点からものを感じたり言ったりすることはできるけど、テーマはそういう初心者を外側から見るような(すでに技術を習得した側からの)視点で立てられているので、一体どちらの視点を軸にしたらいいのか、またどうすれば双方の視点から語られるトピックを自然に構成できるのか、といったことが難しく、なかなかこれを整理できませんでした。

それでとにかく、言いたいトピックを一回全部入れた上で、それだとまったく時間に収まらなかったのでネタを足し引きしながら本の編集のように構成をまとめて、その「語りの軸足をどちらに置くか」とか、「どうやって自然につなげるか」とかは最後の最後まで後回しにする作戦を取りました。

視点や方針を定めないまま構成なんてできるの? とぼくも今これを書きながら思いましたが、ん〜、でもなんか、できましたね。言っておきたいネタはあって、それをどう見せるかまでは出来てしまうというか。

具体的には、こんな感じでした。

  • タイトル
  • 目次
    • その1
    • その2
    • その3
  • 結論
  • その1
    • 話の前提
      • 勝手に水を飲む馬
    • 自己紹介
      • commmons: schola
      • YAPC::Asia 2013 & Perl入学式
      • MOONGIFT
      • ブログ
  • その2
  • その3
    • アウトプット
    • なぜ?
      • 忘れちゃう
      • 見知らぬ人への手紙
        • メッセージ・イン・ア・ボトル
      • 自慢
      • 恥ずかしさが薄れていく
        • 相対的に
  • 引用
  • 結論(再)

ここでやっているのは、ただひたすら見出し文言の洗練とその入れ替えです。結論を最初の方に持っていったのも、結局最後の1行をコピーして初めの方にペーストする、という作業を見出しだけなら簡単にできるところから思いつきました。

ちなみに、今回の一連の作業はもちろん(というか)Vimでやっていました。沖縄での発表でも紹介しましたが、tagbarというプラグインを使って、こんな感じで左に本文、右に見出しを出しながら内容を詰めていきました。

f:id:note103:20190202210801p:plain

*いま気づきましたが、レイアウト調整の都合もあって本来見出しではないものが右に行ってますね・・文字を大きくしたいものを見出しにしていたので。まあ、暖かく見守って頂ければと・・。

そしてまた、このようにMarkdownファイル1本でスライド資料を作りきれたのは、ゆーすけべーさんによるPerlモジュール App::revealup のおかげでした。

metacpan.org

これがなかったらまず間に合いませんでしたし、このモジュールのおかげでKeynoteを地道にポチポチ調整することもなく、本質的な内容の洗練に集中できました。ゆーすけべーさん、ありがとうございます!

筋を通す / 引用

上で何度か書きました「筋道の通し方」ですが、最終的に思ったのは、「結局ぼくにわかるのは初心者側の話なのだから、初心者としての実感をメインにするしかない」ということ、そしてその上で、「アウトプットしてる人を探せ、なんて何も言ってないのと同じだから、そうではなくて、そのアウトプットからそれを支えるモチベーションを逆算的に見出して、もしそのモチベーションが自走型のそれだったら、その元にいる人は自走するプログラミング入門者だっていう論理なら行けるのでは」ということでした。

やや強引にも思える論理ですが、この準備期間でこれらのトピックを入れるにはその方向しかなかったのですよね・・。

ただ実際には、そこまで込み入った論理を説明するヒマはなかったですし、聞いてくれた人たちもそこまで論理のつながりみたいなものは気にしていなかったかな、とも思っています。

それとは別に、もうひとつ論理のつながりとして気になっていたのは、終盤の森博嗣さんの引用でした。

ぼくが今回絶対入れたいと思っていたのは、2本出した引用のうちとくに最初の方、「才能は決して埋もれない」というもので、これは本当にぼくを支える言葉になっています。といっても、それは何も「ぼくの才能が埋もれるはずがない」とおまじないのように思っているということではなくて、ただ「アピールの仕方にリソースを費やすぐらいなら納得行くまで物を作ろう」という気分を後押しするものとして支えにしている、ということです。

なのですが、この引用も結局、なんの支えになるのかと言ったら「教わる側」であるところのぼくを支えているもので、それを外から見る「教える側」とか、自走するプログラミング入門者を「探す側」の実感とは、ある意味では逆なんですね。なので、ん〜、この超終盤の決め手になるようなところで、教わる側視点の引用を出すのって正直意味わからん・・どうしよう・・と、これはかなり悩みました。

悩みましたが、でもこの引用は(くり返しになりますが)絶対必要で、確かにこれがなければ流れはスッキリして、誰からも突っ込まれないウェルメイドなスライドができたかもしれないんだけど、それって言いかえると「小さくまとまる」みたいなことで、せっかくここまで地獄の釜の蓋を開けるようなことをしてきたのに、最後に日和るんかい、というツッコミの方が勝ちまして、「もう論理とかどうでもいいからとりあえず入れとけ、説明は本番でしろ」みたいに自分に説得される感じで結局入れました。

結果的には、発表では「この言葉はぼくの支えになっていて、関係ないって思われるかもしれないけど今回の発表とめちゃ関係してます」みたいな、説明になってるんだかなってないんだかわからないようなことを言って終わってしまいましたが、その数分後に思ったのは、「自走するプログラミング入門者を何が支えているのかと言ったらたとえばこういう信念だから、知っておいて損はないですよ」みたいな観点から見れば筋はちゃんと通ってたな、ということでした。

ようは、瞬間的な反応とか、評価とか、そういうのはもういらないんだと。「いいね」とか、はてブとか、そういうのはもういいんだと。もちろんそういうのを求めたっていいし、その欲求は自然なものなんだけど、でも逆に、すぐには全く反応が得られなかったとしても、それは作品の価値とは全然関係ないし、気にするに値することじゃないんだと。それが本当に面白いものだったら、必ずいずれ評価されるから、作る人が本当に全力で気にすべきことは、それが本当に面白いものなのかどうかなんだってこと。それだけ。作る人はそのことだけに集中してればいいんだと。めっちゃ頑張ったけど全然評価されませんでした、見向きもされませんでした、なんていうのはまったく気にすることじゃなくて、めっちゃ頑張ったけど全然面白くなりませんでした、ってそっちの方がダメなんだと。そっちを気にしろと。それだけを集中して考えろと。・・そういうことをこの引用を通して伝えられたら良かったのかなと思いましたが、ぼく自身今これを書きながら「ああ、そういうことだったんですね」と思ったので、その時点で言えるはずはなかったですね。

いろいろスッ飛ばしながら、最後のまとめに触れ終わった瞬間の手元のiPhoneのストップウォッチは4分57秒で、あ、間に合った・・と思って「ピッタリ」と思わず言いました。実際はどうだったかわからないですが・・ぼくが締めの御礼を言ったあとにpapixさんのドラが鳴り響いて、ああなんか、すみませんありがとうございました、という感じでした。

練習、練習、練習!

しかしステージに上がる数分前まではけっこう正気だったんですけど、階段を上がる瞬間にはなんだか、真っ白な天国の光の中に入っていくような、意識が薄れていく感じがあって不思議な感覚でした。M-1グランプリの決勝に出る人たちとかってこんな感じなのかな・・とふと思ったり。ステージで何を喋っていたのか、ほとんど覚えていないですね。降りてから、「あれ、坂本さんの話ちゃんとしたっけ?」と本気で不安になったりしました(一応してました)。

ステージではもう、だから体が勝手に動くのに任せていた感じでした。そこで生きてくるのが練習なんでしょうね。スポーツとか楽器とかと同じで。普段練習した分がそのまま本番に影響するのかなと。今回、ぼくはスライドがなんとか形になるまでだいぶ時間がかかって、当日の昼前ぐらいまで浅草橋のホテルでスライドを作っていたので、その後にできた練習は正味3〜4周ぐらいでしたか・・もう少しできると良かったのですけど。

ぼくはパフォーマンスの出来/不出来として目に見えるのは山の頂上みたいなほんのわずかな部分でしかなくて、それを高めるにはひたすら山の裾野を広く盤石にしていくしかないと思っていて、つまりパフォーマンスの完成度を高めたかったらひたすら地味な練習をくり返すしかないと思っていました。それがまあ、結局は足りなかったがゆえのあの結果かな・・とも思っています。いやあ、口が乾いて仕方なかったですね。舌が口の中にひっついて喋れない! なんて経験、初めてだったかもしれません。ああ緊張しました。

緊張といえば、ちょっと聴いている人全員を意識しすぎたかなとも後から思いました。もう少し「こういう人に向けて喋る」という対象を絞って想像しても良かったのかなと。今回のYAPC参加者数は384人とのことですから、本編LTに残っていたのは300人ぐらいでしょうか(わからないですが)。なので、その全員に向けて喋っても大半には伝わらないはずで、だからそうではなく、その中のほんの3〜4人だけを相手に喋る感じだったらもう少しリラックスできたかな・・とも。いやまあ、次にそんな機会があってもそう上手くいくとは到底思えないですが・・でも理想としてはそういうことだったのかなあ、と。

また接続にハマる / バックアップ

前回のYAPC::Okinawaの前夜祭LTでもそうだったのですが、ぼくはいまだにMacとプロジェクターとの接続方法がよくわかっていなくて、今回もLT前の接続確認でかなり手間取ってしまったのですが、ぼくの後ろで次のチェックを待っていた id:moznion さんが「ミラーリングじゃないですか」と不調の理由をさっと指摘してくれた上に「それ、そこをチェックして」などと具体的に教えてくれて、沖縄のときには id:karupanerura さんに近い感じで救ってもらったことを思い出しましたが、本当に助かりました・・ありがとうございます。

ただじつは、その後にもまだ結構深刻なトラブルが待っていて、というのも事前に書き出しておいたスライドのPDFを投映しても一部が消えてしまうんですよね。で、こんなこともあろうかと思って、これまた事前にスライドを上げておいたSpeaker Deckのページにアクセスして颯爽と自分のスライドを開いたのですが、それもダメ!🙅‍♂️

え、ええ〜〜〜・・マジやばい、やっぱりプロジェクター意味わからん、苦手すぎる! と逃げ出したい気持ちになりましたが、じつはもう一つだけバックアップとして用意しておいたのが前述のApp::revealupのローカルサーバ機能で、念のためにこれをターミナルから開きっぱなしにして、ブラウザのタブもそれに合わせてあったのですよね。で、そっちに移動したら何とかまともに見れるようになって、これほんとに半ば無意識のうちにやっていた準備でしたが、もしやってなかったらスタートラインにすら立てなかったわ・・という感じでした。

そんな風にフルタイム・パニックみたいな状況でしたが、周りのスタッフの皆さんは常にスムーズかつ間違いなく発表できるようにすごく丁寧に段取ってくれていて、最後までストレスなく場に臨むことができました。ありがとうございました。

ベストLT賞

ぜんぶ終わって、もう何も残ってません・・灰になりました・・という感じで同じくLTに登壇された id:xtetsuji さんと並んで会場最前列に座ってしばらくしてから、ベストLT賞なるものがあることを初めて知りました。で、あ、これもしかしたら獲るかもな・・と思いましたね。自信があったわけでもなければ、誰かからそう言われたわけでもなくて、むしろやってるときは「会場、反応ないな!」と思っていたぐらいでしたが、なにか音もなく届いた手応え。みたいなものを感じていたんですよね。その何というか、一瞬の淡い期待感みたいなのが心地よかったです。もし事前にそういう賞があるとわかっていたら、狙って登壇していたかもしれないので、狙わずに発表しきって、かつそういう手応えを感じられたのが良かったなと。

(結果的にはそれはmoznionさんが受賞されて、その発表内容としても、またその後のsongmuさんのベストトーク賞への流れという意味でも、まさにベストなLT賞だったと思いました)

ご感想

終わってから、いくつか嬉しい反応を頂きました。

tomcha.hatenablog.jp

blog.3qe.us

sorehaedamame.hatenablog.com

nayuta-1999.hatenablog.com

morichan.qrunch.io

*他にもあったかもしれないですが、もし見つけたら追加します。

ありがとうございました。やって良かったです。

ちなみに、スライド上の文字と口頭の内容をずらすというのは意識的にやっていました。紙芝居じゃないのだから読み上げるのはやめよう、と。昔大学で「なんて退屈な講義なんだ」と思ったものは大抵、教科書をただ読み上げるだけのものでした。

でもそれに気づいてもらえるなんて! 伝わるものですね・・。

それからsongmuさん、これは以下の記事にも書きましたが、

note103.hateblo.jp

ぼくは勝手にsongmuさんに煽られ・・じゃなくて導かれるように情報処理の勉強をしてみたり、そうやって一歩一歩進んできた感覚を持っていたので、うわ、直接評価された! って思ってすごい嬉しかったです。

終わりに

本当はYAPC::Tokyo全体の感想の中にこのLT解題を入れるつもりでしたが、ご覧のとおり、だいぶ長くなったので分けました。会全体については、また時間を見つけてアップしたいと思っています。

(ドラフトはほぼできてるので、何ヶ月も先とかにはならないと思います・・)

今回のLTに採択されたときはこんなツイートをしましたが、

果たしてスタッフの皆さん、どうでしたでしょうか・・あまりみっともいい感じではなかったですが、自分的にはやり切りました。スライドにも書きましたが、ぼくは本当は恥ずかしい思いをするのも失敗するのもみっともないのも超!イヤだし、おそらく今後もずっとイヤですが、それを上回る「やるしかない」とか「これをやったら今まで見たことない風景を見られるはず」みたいなモチベーションでやらせて頂きました。恥ずかしさや不安をゼロにすることは決してできませんが、小さくすることはできるな、と今回の発表で自分に教えられました。やりたいことが大きくなるほど、それらは相対的に小さくなります。これをステップに、またこういうことに挑戦したいと思っています。ありがとうございました。

VimConf 2018と私

2018/11/24(土)、VimConf 2018に行ってきました。

VimConf 2018

最初に2行で自己紹介をしておくと、ぼくは先月まではこういうことをやっていて、
note103.hatenablog.com

今月からはこういうことをしています。
note103.hatenablog.com

1行で言い換えると、非エンジニアの元・フリー編集者&現・IT企業のカスタマーサポートです。

では本題です。

本編

会場は秋葉原アキバホールというところで、スタートは10時だったので家を出たのは8時半ぐらい。秋葉原駅には予定どおり9時半過ぎに着いて、事前に地図で確認したところでは5分程度で会場に着く予定だったものの、普段あまり使わない駅なのとiPhone6sのGoogleマップが重くてかえって道に迷うことに・・。

その後、なんとか会場付近まで来てからも似たようなビルが多くて、どこを向いても「アキバホール」の文字が見つからず、また土曜のオフィス街ということもあってか全然人影がなく、普通ならそのあたりにフラフラしていそうな参加者っぽい人たちも見当たらないので、「もしかして、まったく別の場所にいるのかも・・?」とかなり不安になりましたが、あんまり時間もなかったのでGoogleマップはもう無視してカンでそれっぽいビルに入ったら正解でようやく受付を発見。

ノベルティ&Tシャツを受け取って開演10分前ぐらいに会場に入ったら階段状の客席にはワーッと人がいて、さっきまでの外の静けさとは好対照。皆さんもっと早い時間からいらしてたんですね・・30分早く来ていれば迷わなかったのかも。遅刻した人も少ない印象でした。

客席脇の廊下スペースにはタリーズのコーヒー&紅茶が完備されていて、そんなの想像もしていなかったのでサプライズ&堪能しました。

そしてオープニング、いきなり全編英語でまたびっくり。この英語主体の進行は最後まで続いて、すごく新鮮であるとともに嬉しい感じもしましたね。ああ、世界につながった場所にいるんだな、しかも当たり前にそうなんだな、と。日本のカンファレンスに海外ゲストを呼んでいるのではなくて、国際カンファレンスを日本でやってるんだな、と。

キーノート

mattnさん

最初のキーノートはmattnさんで、vim-jpの紹介を中心にVimの前提的・全般的なことから将来的・技術的なことまで。ある意味で、この後のBramさんとこのmattnさんのトークが全編を通して一番ビギナー向けというか、どのレベルのユーザーにとっても身近に感じられるバランスの良い内容だったように思いました。

vim-jpがどういう歩みを辿っていて、今はどういう働きをしていて、それに対してぼくらユーザーはどう関わっていけるのか、ということは今までも「調べればわかる」状態だったかもしれないですが、この発表を見てスイスイ理解できたようで、ぼくにとってはこちらと午後イチのdaisuzuさんの発表が今回のカンファレンスで自分にぴったりフィットしたなという印象でした。

Bramさん

続いてBramさんのキーノート。Bramさんは以前にYouTubeで見た講演の動画で、聞きやすい英語を喋っている印象があったので、

www.youtube.com

そのまま聞くか、翻訳レシーバーを使うか一瞬迷いましたが、きちんと意味を拾うことを優先してレシーバーで聞きました。通訳さん、とてもいい感じでしたね。正直、専門的な部分については把握しきれなかったですが、とはいえまったく追いきれないというほどでもなく、長さ的にも聞いていて全然疲れないぐらいですっきり終わって、質疑応答も含めて楽しみました。

その質疑応答、これまでに参加したITカンファレンスだと挙手した人の席までスタッフがマイクを持って走る、みたいな運用が多かったですが、このVimConfでは会場前方まで質問者が来て、列状に並んで順に質問する、みたいになっていてこれも新鮮でした。

この方式なら、質問者は登壇者と近い場所で話せるし、周りとしても質問者があと何人いるのか、とかがわかりやすくていいなと思いました。2階席まであるような大ホールだと難しいかもしれないですが、スタッフのリソースを最小限にできるという意味でもけっこう良いなと。

昼食

その後の昼食では、今半のすき焼き弁当とベジタリアン向けの野菜弁当の2種類が用意されていました。野菜弁当にもかなり惹かれましたが、今半のすき焼き弁当なんて次にいつ食べられるかわからないので、そちらに。もしかしたらチケット代の大半はこれに行ったのではと思うほど贅沢な内容でしたね。ぼくは普段は少食なので、お弁当ってけっこう残すことが多いのですが*1、今回は完食しました。

午後

daisuzuさん

午後イチは上にもちらっと書いたdaisuzuさんの "Migrating plugins to standard features."

https://vimconf.org/2018/sessions/#link-daisuzu

膨大なプラグインとともにあったVim環境から、最小限のプラグインと最大限の標準機能を活かした新たなVim環境への移行の試み、といった感じでしょうか。これはすごく共感できる指向というか、結局プラグインって増やすのも減らすのも効率化を追求するという意味では同じというか、しかし減らす方ではさらにそこに「標準機能縛り」みたいなある種のゲーム性が加わって面白そうだなあ、と思いました。とくに、Ctrl+xを用いたキー操作はあまり(というかタイプミスのとき以外は)使ったことがなかったので、そっちの世界にも足を踏み入れてみたい気持ちが高まりました。

Alisueさん

他に個人的にヒットしたものとしては、Alisueさんの "Effective Modern Vim scripting" がありました。

https://vimconf.org/2018/sessions/#link-lambdalisue

わかりやすく3ステップに分けて、ごく初歩的なVim scriptの書き方から非同期で動く本格的なものまでひと息に解説するという内容でしたが、ぼくもVim scriptで自作プラグインを作ることにはすごく興味があって、実際以前にちょっとしたものを作ったことはあったのですが(それはまだブログに書いてなかったのでいずれ・・)、でも普段から実際にVim scriptを書いている人がそういう方法についてまとめてくれることってなかなかナイので(書籍はすごいのがありますが)、これはあらためてじっくり見直しながら、手を動かして試してみたいなと思っています。

とくに、今までvital.vimというプラグインがあること自体は知っていたものの、それが何をやるのか、というのはどうしてもイメージできなかったのですが、この発表を通して「なるほど」という感じでうっすらイメージできた気がするので、次にプラグインを書くときが来たら、vital.vimを使うことがひとつの目標になりそうです。

ちなみに、同じAlisueさんが懇親会で紹介していたfila.vimにもすごく興味を持ちました。

github.com

ぼくは今やっている編集仕事でも趣味のプログラミングでも、Shougoさんのvimfiler.vimを頻用していて、こういったものが無くなるのは本当に困るので、こちらの動向も注視したいなと。

ついでに言うと、今年の3月にYAPC::Okinawaで発表した中の以下のスクリーンショット

f:id:note103:20181125231912p:plain
https://speakerdeck.com/note103/the-non-programmers-programming-techniques?slide=12

この左のサイドバーになっているのがvimfiler.vimですね。さらに付け加えると、そのIDE風の構成はmattnさんの以下のSoftware Design誌の記事を見て真似したものです。(という話もそのスライドの中で触れています)

軽い話

本編最後の発表は、Linda_ppさんでした。導入のところで「もう皆さんお疲れでしょうから、最後は軽い話をしますので。ゆったり聞いてください」みたいなことを言っていたので一瞬気を抜きましたが、それからものすごい速さで深遠かつ先端的な話をなさっていたようで、ふんわり聞いてしまいました。とはいえ、WebAssemblyについては少し前にbuildersconで見た以下の発表で興味の下地はできていたので、

https://builderscon.io/tokyo/2018/session/5212a273-a1b8-4458-9ce6-621d136b24f1builderscon.io

まったくワケわからん、というほどでもなく。図説なども丁寧に重ねてあったので、こちらもあらためて資料など出たら見直してみたいと思っています。

幸運

会の終了後、じつはというか幸運にもというか、mattnさんがすごく近いところに座っていたので、自作の英語練習ツールでmattnさんのchoを使っていることについて、実際にターミナルで動いているところを見てもらいながら、少しだけ話すことができました。

choはこういったもので、

github.com

それを使ったぼくのはこういったものです。

github.com

このうち、以下の動画の7秒目以降で出てくるセレクタのところでchoを使っています。

www.youtube.com

そして上の方で挙げたIDE風の画面分割についても、mattnさんの記事がすごく参考になった旨を伝えることができました。たぶん懇親会の時間だけだったらここまでいろいろ話すことはできなかったと思うので、座った場所が近かったというのは本当にラッキーだったな〜・・と思っています。

mattnさんはスタッフ業もあってお忙しかったと思いますが、同じモニターを見ながら丁寧に話を聞いてくださって、嬉しかったです。

懇親会

懇親会は同じフロア(5階)の、ホールから少し歩いた別会場で行われました。料理も飲み物もサービスも適度な具合で心地よかったです。これまでにもこうした懇親会には何度か参加してきましたが、この過小でも過大でもないバランスってなかなか実現しづらいというか、どうしても料理が足りなくなったり、逆に多すぎて余ってしまったり、あるいは給仕さんが雑な人だったり・・とコントロールが難しいところが多々あると思うのですが、そういうストレスを全然感じなかったです。

初めの方でスポンサーセッションなどの発表があったのもよかったですね。終始歓談タイムだけだと、ちょっとアイスブレイクしづらかったりすると思いますが、同じものを皆でじーっと見る時間があったことで、イベントが柔らかく始まった印象を持ちました。

しかし今回の懇親会、これはいつもそうと言えばそうなのですが、ぼくには知り合いと言える人が見事にまったくいなくて、ぼくはこれまでもYAPCPerl入学式Perlおよびプログラミング自体の入門者を対象にした無料のプログラミング講座)に何度も参加したり、今年はそれに加えてbuilderscon大江戸Ruby会議にも行ったり、それなりにいろんなコミュニティに顔を出してきたと思うのですが、それでも結局まだまだ知らない人ばっかりなんだな・・と思い知らされました。

daisuzuさん

でも、そこでふと気がついたのは、向こうは知らなくてもこっちは知ってる、と言える相手がけっして少なくないということで、だったらそういう相手に話しかけて、面識を持てばいいじゃないかと思って、さっそく前述のdaisuzuさんを見つけて感想を伝えました。お話ししてみると、思いがけず共通の知人や話題があったり(daisuzuさんの発表ではPerlのコードが出てきたのでその話とか)、ちょうどそのときに一緒にいらっしゃった人たちも交えて楽しく話せたりして、この積極方針は思っていた以上に有益なものでした。

松田明さん

その後、Asakusa.rbの松田明さんを見かけたので、先日の大江戸、超面白かったです!と伝えました。あとはぼくが今月入社した会社ではRailsを使っているので、そういう話も。ちょっとだけ挨拶、のつもりがこちらも思いがけず話題がいくつも浮かんできて、いろいろお話しすることができました。そして来年のRubyKaigi熱も高まりました・・なんとか参加したい!!

rubykaigi.org

Bramさん

それからしばらくの間は、食事やドリンクを頂いてまったりしていましたが、ふと会場の端の方を見ると、Bramさんの周りには思ったより人がいないことがわかりました。何人かと話してはいるものの、とても辿りつけない、というほどではないな・・と。

じつは今回は、Bramさんと話さなきゃ!みたいな気持ちはあまり持っていませんでした。なぜなら、ぼくよりずっとそれに相応しい人が他にたくさんいると思っていましたし、ぼく程度のVim歴で対面したところで、とくにBramさんに提供できる価値もないだろう、と思ったからです。でも、考えてみたら本人と直接話せる機会なんてもう二度とないかもしれないし、一応ぼくも毎日Vimを使って仕事も趣味もやっているし(このブログももちろんVimで書いています)、こうなったら当たって砕けろ、邪魔と思われてもいいから行ってみよう!と勢いをつけて話しかけました。

英語は普段のとおりまったく出てこなかったですが、名前を言ってから「ぼくは編集者で、プログラマーではないですがいつもVimを使っています。日本語の編集という仕事でもVimはとてもヘルプフルです。ぼくはVimでddと打つのが好きです。Vimは行単位や段落単位での作業に向いていて、編集という仕事ではまさにそれが役立つのです。ぼくはあなたにとにかく感謝を伝えたいと思っていました。どうもありがとう」みたいなことを言いました。

このうち、とくに「行単位」とか「段落で作業する」みたいなことはまったく英語の表現が浮かばなかったのですが、すぐそばにいたスピーカーの大倉雅史さんがササッと通訳をしてくれて、Bramさんも「ああ、そうなんだね」とか、「ああ、ddね」みたいな感じでリラックスして聞いてくれたようでした。大倉さんには本当に感謝しています。

暗黒美無王(Shougo)さん

その後、こちらもいつも勝手にお世話になっている暗黒美無王ことShougoさんに話しかけました。Shougoさんの周りにはそれこそ人が途切れなくて、その話も常に盛り上がっているようだったので、どうしようかけっこう迷いましたが、しかしこれもやっぱりなかなか無い機会だから、とその話をちょっと割るような感じで「少しだけ今話してもいいですか」と言うと「もちろん、どうぞどうぞ」という感じでShougoさんもお相手の方も一旦それまでの話を止めてくれて、それからしばらくShougoさんのプラグインをいかに使っているか、助けられているかみたいなことを伝えました。

ぼくはあまりShougoさんのプロダクトの良いユーザーとは言えなくて、というのは最近のものよりも以前に作っていた(現在はアクティブな開発はストップしている)プラグインの方をまだ使っているので、その点についてはご本人の前でアピールしづらい気もしましたが、それでもそうした作品の恩恵を大いに受けていることは確かで、そのことを直接伝えられたのは嬉しいことでした。

kaoriyaさん

懇親会もそろそろ終わりかな、という雰囲気になってきたとき、会場の出口付近にkaoriyaさんがいらっしゃることに気づきました。kaoriyaさんは今回のイベント中、どの段階でもつねにあちらへ、こちらへと走り回っていて、とても話しかけるタイミングはないな・・と思っていましたが、そのときはしん、とした場所で知り合いの方と和やかに喋っていて、今だったら話しやすいかなと思って、声をかけました。

じつはkaoriyaさんとは数ヶ月前のbuildersconの終演直後、フォトブースのコーナーで初めてお会いして、そのときは本当に一瞬でしたが、5年前に書籍『実践Vim』のプレゼント企画で本を送ってもらったことの御礼を伝えていました。

2013年という年は、ぼくにとって「プログラミング元年」みたいな年でした。ぼくはその数年前から「あ〜、プログラミングやりたい、できるようになりたい!」と思いながら、でもどうしても中途半端というか、RubyJavaScriptの入門書を何冊も買ったり、有料のちょっとしたオンライン講座を受けてみたりしたものの長続きしなくて、毎回よくわからないまま自然消滅、ハローワールドってなんなん?何が嬉しいのん?みたいな、やっぱり向いてないわ自分、挫折・・みたいなことの連続だったのが、この年の後半になっていきなりスイッチが入ったというか、継続する方向にモチベーションが切り替わったのでした。

具体的には、この年の9月初旬、前述のPerl入学式に通い始め、同月後半には神奈川で行われたYAPC::Asiaにそれこそ知り合いゼロの状態で飛び込みました。

このPerl入学式およびYAPCへの参加はぼくにとって非常に大きな出来事で、その後にぼくがプログラミングを続けてこられたのは、これらのイベントやコミュニティの人たちがいてくれたおかげだと思っています。

では、なぜそのような勉強会やイベントに、まったく畑違いのぼくが無謀にも飛び込む気になったのかと言えば、その一番のきっかけは上記の『実践Vim』にあったと思います。ぼくはそれまでもVimを何度も試しては「ダメだ、難しすぎる!」と思っていつものように挫折しかけていましたが、なぜかノーマルモードの不思議な魅力には取り憑かれたままで、Vimを諦めることもできず、かといって使うこともできない、という半端な状態を漂っていました。

そんなときにkaoriyaさんの以下のブログを読んで*2

www.kaoriya.net

本当に「何を思って」という感じなのですが、応募したのですよね、プレゼントに。どう考えても想定読者には入っていなかったと思うのですが・・。

しかし結果はなんと、当選。倍率は25%。kaoriyaさんからは、

異業種からの参入であることを重視。どういう視点で見るのかに興味があった。*3

とのこと。いやあ、異業種でよかった・・(笑)。

そして書いたレビューがこちら。

note103.hatenablog.com

この記事は、その後のぼくのプログラミングへの関わり方を大きく左右する分岐点になったと思います。というのは、第一にはこのレビューを書くために同書を必死になって全部読んだこと。どれだけわからない内容が並んでいたとしても、さすがに全ページに目を通せばそれなりに知識は定着するもので、しかもレビューを書かなくてはならないのでとにかく何でも良いから吸収しなければ!という姿勢で読むことになって、もう一旦そういうことをやると不可逆というか、だからこのレビューを書き終えた頃には、それまでの

ダメだ、Vim難しすぎる!もうやめた!

という感じだったのが、

ダメだ、Vim難しすぎる!・・けど、もう少しやってみるか

みたいになっていたと思います。

そして「分岐点」という意味はもうひとつあって、それはその記事に付いたはてなスターが示しています。見て頂けたらおわかりになると思いますが、thincaさんやh_eastさんをはじめとするVim界の人たちがスターを付けてくれて、ブックマークの方にも好意的なコメントをもらいました。

これがもう、すごーーーーく嬉しかったのです。そんなこと、それまで一度もなかったですから。それまでのぼくのブログと言ったら、知り合いか、編集の仕事絡みで見てくれる人はいても、プログラマーの人たちから反応をもらうことなんてまずないし、ましてや好評価をもらうなんてありえないことでした。

それが、このレビュー記事ではそういうプログラマーの人たちから「ウェルカム!」と言われたような感じがして、実際にはその後も技術コミュニティに関わる過程ではそれなりの苦労をするわけですが*4、でもそれにしても、やはりこの記事をきっかけに、本格的なチャレンジを始めたからこそ体験できたことなのだと思います。

この記事を公開した数日後、ぼくは上記のPerl入学式に初めて参加して、

note103.hatenablog.com

その2週間後に初めてYAPCに参加して、

note103.hatenablog.com

気がつけば、今年の春のYAPCにスピーカーとして登壇していました。

yapcjapan.org
30d.jp
note103.hateblo.jp

そして今月からは、これまで続けてきたフリーランスの編集者の活動を収束して、ITの会社に勤めはじめています。

www.velc.co.jp

会社の事業は受託開発と自社サービスが半々ぐらいで、ぼくはその自社サービスのカスタマーサポート*5を担当することになっています(今は絶賛トレーニング中)。プログラミングを生業とするわけではないですが、それでもプログラミングをやってきたからわかること、想像できることは多くて、そういうことに関心がなかったらちょっと対応できなかったな、と思えることがすでにたくさんあります。

今までやってきた編集の仕事もすごくクリエイティブで、とくに世界的に活躍するクリエイターさんたちとの仕事は自分がどこまでも高く引っ張り上げられていくような、ロケットで見知らぬ場所まで飛ばされてしまうような面白みに満ちていましたが、でも一方で、ぼくが理想とするような仕事や生活の環境をそこで作っていくのはなかなか大変で、その意味で今の会社に入れたことは、理想の人生に大きく近づいたということだと思っています。

だいぶ話が広がってしまいましたが(そして一気に戻しますが)、VimConfの懇親会の最後に、会場の出口近くでkaoriyaさんと握手をしながら、あの『実践Vim』がなかったらまだ挫折をくり返していたかもしれないこと、そしてあのレビュー記事が最初の成功体験になって今があるのだということを伝えられて、本当に嬉しかったです。

その後、kaoriyaさんからは以下のようなツイートをしてもらいました。

ありがとうございます!!!

終わりに

帰り道、まだ御礼を言えていないVimmerがたくさんいるな、と思いました。たとえば、会場にはいたはずの(必ずどこかですれ違っていたはずの)thincaさん、それから今回はいらしてなかったかもしれないですが、open-browser.vimやcaw.vimで毎日のようにお世話になっているtyruさん、そしてこちらも毎日めちゃくちゃ使っているVim-EasyMotionのhaya14busaさん、あるいはprevim*6の作者であり、現在は書店向けの先進的なサービス 「リトルスタッフ」の事業に邁進してらっしゃるkannokannoさん。他にもまだまだ、そうやってぼくの方で勝手に知っている人たちがいると思います。

でも、また来年VimConfが開催されたら、そういった方々に会えるチャンスもあるかもしれないですね。そのときまでに、ぼくも何か貢献できるよう、自分なりに準備をしておきたいと思います。

VimConf 2018を実現してくださったスタッフの皆さん、登壇者の皆さん、参加者の皆さん、スポンサーの皆さん、ありがとうございました。これからもよろしくお願いします!

*1:家や職場のように取っておける場合は後で残りを食べます。

*2:どうしてその記事に行き着いたのかと言うと、たぶん2011年の同ブログで書かれていた「Vim昔話」シリーズがすごく面白くて、それを読み漁るかたわら新着記事も読んでいたのだと思います。同シリーズは本当に名文!

*3:「実践Vim」レビュワー選考結果発表 — KaoriYa

*4:受け入れられなかった、とかではなくて自分自身の固定観念やカルチャーショックを乗り越える大変さ、みたいなものだと思います。

*5:電話や対面によるものではなく、Intercomを利用したチャットサポート。

*6:直近の編集仕事でもめちゃめちゃ使いました。

ボッチでもOK

こちらは「春のPerl入学式リレーブログ」の7日目の記事です。
blog.perl-entrance.org

ひとつ前は、 id:kousy さんによる以下の記事でした。
kousy.hatenablog.com

Perl入学式での経験が仕事につながるというのは、すごすぎますね! 敬服します。
東京でのプログラマー生活、ぜひがんばってください。

今回の記事では、ぼくが初めてPerl入学式に参加したときのことを書きます。

ぼくが初めてPerl入学式に参加したのは、38才の夏でした。
これは同時に、ぼくがプログラミングの講義に参加した最初の機会であり、また初めて「プログラマー」と呼ばれる人々に対面した日でもありました。

その時のことは、以下の記事に書いています。
note103.hatenablog.com

今でもそうですが、ぼくは当時からプログラミングにまったく関係のない仕事をしていて、IT企業に勤める知り合いもいなかったので、このときには一人で参加することになり、会場には知ってる人が誰もいませんでした。

緊張していたせいか、時間よりも少し早めに会場に着くと、サポーター(スタッフにあたる人々) の id:papix さんや id:mackee_w さんたちもちょうど同じぐらいに着いていて、同じエレベーターに乗って上の階まで一緒に上がりました。

papix さんたちにはその時に少しだけ挨拶をしましたが、その後は基本的にサポーターさんはサポーター同士で楽しそうに話をしていて、今だから言えることですが、ぼくはうっすらと疎外感のような気持ちを抱いていました。

なにしろ、ぼくは年齢的に他の皆よりひと回りも(あるいはそれ以上に)離れていましたし、ITに関係ない仕事をしているのでその話題もまったく意味がわからず、周りに知り合いもおらず、Perl入学式自体も初めてで、さらにはその年の第3回の補講という、中途半端な回からの参加でもありました。

言うまでもなく、その疎外感はぼくが勝手に感じていたもので、サポーターの人たちから嫌な態度を示されたとかいうことは一切ありません。

ただ、自分以外の人は皆知り合いで、その人たちが共通の話題について楽しそうに話している、というその状況が、なんというか、チョット厳しかったわけです。

そしてぼんやりと、「ああ、自分が来るところではなかった」という気持ちになりました。

「呼ばれてもいないのに、身の程も知らずに、なぜこんな冒険をしてしまったのだろう?」と。

「あと何時間、この状況に耐えればいいんだ・・」と。

しかしながら、ボッチでも構わないから参加しよう、と思ったのは自分自身です。

とにかく時間が終わるまで頑張ろうと、そこは38才、なけなしの社会性を発揮して、こめかみには脂汗を浮かべながら、また周りの受講生の人たちともポツポツ会話を交わしながら、最後までなんとか時間を過ごしました。

それまでの人生でも、一人でイベントなどに参加することはよくありました。

知っている人が誰もいない場所に、後先考えずとりあえず飛び込んで、そのままコミュニティとの付き合いが始まったり、意図せず仕事につながったりすることもありました。

そういう経験が知らぬ間に体に染みついていたのか、初めは「すぐにでも帰りたい」と思っていたはずが、講義後の懇親会にも参加することになり、受講生やサポーターの人たちと少なからずおしゃべりをしながら、結局会場が閉まるまで残っていました。

その何日か後に、YAPC::Asia 2013が神奈川県の日吉で開催され、その中で行われたPerl入学式出張版にも参加しました。

Perl入学式 @ YAPC - YAPC::Asia Tokyo 2013
YAPC::Asiaで行われるPerl入学式のワークショップについて色々インタビューしてみました! | YAPC::Asia Tokyo 2013

なぜ一度痛い目にあったのに、懲りずにまた参加したのかというと、じつはYAPC::Asiaのチケットの方を先に買っていて、その下見のようなつもりで上記の講義(第3回補講)を受けていたからでした。

そして、このYAPC::Asiaでもまた、基本的にはずっと一人でした。

YAPCでのPerl入学式には、サポーターはもちろんのこと、先の受講生も何人か参加していたので、今度はまったくの一人ではなかったものの、YAPC全体を通してみれば、前夜祭でも、初日の懇親会でも、大半の時間は一人で過ごすことになり、それが数日間にわたり続いたため、このときには疎外感というより、もう少し重々しい、とりとめのない孤独のようなものを感じていました。

ちなみに、YAPCにおけるPerl入学式の内容は、普段とはちょっと違う番外編のようなもので、入門というにはひねりの効いた、少なくともぼくにはなかなかハードルの高いもので、何をやっているのかよくわからないうちに終わってしまった、という感じでした。

そういうこともあって、「やっぱりYAPC、俺には早すぎた・・」という後ろ向きな感想を持ちましたが、なぜかその後もPerl入学式には参加し続けることになり、翌年の4月からはサポーター側に回ることになりました。

ある種、痛切ともいえるボッチ体験に遭遇しながら、なぜその後もやめずに続けられたのかと考えると、結局のところ、その疎外感とか、孤独感とかいったツラさは最初に味わうものが一番大きくて、その後は痛みに慣れるというか、弱まるというか、軽減される一方だから、ということが言えると思います。

喩えてみると、バンソコウをはがす時に、最初にピャッとはがしてしまえばそれで終わるというか。

あるいはインフルエンザの予防接種を受けるときに、「はい、チクッとしますよ〜」とか言われて、「ひえ〜!」と思っても、その数秒後には全部終わってる、みたいな。

新しい体験がもたらす痛みは、最初の方ほど強く、しかし後は弱まる一方で、やがてそれは心地よい自分の居場所になっていきます。

この記事の前半で、エレベーターに乗ったときの話を書きましたが、今思えば、サポーターさんはサポーターさんで、普段はそれぞれ別の職場で仕事や生活をしていますから、Perl入学式という場で、気の置けない友人たちに久しぶりに会えたなら、普段はできない楽しい会話に時間を使いたくなるのはごく自然なことです。

当時のぼくからすれば、「自分と自分以外」という物の見方しかできていませんでしたが、実際には、サポーターにはサポーターの、特別な場としてのPerl入学式があったわけです。

普段の生活習慣から離れた場に、一人で飛び込むというのは、不安もあると思いますし、実際、人によってはツライ思いをすることもあるかもしれませんが、その次の瞬間から、欲しいものは確実に手に入ってきます。

ぼくの場合、それはプログラミングの技術でした。

だいぶ時間はかかりましたし、今なおかかっていますが、当初では考えられなかったほど、その技術を自分のものにし、それを楽しんでもいます。

プログラミングの勉強を始めるときに、一緒にやってくれる友達は不要です。
自分の体ひとつあればOKです。

Perl入学式では講義資料を広く公開していますし、

講義資料 - Perl入学式 | Perl Entrance

全国各地でも開催していますので、もし都合が合えば、いつでも参加してみてください。
www.perl-entrance.org

ノンプログラマーのためのPerl 〜 forと正規表現を使ったお得なセット

こんにちは。こちらはPerl入学式アドベントカレンダーの20日目の記事です。
(おっと日付が……🙇)

qiita.com

はじめに

あらためまして、まずここで「Perl入学式」について簡単に説明しておきますと、Perl入学式とは、Perlまたはプログラミング自体の未経験者に、Perlを通してプログラミングの基礎をお教えしましょう、という無料のプログラミング講座です。
www.perl-entrance.org

ぼくも2013年の8月、同年度第3回の補講から、まったく素人の状態で生徒として参加しまして、
Perl入学式#3補講に行ってきた - 103

その翌年春からはサポーター(運営側)に加わっています。

……といっても最近は地理的な問題などもあり、リモート参加が大半なのですが。
継続的に現場で開講しているメンバーの皆さんには、本当に敬服するばかりです。

さて本日は、ぼくのようなノンプログラマー、つまり普段の仕事ではプログラミングとは関係のないことをしている人*1が、プログラミング言語Perlを学ぶことによって、どんな便利なことになるのか、みたいな話をします。

といっても、その便利さをすべて説明しようとしたら大変な時間と文章量が必要になりますので、今回はその中でもとくに「これは」というところに絞って説明します。

for文

多くの場合、ぼくが普段の仕事をしているときに、「んー、こりゃプログラミングの力を借りた方がよさそうだな!」と思うのは、

テキストファイルAの内容に何らかの処理を加えて、テキストファイルBとして保存する

みたいなことをやりたい時です。

具体例を挙げてみると、たとえば以下のような名簿があったとして、

ジョン・レノン
ポール・マッカートニー
ジョージ・ハリスン
リンゴ・スター

このすべての文末に敬称「さん」を付けたい、という場合。

いやもちろん、このぐらいなら自分で書けばいいんですが、これが何百人もいたら大変なので……ということ。

こんなとき、ぼくだったらこんなコードを書きます。

#!/usr/bin/env perl
use strict;
use warnings;

my @band = qw/
ジョン・レノン
ポール・マッカートニー
ジョージ・ハリスン
リンゴ・スター
/;

for my $member (@band) {
    print "$memberさん\n";
}

まず配列 @band に4人の名前を入れて、これをforループで回しつつ、出力時に「さん」を加えています。

実行してみると……
gyazo.com

はい、できました。for文、めっちゃ便利ですね。

このfor文については、Perl入学式の講義資料より以下をご参照ください。
https://github.com/perl-entrance-org/workshop-2017/blob/master/2nd/slide.md#for文-配列

qwについては以下をどうぞ。
https://github.com/perl-entrance-org/workshop-2017/blob/master/2nd/slide.md#qw-ショートカット

if文、正規表現

さてしかし、現実の世界では、このように元のデータすべてに同じ処理をするという機会はそうそうなくて、この内の「ある条件に合致するもの」だけに処理を加えたい、ということが多いです。

たとえば、この中で名前の最後に「ン」が付く人だけ敬称を「様」にしたい、という場合にはどうすればいいでしょうか?

そのような時には、こう書きます。

#!/usr/bin/env perl
use strict;
use warnings;

my @band = qw/
ジョン・レノン
ポール・マッカートニー
ジョージ・ハリスン
リンゴ・スター
/;

for my $member (@band) {
    if ($member =~ /\z/) {
        print "$member\n";
    }
    else {
        print "$memberさん\n";
    }
}

実行。
gyazo.com

はい、できました。

このif文と、それに付いてくる正規表現(「=~」とか「//」を使って色々やっているもの)については、同じくPerl入学式の講義資料から以下をご参照ください。

if文
https://github.com/perl-entrance-org/workshop-2017/blob/master/2nd/slide.md#if-else文

正規表現
https://github.com/perl-entrance-org/workshop-2017/blob/master/4th/slide.md#正規表現

__DATA__

さてここで、一旦冒頭の話に戻りますが、普段の仕事(プログラミングとは関係ないそれ)をしていて、時々欲しくなるのは、

テキストファイルAの内容に何らかの処理を加えて、テキストファイルBとして保存する

という能力です。

上の例でいうと、テキストファイルAにあたるのは

ジョン・レノン
ポール・マッカートニー
ジョージ・ハリスン
リンゴ・スター

で、処理後のテキストファイルBにあたるのは

ジョン・レノン
ポール・マッカートニーさん
ジョージ・ハリスン
リンゴ・スターさん

になります。

ただ、さすがにこんな風に、処理したいデータ(ここではその4名)を毎回コードの中に埋め込むというのは面倒というか、できればコードはコード、素材データは素材データとして分けて扱いたいので、上記に加えてぼくが多用するのが「__DATA__」という記法*2です。

さっそく、それを使って書き換えてみましょう。

#!/usr/bin/env perl
use strict;
use warnings;

my @band = <DATA>;

for my $member (@band) {
    chomp $member;
    if ($member =~ /\z/) {
        print "$member\n";
    }
    else {
        print "$memberさん\n";
    }
}

__DATA__
ジョン・レノン
ポール・マッカートニー
ジョージ・ハリスン
リンゴ・スター

はい。だいぶスッキリしました。
結果は先ほどと同じですが、一応実行してみましょう。
gyazo.com

いいですね。
こうすることによって、対象のデータがいくら変わっても、それは「__DATA__」より下の部分で書き換えればよくなり、それより上のコード部分を触る必要がなくなります。

また、この方法だと1本のスクリプトファイルで完結するので、コードもデータもそれぞれ手軽に書き換えられて便利です。

じつのところ、ぼくが普段の仕事に関連して書くコードの大半は、これのバリエーションです。

たとえば、少し前に、別のアドベントカレンダーでこんな記事を書いたのですが、
note103.hateblo.jp

この後半で紹介している、本の脚注データを分析するコードにしても、途中でハッシュを使ったりはしていますが、基本形は上記と同じであることがわかるかと思います。

実際には、もう少し踏み込んだことをしようとすると、コードとは別に置かれた素材ファイルを読み込んだり、結果を別のファイルに書き出したり、あるいは任意のディレクトリにあるファイルを読み込んだりもしたくなってくるのですが、まずは上記のようなことができるだけでも、かなりいろんな作業が効率化するので、入門者の方は試しにこれらのセット(for + if + 正規表現 + __DATA__)を自分の環境で動かしてみてはいかがでしょうか?

ちなみに、環境構築を含む第1回からの講義資料は、以下にまとまっています。
講義資料 - Perl入学式 | Perl Entrance

ということで、本日の記事は、以上です。

明日の……ではなくて、本日のご担当はgomaaaさんです!

Perl入学式のアドベントカレンダー、ひき続き、お楽しみに。
qiita.com

*1:ぼく自身は本の編集をしています。より詳しくはこちらをどうぞ。→ note103 - note103 - Scrapbox

*2:『初めてのPerl(第6版)』によると、厳密には「ファイルハンドル」と呼ばれるようです。ファイルハンドルとは、Perlの処理世界と外部世界(おそらく素材のテキストデータなど)を結びつけるコネクションの名前、とのこと。詳しくは同書をどうぞ。

初めてのPerl 第6版

初めてのPerl 第6版

2つの配列から重複を弾く(Perlで)

いきなり例題から。

以下のような2つの配列があるとき、

my @fruits1 = qw/orange banana apple lemon/;
my @fruits2 = qw/orange banana/;

@fruits1のうち@fruits2とカブるものをカットして、重複しないappleとlemonだけ@fruits1に残したいとする。

こういうとき、今までぼくはこう書いていたのだけど、

#!/usr/bin/env perl
#
# cut_overlap.pl

use strict;
use warnings;
use feature 'say';

# 以後、配列名は短縮
my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

for my $f2 (@f2) {
    for my $f1 (@f1) {
        if ($f1 eq $f2) {
            say "match:\t$f1!";
            @f1 = grep {$f1 ne $_} @f1;
        }
    }
}

say '===';
say "\@f1の残りは……";
say for @f1;
say "です!";

まあ、これでも目的は達成できる。実行結果は以下。

match: orange!
match: banana!
===
@f1の残りは……
apple
lemon
です!

最初にorange、その後にbananaがマッチして、あとにはappleとlemonが残っている。

コードでやってることとしては、まず2つの配列をループさせて、要素同士がマッチしたらその要素を元の配列からgrepで削除する。

削除というか、実際には「対象の要素以外を元の配列に入れ直す」という感じか。

で、ここでは重複を弾きたい(数を減らしたい)@f1の方を内側のループにして、grepでもその配列を対象としてカットしている。

というのも、この内と外を逆にすると、

# 以後、シバンやプラグマは省略
#
# cut_overlap2.pl

my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

for my $f1 (@f1) { #<= 外側にもってくる
    for my $f2 (@f2) { #<= 内側に入れる
        if ($f1 eq $f2) {
            say "match:\t$f1!";
            @f1 = grep {$f1 ne $_} @f1;
        }
    }
}

say '===';
say "\@f1の残りは……";
say for @f1;
say "です!";

結果。

match: orange!
===
@f1の残りは……
banana
apple
lemon
です!

こんなふうに、意図に反して最初のorangeだけマッチして、本来消えてほしいbananaが残ってしまう。

中身はどういうことになってるのか、必殺のprintデバッグ

# cut_overlap3_debug.pl

my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

for my $f1 (@f1) {
    for my $f2 (@f2) {
        say "f1:$f1 & f2:$f2"; #<= 中身を出力してみる
        if ($f1 eq $f2) {
            say "match:\t$f1!";
            @f1 = grep {$f1 ne $_} @f1;
        }
    }
}

say '===';
say "\@f1の残りは……";
say for @f1;
say "です!";

結果。

f1:orange & f2:orange
match: orange!
f1:orange & f2:banana
f1:apple & f2:orange
f1:apple & f2:banana
f1:lemon & f2:orange
f1:lemon & f2:banana
===
@f1の残りは……
banana
apple
lemon
です!

ということで、どうやら最初にorangeにマッチした後、@f1が2周めでbananaを飛ばしてappleの周回に入ってしまっている。(実行結果の4行目)

ちなみに、さっきの上手くいった場合だと、内部はどうなっているのかというと、

f1:orange & f2:orange
match: orange!
f1:apple & f2:orange
f1:lemon & f2:orange
f1:banana & f2:banana
match: banana!
f1:lemon & f2:banana
===
@f1の残りは……
apple
lemon
です!

という感じで、このときは目的上の影響がなくて気づかなかったけど、じつはここでもorangeがマッチした後、@f1のbananaがスッ飛ばされている。(実行結果の3行目)

ということで、実利的には最初の方法であれば目的は果たせるものの、裏で起こっていることはどちらも意図と違うというか、ちょっと気持ち悪い感じがあって、そこでいつもお世話になっていますPerl入学式のサポーター陣とのチャットでいろいろ相談してみた。

で、さっそく @xtetsuji さんからいただいた解答例がこちら。

# xtetsuji_1.pl
# 
# 出力部分は省略

my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

array_minus1(\@f1, \@f2);

sub array_minus1 {
    my $f1 = shift;
    my $f2 = shift;
    @$f1 = map {
        my $f1_value = $_;
        ( grep { $f1_value eq $_ } @$f2 ) ? () : $f1_value;
    } @$f1;
}

さらに、もう1案いただいた。

# xtetsuji_2.pl

my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

array_minus2(\@f1, \@f2);

sub array_minus2 {
    my $f1 = shift;
    my $f2 = shift;
    my %f2_value_is = map { $_ => 1 } @$f2;
    @$f1 = map { $f2_value_is{$_} ? () : $_ } @$f1;
}

結果はいずれも、以下。

@f1の残りは……
apple
lemon
です!

前者はgrep, 後者はmapを使っているけど、どちらも「マッチしたら空リストに入れる=元の配列から外す」という処理になっている。

そしてそれとは別に、@skjmさんからAcme::Toolsのminusもあるよ、と教えて頂いて。
Acme::Tools - search.cpan.org

これを使うと、こんな感じ。

# acme_minus.pl

use Acme::Tools 'minus';

my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

my @result = minus(\@f1, \@f2);

say "\@f1の残りは……";
say for @result;
say "です!";

結果は同じなので省略。

このAcme::Tools::minusの中身はこんな感じ。

sub minus {
  my %seen;
  my %notme=map{($_=>1)}@{$_[1]};
  grep !$notme{$_}&&!$seen{$_}++, @{$_[0]};
}

http://cpansearch.perl.org/src/KJETIL/Acme-Tools-0.21/Tools.pm

ちょっと略記が多いのでわかりづらいのだけど、自分が見慣れた書式に噛み砕くと……

sub minus {
    my $f1 = shift;
    my $f2 = shift;

    my %notme = map { ($_ => 1) } @{$f2};

    my %seen;
    my @result = grep { !$notme{$_} && !$seen{$_}++ } @{$f1};

    return @result;
}

といった感じか。

ちなみに、これの途中にある以下のインクリメント。

!$seen{$_}++

何度見てもこれのある意味がわからず、実際、これを取っても結果は同じなのだけど、じつは最初の配列@f1に対して、

my @f1 = qw/orange banana apple lemon/;
my @f2 = qw/orange banana/;

以下のように、同配列内の重複要素を入れてみると、結果も変わる。

my @f1 = qw/orange banana apple lemon apple/; #<= 末尾にappleを追加
my @f2 = qw/orange banana/;

先のインクリメントを入れた状態だと、これまで通りこうなるのだけど、

@f1の残りは……
apple
lemon
です!

そのインクリメントを外して以下のようにすると、

my @result = grep { !$notme{$_} } @{$f1};

結果はこうなる。

@f1の残りは……
apple
lemon
apple
です!

つまり、そのインクリメントは元になる配列(@f1)内の重複をカット(ユニーク化)してくれていた。

ということで、これについてはもう要件の問題というか、このツールを使う人がそもそもどういう結果を期待しているか? によって要不要を判断するところだろう。

とりあえずぼくの当初の希望としては、「片方の配列からもう片方の配列と重複する要素を取り除く」ということだけを求めていて、「元の配列内に存在する重複も取り除く」ことは求めていないので、そのインクリメントなしバージョンの方が適切かもしれない。

結論としてのコード集

すでにけっこう長くなってしまったけど、もう少しコード例を挙げつつ、では結局のところ、ぼく自身は今後どういうときにどういうコードで対応していくか、というまとめ。

remove

まずはこれまで話題にしたとおり、「片方の配列からもう片方の配列と重複する要素を取り除く」ということをしたい場合には、こんな関数を使う。

sub remove {
    my $whole = shift;
    my $part = shift;

    my %remove = map { $_ => 1 } @$part;

    my @result;
    for my $element (@$whole) {
        if (! $remove{$element}) {
            push @result, $element;
        }
    }
    return @result;
}

これを以下のように呼び出すと、

my @f1 = qw/orange banana apple lemon apple/;
my @f2 = qw/orange banana/;

my @result = remove(\@f1, \@f2);
say for @result;

@f1から@f2の要素と重複する要素を取り除いたものが出てくる。

apple
lemon
apple

この際、@f1内の重複はカットしない。

crush

次に、じつはこれまでに出た要件とは別に、「とにかく重複するものは全部消してほしい」と思うこともあるので、その対策。

この場合、上記の修正前の Acme::Tools::minus でも微妙に適合していなくて、なぜなら上述のとおり、同配列の重複については最低でも1つ残してしまうから。

しかしここでの新たな要件は、たとえば以下の2つの配列があった場合、

my @f1 = qw/orange banana apple lemon apple/;
my @f2 = qw/orange banana/;

lemon以外はすべて重複しているので、

lemon

とだけ出てほしい。

で、そのためにこのような関数を作ってみた。

sub crush {
    my $x = shift;
    my $y = shift;

    my %crush;
    map { $crush{ $_ }++ } ( @$x, @$y );

    for (keys %crush) {
        if ($crush{$_} >= 2) {
            delete $crush{$_};
        }
    }

    my @result;
    for ( @$x, @$y ) {
        if ($crush{$_}) {
            push @result, $_;
        }
    }
    return @result;
}

これで以下のように実行すると、

# 以後、果物の種類を増やす

my @f1 = qw/orange banana apple grape lemon apple/;
my @f2 = qw/orange banana strawberry/;

my @result = crush(\@f1, \@f2);
say for @result;

以下のように、とにかく全体の中で重複したものは取り除いてくれる。

grape
lemon
strawberry

この際、関数内ではハッシュで処理しているので、途中で順番がめちゃくちゃになっているのだけど、用途としては関数に渡した順に返ってきたほうが便利な気もするので、最後のfor文で順番を元に戻している。

ちなみに、関数名の crush というのは、重複した果物どうしをぶつけてつぶしてしまうイメージより。ジュースになって、形が消えるというような。

uniq

ついでにもう一つ、途中で少し話題にしたけど、渡した配列全体の中から、重複した余分な分はカットしつつ、でも1つは残しておきたい場合。

これは List::MoreUtilsのuniq関数を使えば早い。

use List::MoreUtils 'uniq';

my @f1 = qw/orange banana apple grape lemon apple/;
my @f2 = qw/orange banana strawberry/;

my @result = uniq(@f1, @f2);
say for @result;

実行。

orange
banana
apple
grape
lemon
strawberry

登場した果物すべてが1つずつ残っている。

uniqはリファレンスではなく普通に配列を渡すだけなので、用途が合えば作業も手っ取り早くてよい。

まとめ・謝辞・宣伝

ということで、さすがにこれだけ対処法を作っておけば、この辺りの要望には応えやすくなるだろう。

冒頭に示した危なっかしい二重ループ&grepの方法に比べると、コードの効率としても安心感としてもだいぶ改善したのではないか。

そして今回もまた、いつものようにPerl入学式のサポーターの皆さんには大変お世話になりました。
ぼくも一応サポーターなんですが、まだまだ教わってばかりです……。

ちなみに、Perl入学式は東京・大阪に加えて去年からスタートしたin沖縄、そして今年からはin北海道も増えて、ますます積極的に活動中です。
www.perl-entrance.org

近いところだと今週土曜にin東京の今年度前期の第2回が開催されます。
perl-entrance-tokyo.connpass.com

その翌週には大阪と沖縄、さらにその後に北海道もありますので、興味のある方はぜひご確認のほど。
perl-entrance-okinawa.connpass.com
perl-entrance-sapporo.connpass.com
perl-entrance-osaka.connpass.com

以上です。

(大阪の画像……)

Perlの正規表現で名前付きキャプチャとqr//演算子を使ってみた話

少し前にこのようなツール&記事を書いたのだけど、
note103.hateblo.jp

簡単に説明すると、「URLを渡すとMarkdownの書式でそのページタイトル&URLを返してくれる」というもの。

で、そのコードについて、Perl入学式でいつもお世話になっています @xtetsuji さんから指摘があって、この extr サブルーチンの if文にある $4 ってなに? と。

sub extr {
    my $e = shift;
    my ($x, $y);
    if ($e =~ /(.*)(\(http[:s][^\s,;>]+\))(.*)/g) {
        $x = $1 if $1;
        $y = $4 if $4;  #<-これ
        if ($x && $y) { $rest = $1.$4;  #<-これ
        } elsif ($x) { $rest = $x;
        } elsif ($y) { $rest = $y;
        }
    } elsif ($e =~ /(.*)(http[:s][^\s,;>]+)(.*)/g) {
        push @urls, $2;
        $x = $1 if $1;
        $y = $3 if $3;
        if ($x && $y) { $rest = $1.$3;
        } elsif ($x) { $rest = $x;
        } elsif ($y) { $rest = $y;
        }
    }
    extr($rest) if ($rest =~ /(.*)(http[:s][^\s,;>]+)(.*)/);
}

urls/Urls.pm at da66791eccec8fc33e0bd1c7a95994deca1c66d3 · note103/urls · GitHub

んん〜……何って……何だろう……?(笑)
自分でもわからない。というか、よくよく読むと、たぶん、というかどう考えてもその正規表現のパターン部分、

    if ($e =~ /(.*)(\(http[:s][^\s,;>]+\))(.*)/g) {

この http で始まる部分を囲う丸括弧のうち、エスケープしているはずの括弧もキャプチャ対象としてカウントしてしまって、本来存在しないはずの $4 というのを書いてしまった。ということだと思うのだけど、じゃあそれを正しく数え直して $3 にすると、今度はそのif文の中身と、その下のelsif文の中身がほぼ同じになってしまって、そのまま繰り返させてしまうのはさすがに具合が悪い、というか DRY(Don't Repeat Yourself) の原則に反するという新たな問題が……。

しかも、だからといって共通する数行をif文の外に持ち出すと、こんな感じになって、

sub extr {
    my $e = shift;
    my ($x, $y);
    if ($e =~ /(.*)(\(http[:s][^\s,;>]+\))(.*)/g) {
    } elsif ($e =~ /(.*)(http[:s][^\s,;>]+)(.*)/g) {
        push @urls, $2;
    } else {
        next;
    }

    $x = $1 if $1;
    $y = $3 if $3;
    if ($x && $y) { $rest = $1.$3;
    } elsif ($x) { $rest = $x;
    } elsif ($y) { $rest = $y;
    }
    extr($rest) if ($rest =~ /(.*)(http[:s][^\s,;>]+)(.*)/);
}

とりあえず $x, $y への代入部分の重複がなくなったのは良いけれど、$1, $3 をif/else文の外に持ち出すというのは何となくわかりづらいような……という問題にさらに加えて、正規表現のパターンがほぼ同じであるにもかかわらずこれだけ短い間に3回も繰り返し書かれていて、ちょっと綺麗じゃないような……とかなんとか。

などと思っていたら、@xtetsuji さんからのさらなるアドヴァイスで、前者については「名前付きキャプチャを使えば見やすくなるかも」、そして後者については「qr//で正規表現を事前定義しておくと良い場合がある」とのこと。

なるほど。じつは名前付きキャプチャについては、ぼくもちょうどその数日前にこんなツイートをしていたぐらいで、

もう少し実践的に使ってみたいと思っていた。

プラス、qr// についてもいつも q// や qq// や qw// との違いを思い出すのにいちいち時間がかかって面倒だったので、この機会にあらためて勉強してみよう、ということで、いろいろ情報を参照しつつとりあえずこんな感じに。

sub extr {
    my $e = shift;
    my ($x, $y);

    if ($e =~ /(?<prematch>.*)(\($regexp\))(?<postmatch>.*)/g) {
    } elsif ($e =~ /(?<prematch>.*)(?<match>$regexp)(?<postmatch>.*)/g) {
        push @urls, $+{match};
    } else {
        next;
    }

    $x = $+{prematch} if $+{prematch};
    $y = $+{postmatch} if $+{postmatch};
    if ($x && $y) { $rest = $x.$y;
    } elsif ($x) { $rest = $x;
    } elsif ($y) { $rest = $y;
    }
    extr($rest) if ($rest =~ /(.*)($regexp)(.*)/);
}

で、その後に別の部分もちょっと調整しつつ、ひとまず現状(この記事を書いている時点)の最新版はこんな感じで。

DEMO

で、その動いてるところ……は、挙動を改良したわけではないので前回と同じ動画ですが、こんな様子。

1本だけ渡す場合。
f:id:note103:20160505185803g:plain

複数のURLを渡す場合。(1行に複数のURLが入っててもOK)
f:id:note103:20160505185909g:plain

謝辞

今回も @xtetsuji さんには大変お世話になりました。ありがとうございます。 :bow:

また、このあたりのやり取りはPerl入学式の運営用Slackで行われたのですが、校長の @papix さんやその他メンバーの方々も時折絡んで&盛り上げてくれて楽しみながら学ぶことができました。重ねてありがとうございます。

で、そんなPerl入学式ですが、東京・大阪・沖縄の本年度第1回の開催日が近づいてきました。
ざっと日程だけ書き出すと、こんな感じ。

  • Perl入学式 in東京 第1回
    • 2016年5月14日(土)
  • Perl入学式 in大阪 第1回
    • 2016年5月28日(土)
  • Perl入学式 in沖縄 第1回
    • 2016年6月18日(土)

東京編はもう来週ですね。

その他、詳細については公式サイトをご参照ください。
www.perl-entrance.org

ちなみに、沖縄編に関しては、記念すべき第1回開催に向けて沖縄サポーターの方が書かれたブログ記事を絶賛校正中ですので、近日中に以下で公開される予定です。
(というか僕が止めてます……すみません)
perl-entrance.blog.jp

以上です!