Perlで 'use strict;' をしない状態で 'return nil' をした時の挙動
こんばんわ、忘年会シーズンというにはもう遅いタイミングですね。
先日 gotanda-pm 忘年会の酒の席の話で
"Perlで 'use strict;' をしない状態で 'return nil' をした時どうなるか?" といった話が上がり
酒の席のせいか妙にテンションが上りツボに入ってしまい以下のようなツイートをしました。
Perlで、'use strict;' をしなければ 、'return nil' で undef が返るという話が今年聞いたperlの一番面白い話になってしまった。
— ╹) っ < (@likk) December 27, 2016
ruby を普段書いてる人が perl を書くと起き得る事故ですね。
通常 `use strict;` をした状態だと `nil` ベア(裸の)ワードの最適化を制限してくれてコンパイルエラーを出してくれます。
ですが `use strict;` をしないどうなるか?
最適化の結果 nil は値が設定されてないし、関数も無いし予約語でも無いので偽が返すと解釈し上記のようなツイートにつながりました、
では、実際に実行してみるとどうでしょうか。
$ perl -E 'say sub { return nil}->()'; nil
おや、nil が返ってきますね。ツイートした内容と相違があります。
これは perl ではどのように解釈してるでしょうか
$ perl -MO=Deparse -E 'say sub { return nil}->()'; use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; say sub { return 'nil'; } ->(); -e syntax OK
文字列 "nil" と解釈してるのが分かります。
perl は文字列を真として扱ってくれますので、結果としてツイートの内容が"偽" であるというオチがついてしまいました。
ということで以下の締めになります。
酒の席で聞いた話を検証できる環境が手元にあるにも関わらず検証せずにツイートするのは良くないですね。
— ╹) っ < (@likk) December 28, 2016
以下蛇足:
`print nil;` が何も出力されないので、nil が undef っぽい挙動になります。
$ perl -e 'print nil'; $
これはどう解釈してるか同様に見てみるとすぐに分かります。
$ perl -MO=Deparse -e 'print nil'; print nil $_; -e syntax OK
nil をファイルハンドルとして扱ってそこに print してるから。
つまり`print nil $_` として解釈をしてるので何も出力されない挙動となります。
use strict!
Acme::Kiyoshi でっちあげた
元ネタ
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも (@kumiromilk) 2016年3月9日
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた
だいぶ出遅れてる感じがあるけど Perlで書いたのでgithubに上げた。
インストールしたら
perl -MAcme::Kiyoshi -E 'kiyoshi'
で実行できます。今のところ最短タイプ数であなたもZUN DOKO KIYOSHI!ができます。
以下、実行結果。
$ cpanm https://github.com/Likk/Acme-Kiyoshi.git Cloning https://github.com/Likk/Acme-Kiyoshi.git ... OK --> Working on https://github.com/Likk/Acme-Kiyoshi.git Configuring /tmp/R_aUbFiUCB ... OK Building and testing Acme-Kiyoshi- ... OK Successfully installed Acme-Kiyoshi- 1 distribution installed cpanm https://github.com/Likk/Acme-Kiyoshi.git 2.02s user 0.34s system 52% cpu 4.508 total $ perl -MAcme::Kiyoshi -E 'kiyoshi'; ZUN ZUN DOKO DOKO ZUN DOKO ZUN DOKO ZUN DOKO ZUN DOKO DOKO DOKO ZUN ZUN ZUN DOKO ZUN DOKO ZUN DOKO ZUN DOKO DOKO ZUN ZUN ZUN ZUN ZUN ZUN ZUN ZUN DOKO KI.YO.SHI!
久々にブログ書いたかと思えば何をやってるんだ自分は。
Gotanda.pm #6 で飛び込みLTしてきた。
Gotanda.pm #6 2015/09/17 (木) からかなり時間が経ってからのブログ書き込みだけど気にしない。
テーマは「障碍」でしたので何かやろうかなと思っていたけどスライド用意している時間がなくて、LTするつもりは無かった。
全てのプログラムが終わり、同会場内で懇親会を始めるタイミングだったのですが、
懇親会側の準備が終わってなく時間が余ったので肉が焼けるいい匂いの中スライドもなしにTLしてきました。
障碍というテーマにそって「リアルで障碍が起きたとき通知をするbotを以前作ってましたよー、リアルな障碍とは何か、例えば電車遅延だったり、地震だったり、台風だったり、あるいはYAPCでLTした雨雲通知だったり、そういうの。」とい内容で話してきた。
情報を取得するライブラリはgithubに全部上がっるので自分のgithubリポジトリを紹介するだけのLTになった。スライド無いしね。以下のリポジトリはその時に紹介したリポジトリ
Likk/WebService-TenkiJp-RSS-WeatherNews · GitHub
- tenki.jpのRSSから、天気概要を取得する
Likk/WWW-TrainInfo · GitHub
- 鉄道各社のサイトの遅延情報をスクレイピングして何線が遅延・運休してるかを取得する
Likk/WebService-TenkiJp-Typhoon · GitHub
- tenki.jpの台風情報をスクレイピングして台風の概要を取得する
ただ、「以前作ってましたよー」と言うだけの話であるとおり、今はメンテしてないので今は動かないと思う。メンテを再開したりする予定はないです。
理由としては、公式のbotがtwitterにあるので今はそれを見たほうが早いから。
あと、意外と気象庁や鉄道会社の公式の発表より、ニュースサイトの方が早く情報が得られたりします。
更に言うとニュースサイトよりも、ニュースサイト公式twitter botの方が速報早かったりもします。
どっちかというとリポジトリ供養LTというのが正しい。
あと、飛び込みLT楽しかった。スライドが無くても、失敗しても「飛び込みだし!!」と思えば気負うものはなにもない。(言い訳もできる!!)
お疲れ様でした。
思いつきだけどリポジトリ供養LT大会やると楽しそう。github url伝えるだけなので、みんな頑張ってスライド作る必要ないしね。
(「スライド頑張った時点でもうL(ightning)Tじゃないよね。」という面白い意見も懇親会で頂きました。)
YAPC::Asia 2015 でLTしてきた
一日目のライトニングトークにて『YAPC?雨事情』というタイトルで発表させていただきました。
スライド中で紹介したライブラリは以下です。git log たどると実は2012年ぐらいからありましたgithub.com
YAPC初LTでしたし、1000人超の前で話すことも初めてでしたので、めちゃめちゃ緊張しましたが結果的よかったと思います。
YPACには2007年から参加してましたが、毎年視聴者側で今年もLTで出る予定はありませんでした。基本的に引っ込み思案なのです。
開催一週前にたまたまGaiaXさんとモバイルファクトリー合同勉強会があり、
そこでLTする機会があったので、大体同じ内容で発表し、その勢いで応募しました。
五反田界隈のみなさまありがとうございました。
実際のLTの最中は緊張していて反応が良く分からなかったですが、
twitterや懇親会で質問や、コメントや、ツッコミを頂いたりしました。
案ずるより産むが易しのことわざ通り、一旦発表してしまうと、あと5年早くやっておけばと過去の自分を責め続けます。
来年も何らかあるのであれば、何かしらトークできるといいかなと思います。
以下、頂いた質問やツッコミに対する回答。
Q: ametto とLTとの関係。
A. 誤解を与えないよう、LT中でもお伝えしたつもりですが、アプリ ametto の機能には今回のLTで発表した内容に関わることは一切含まれてま
せん。ただのCMです。
Q: 雨通知アプリ(ammeto)があるならその機能使えばいいのでは
A: 通知基準が違います。ametto は「"降水確率"という同じ気象条件下なら統計学的にどれぐらい雨が降る確率があるか、それが一定値以上なら通知する」というにアプローチ対して、雨雲通知botは「気象レーダを使い雨雲が現在どこにあるか地図上に表示する画像を解析し、特定地点の色が晴天時と差異があれば通知する」というアプローチです。今日の品川区の降水確率が100%だからといって、今現在五反田駅周辺で降ってるとは限らないということです(どっちにしろ、傘持って出る必要はありますが)。ついでに言うと雨雲通知botのほうが歴史が古いです。
Q: 残り時間がGame Overだ
A: リロード忘れました。というか回線が不安定でリロードする勇気がありませんでした。スライドはローカルにおいておくべきでした。
オチ
#yapcasia オフィス周辺でピンポイントに雨が降ってるどうかの雨雲通知botを作る前に、窓から外を見ろという大変ありがたい指摘を頂きました。
— Likk (@likk) August 21, 2015
String::Slack でっちあげた
使い方は簡単で
say String::Slack->new("message")->bold->italics->stringify; #_*message*_
となる。
きっちりとslack.com に投げるところまで書く場合のsampleコードもつけた。
use strict; use warnings; use Furl; use JSON::XS qw/encode_json/; use HTTP::Request::Common qw/POST/; use String::Slack; my $message = 'hoge'; my $url = 'https://slack.com/api/chat.postMessage'; my $token = 'xxxxx-XXXX-XXXX'; my $channel = 'XXXXXXX'; my $data = { channel => $channel, text => String::Slack->new($message)->bold->italics->stringify, as_user => 1, }; my $request = POST($url, Content_Type => 'form-data', Content => [ token => $token, %$data, ] ); my $res = Furl->new->request($request);
こんな感じで簡単にslackに投げる文字に装飾をつけることが出きる。
DBIx::Skinnyのトランザクション観測したい。
実装書いてるうちに、どのタイミングでcommit/rollback が発行されるのか確認したくなったんだ。
そしたら。
DBIx::Skinny::txn_scope() だと BIGIN と ROLLBACK がDBIx::QueryLog で観測できない……
— Likk (@likk) April 23, 2015
正確にはBEGIN/COMMIT/ROLLBACK
txn_scope を使わずに、search_named() を使うと BEGIN/COMMIT/ROLLBACK はきちんとDBIx::QueryLogのログに吐かれる。かと言ってトランザクション自前管理はしたくない。どうにかDBIx::Skinny::Transactionを観測する方法はないだろうか。普通にwarnするか。
蛇足。
ソースコード見てるうちにちょっとイタズラしたくなった。
DBIx::Skinny::txn_scope(); 張った同一コネクションの中で、DBIx::Skinny::search_named(q{COMMIT WORK},{}); とやるなどして無事コミットされてしまうのを確認した。
— Likk (@likk) April 23, 2015
search とはいったい。
— Likk (@likk) April 23, 2015
#下書きのまま放置していたので公開。
#結局 Test::Mock::Guard 辺りで観測する事に落ち着いた。
コマンドラインからslackチャット
slackを使い始めたのでコマンドラインからslackの閲覧と発言が出きるツール書いたのでgistに上げた。
これは下記エントリ id:mihyaeru21 が作ってくれたライブラリWebService::Slack::WebApiを使ってるので、APIとの疎通周りをほとんど気にせず書くことができた。mihyaeru21.hatenablog.com
煩わしいチャンネル移動も不要だし、$SAVE_FILE_PATHを有効にすればログを手元に保存するのでログ上限とかも気にしなくて済む。
ただslackの便利なコマンド補完ができないので普通にwebかクライアント使うほうがどう考えても楽なので、お気楽にログを眺めていたい程度の時に立ち上げておくといい感じになるかもしれない。
実行は簡単で単にコマンドを叩いて初回に聞かれるAPI-TOKENを入力するだけ。Config::Pit を使ってるので二回目以降の立ち上げはそれも不要。
発言したい時は
#channel_name hoge
とか入れるとそのチャンネルにpostされる。
これも2回目以降はチャンネル名は不要で本文だけ入れればpostできる。
別のチャンネルに発言したくなったら、改めてチャンネル名を入れればいい。
実行時のイメージは下記な感じ。