Masteries

技術的なことや仕事に関することを書いていきます.

英語学習としての Perl/perl5 購読

最近英語学習をじわじわと進めているのですが, その一環としてGitHubのPerl/perl5を購読する活動(?)をはじめました.

github.com

去年の11月辺りから, Perl5の開発がGitHubが主軸になるように変更されていて(過去のIssueとかも移植されている), 手軽にContributeしたり, IssueやPull Requestを追えるようになりました.

購読して何をしているか? と言うと, 具体的にはGmailに届いたIssueやPull Requestの通知を, タイトルを見て面白そう!!! と思ったものを中心に空き時間に眺めていく, という感じでやっています. iPhoneだと, よくわからない単語を長押しして「調べる」とすると, 英和辞書とか開けるので, 移動中でもサクッと読めて便利です.

ひとまず英語を目にする, 英文を読む機会を増やそう, という施策で始めた感じですが, 何れは何かしらのContributeもできればいいかな〜, と思っています.

The Perl and Raku Conference in Amsterdam 2020にproposalを出しました

去年, 「PerlCon 2019」に参加してとても良い経験が出来たので, 今年も行くぞ!!! ということで, 「The Perl and Raku Conference in Amsterdam 2020」にproposalを出しました.

developer.hatenastaff.com

去年, 「PerlCon 2019」に参加したときの様子はこのエントリに書きました.

proposalのネタ

去年は「Perl in Japan」ということで, 日本のPerl界隈の様子を話してきたのですが, 今年は何について話そうかな〜, と考えた結果, 拙作のClass::Accessor::Typedについて話そうかなと思いました. Class::Accessor::Typed, MooやMouseなどのオブジェクトシステムと, Class::AccessorやClass::Accessor::Liteのようなライブラリのちょうど真ん中くらいの立ち位置にあると思っていて, 程よく便利で使い勝手も良いと思っており, 紹介しつつ新しいアイデアなどを得ることができればいいなー, とか思ったりしています.

title: Introduce of Class::Accessor::Typed

In this talk, I introduce Class::Accessor::Typed.

When you want to implement a new object in Perl, which CPAN module do you use?
We have many choices. One of the options is using Object System like Moose, Moo, and Mouse.
And another option is using automated accessor generator like Class::Accessor and Class::Accessor::Lite.
Of course, using "bless" is one of the simple solution.

In this case, usually, I use Class::Accessor::Lite.
Because that is lightweight, fast and readable.
But, Class::Accessor::Lite does not have type system.
So, I think that It is difficult to use in large scale system development.

To solve this problem, I implemented Class::Accessor::Typed.
This module is fast and readable like an automated accessor generator and supports type system using Mouse::Util::TypeConstraints.

In this talk, I want to talk about function, implementation method and benchmark result about this module. 

(英文は一応grammarlyを通したりチェックしていますが, 明らかにおかしいところがあったらTwitterのDMとかでこっそり教えて下さい...)

正直なところ, もう航空券など全部手配してしまったので, proposalの採否に関わらず参加する予定なのですが, 折角なので話せると良いですね. 海外のカンファレンス, やっぱり勇気は必要とは思いますが, とはいえいろいろな面で得るものが多いので, 皆さんも是非どうですか. 僕と一緒に英語を勉強しようよっ!!! (最近サボリ気味なので, 夏に向けて頑張らねば... と思っています)

TypeScriptの型について学んでいた, そしてCLIでTypeScriptのコードを実行する方法についての備忘録

業務でTypeScriptを書いている訳ですが, 「ぜんぜんわからない, 俺は雰囲気でTypeScriptをやっている」という感じなので, まずは型について理解を深めようと思って, Qiitaの次の記事を読んでいました:

qiita.com

日頃, Perlというゆるふわな言語を主に使っているので, 型についての考え方とかスッと入ってこなくて, やっぱり難しいですね〜!!! という気持ちになっていました. とはいえ, これまで雰囲気で書いていた部分について, 「ナルホドそういう意味だったのか...」みたいな発見があって学びがありました.

引き続き以下の記事を読もうかと考えています:

qiita.com

qiita.com

「これも読んでおくといいぞ!」というテキストがあれば是非教えて下さい!!!!

CLIでTypeScriptのコードを実行する方法

ある言語の仕様について学習するとき, 実際に動作する環境を作って, 適当なコードを書いて動かして試行錯誤する... というのは良い方法だと思っています.

というわけで今回は, CLIでTypeScriptのコードをシュッと実行する環境を作って, 実際にTypeScriptのコードを実行しながらテキストを読んでいくことにしました.

qiita.com

今回は上記のエントリを参考にして, ts-node というライブラリを使うことにしました.

$ npm install -g typescript ts-node

とすると, ts-node というコマンドが使えるようになり,

$ ts-node /path/to/script.ts

みたいな感じでTypeScriptのコードが実行出来るようになります. 型なども考慮されるので, こういった学習用のサンプルコードをシュッと実行するにはとても有用でした.

...っていうかよく見たら普通に社の同僚の書いたエントリでした. こういう時無意識に同僚のエントリが出てくると「オッ!」となりますね. サンキューです!!!

2019年の振り返り

あけましておめでとうございます, 2020年になりましたね. 去年, 遂に30歳になってしまったので, 今年からは年間通してフルに(?)30代独身男性として過ごしていくことになりました. 引き続き今年もよろしくおねがいします. というわけで今年もKPTでやっていきましょう.

過去の振り返り達

papix.hatenablog.com

papix.hatenablog.com

papix.hatenablog.com

papix.hatenablog.com

papix.hatenablog.com

K

「2019年にやってみてよかったこと, 2020年も継続して取り組みたいこと」

読書習慣が定着しつつある

papix.hatenablog.com

去年, Advent Calendarのネタとして書いたのですが, 2019年は読書習慣がだいぶ定着してきた1年だったと思います. 特に夏頃はかなり順調で, これまで積ん読していた本をどんどん消化出来たのですが, 夏〜秋にかけて体調を崩してしまった結果, 一旦停滞したりしていました. とはいえ年末から年始にかけてリブートしているところで, 最近は徐々に読書量が回復してきました.

良質なOutput(ブログエントリ, 登壇など)には, 良質なInputが欠かせないと感じているので, 読書習慣を定着させて, 積ん読している本を消化していくというポイントについては, 2020年もしっかり取り組んでいきたいと思います.

海外のカンファレンスで登壇できた

papix.hatenablog.com

夏にPerlCon 2019に参加してきました. 2015年にYAPC::EUに参加して以来4年ぶりの参加になりました. 「Perl in Japan」というタイトルで発表も出来ましたし, 何より英語コミュニケーションに勇猛果敢に(?)取り組めたというのが良い体験になったと思っています.

4年前は, とにかく英語コミュニケーションについて恐怖感というか, 「伝わらなかったらどうしよう...」という気持ちがあって, 結果として言葉が出てこない, 聞き返せない... みたいな悪循環に陥ってしまっていたように思います. 今回は, とりあえず思っている事を(雑な英語ではあるが)口に出してみること, そしてわからなかったら素直に「すいません, もう1回言ってもらえますか...?」と伝えることが出来たように思います.

最近, Google翻訳の進化が著しいので, 割と近い段階で「英語の知識が不要になる(= Google等がよしなにやってくれる)」時代が来るのでは...? という気がしますが, 趣味(= 旅行)と実益(= 英語の文章読んだりとか)の両方に役立つので, 最近英語のトレーニング(といっても文法の本読んだり, 見かけた英語の文書を試しに読んでわからない単語を調べてみたり, 程度ですが...)に取り組んでいます. 2020年も, これについてはちまちまと継続できれば良いかなと思っています(あとは2020年もPerl and Raku Conference in Amsterdamに参加する予定です. ついでに人生初のヨーロッパ1人旅なども敢行する予定...).

いろいろとOSSに貢献出来た

2019年はClass::Accessor::Typedをリリースしたり, Devel::KYTProfやAWS::XRayなどのCPANモジュールにPull Requestを送ることができました. 「こういうのあると面白そう」とか, 「これ今必要だな...」というきっかけで, いろいろアクション出来たのではないかと思います. Class::Accessor::Typedについては2020年も引き続き手を入れていきたいですし, Pull Requestについてもちまちまと送っていけるといいなと思っています.

P

「2019年で良くなかったところ, 2020年に改善していきたいところ」

特に業務の領域で, 余りチャレンジ出来なかった

前述の「K」で挙げた, 読書習慣や海外のカンファレンス登壇などは, どれもある種のチャレンジであると言えると思います. 一方で, 業務の領域においては余り新しい取り組みが出来なかった... というのが2019年の正直な感想です.

業務において, 視野が狭くなっていたというか, 「とにかく来たものを受け流す」というポイントに重点を置きすぎていたような気がしており, それはそれで大事(目の前にあるタスクを片付ける)とは思うのですが, とはいえ中長期的な視点でアクションしていかないと, プロダクトの成長にも貢献出来ないですし, やはり自分自身のスキルセットも伸びていかないなあ... と改めて感じました.

体調も精神状態も波があった

体調については夏〜秋にかけて, 何度か風邪を引いてしまい, 結果として数日休んでしまったことがありました. また秋〜冬にかけては, 考える事が増えてしまった結果, 精神的に辛い状況に陥った出来事がありました. 「ちょっと大変です」とヘルプを挙げることが出来たのは良かったですが, とはいえ本来はうまく乗り切りたかったですね...

前述のように, 「考える事が増えてしまった」ということがうまく乗り切れなかった理由の1つあると思うので, そこについてはうまく「考える」ということを委譲するアクションをしていく必要があったと思いました. 年齢を重ねるにつれて, 視野や権限などが広がっていくと, 取れるボール(やれること, 考えられること)が増えていって, 一方で自分自身でボールを持てる量(範囲)については限界があるので, うまく取捨選択する必要があると痛感しました. 30代を迎えた今, ボールを持つ/持たないの精度向上はどんどん必要になっていくと思ったので, 2020年は試行錯誤したいと思いました.

T

「2020年, 改めてチャレンジしていきたいところ」

やっていく: アクションの質と量を高める

引き続き, 2020年もやっていきたいと思います. まだ停滞する歳ではない. 仮にエンジニアとしての定年が35歳だったとしてもまだ4.5年くらいはあるので, 足掻きつつやっていきたいですね.

その中で, やっぱりこれまで「チャレンジ」, 「挑戦」, 「アクション」という言葉を便利に使いすぎていた... というのは反省点として挙げられると思います. 「チャレンジするぞ!」, 「挑戦するぞ!」, 「アクションしていくぞ!」と言っていると, 確かにやっている感は出ますが, とはいえ言うは「言うは易く行うは難し」で, もう少し計画的に? 具体的に? やっていく必要があると思いました.

とりあえず, 2020年について, しばらくは次のような方針でやっていきたいと思います:

  • 業務: アクションの量を増やす
  • 業務外: アクションの質を高める

業務においては, とにかくアクションの量を増やしていくのが先決と思いました. これまでのように, 来たタスクをうまく捌くだけでなく, その中で新しい取り組みを取り入れたり, 或いは中長期的視点で次に繋がるアクションを織り込んでいく... といった事が出来るとよいですね.

一方, 業務外については, 読書習慣や海外のカンファレンス登壇(英語力向上)といった, 2019年に取り組むことが出来たアクションについて, 更に質を高めていくことを目指したいです. 2020年も引き続きいろいろな本を読んでInputを捗らせたい(読書感想エントリもどんどん書いていきたい)ですし, 英語力の向上についてもこれまでのアクションを継続しつつ, 新しい取り組みもやっていきたいと思います.

...まあなんというか, この辺り, まだまだ全然噛み砕ききれていないと思うので, 数ヶ月のスパンで振り返ったり, 方針を立て直したり出来ると良さそうです. こういった取り組みについても2020年新たに取り組んでいきたいと思いました.

まとめ

2019年は... なんというか, 平凡な1年にしてしまったという気がします. プラスな出来事もマイナスな出来事もあって, トータルでは0でした, みたいな感想があります.

人間, 急にシュッと大きく変わる事は出来ないと思っており, 小さい取り組みを積み重ねて, それを継続してやっと変化の兆しが見える... みたいな所があると思っています. ので, 去年のことは去年のこととして, 今年は気持ちを切り替えて, また少しずついろいろなものを業務内/業務外の両軸でしっかり積み重ねていきたいと思います. 2020年もご指導ご鞭撻の程よろしくお願いいたします.

Syntax::Keyword::TryとPerlのキーワードプラグイン (その2)

id:papix です. この記事は, Perl Advent Calendar 2019の24日目の記事です. 昨日はmp0liiuさんの「Perlのスタックトレースを見やすく扱う方法」でした.

qiita.com

Syntax::Keyword::Try

さて, Perl Advent Calendar 2019の2日目に, Syntax::Keyword::Tryの紹介をしました.

papix.hatenablog.com

そしてその最後に, このような予告をしていました.

「キーワードプラグインを使ったモジュールの実装について」をご紹介させてもらえればと思います!!!!!!

...が, 当初予定していた16日では準備が間に合わず, 他の話題でお茶を濁したりしました.

papix.hatenablog.com

このエントリでは, 今度こそSyntax::Keyword::Tryを題材に, キーワードプラグインの実装について触れていきたいと思います. ...が, 後述しますが, この記事単体では到底説明を終われそうにありません!!!! 今後, 数記事に分けて紹介していきますのでその点ご了承ください...

諸注意

  • papixのXS力はゴミです
  • 以下の記述は, 実際のコードやPerlの各種ドキュメントを読みながら, 推測(自信がない状態)で書いています
  • この記事で紹介しているSyntax::Keyword::Tryの実装やXSの知識が正しい保証は出来ません

Syntax::Keyword::Tryのソースコード

さて, いよいよSyntax::Keyword::Tryを通じて, Perlのキーワードプラグインについて, その実装について触れていきましょう. 今回は, 現時点での最新版である0.11のソースコードを題材にします.

metacpan.org

さあ, まずはlib/Syntax/Keyword/Try.pm を見ていきましょう.

...import, import_intoという, パッケージをuseするときに使われる関数を除けば, このファイルで実行している処理はたったこれだけです:

require XSLoader;
XSLoader::load( __PACKAGE__, $VERSION );

XSLoader. というわけで, ここからはXSの世界へと突入していきます.

XSとは?

そもそもXSとは何か. XSは, PerlとC言語を紐付けるための言語... という表現が一番わかり易いのではないかと思います. C言語で書かれたプログラムをPerlの世界から呼ぶためには, XSという言語で紐付けてあげる必要がある, という感じです.

日本語の資料で言えば, 下記の「CによるPerl拡張入門(α)」が有用です.

xsubtut.github.io

Try.xsを読み解く

というわけで, Syntax::Keyword::TryのコアにあたるXSで記述されたlib/Syntax/Keyword/Try.xsを見ていきましょう.

...そもそも, XSの世界でキーワードプラグインを有効にするにはどうすればいいのでしょうか? いろいろ調べていくと, perlapiの「Global Variables」の節に, 次のような記載があります.

PL_keyword_plugin NOTE: this function is experimental and may change or be removed without notice.

これっぽいですね. PL_keyword_pluginというグローバル変数は, キーワードプラグインを扱う関数を指す関数ポインタとのこと. つまりここに適当な関数ポインタ(キーワードプラグイン用の)をセットすると, Perlはそれを使ってよしなにキーワードプラグインを有効にしてくれそうです. そして, ここで指す関数は, 以下のように宣言されている必要があると書かれています.

 int keyword_plugin_function(pTHX_
        char *keyword_ptr, STRLEN keyword_len,
        OP **op_ptr)

これをもとに, Try.xsを見ていくと, まず static void S_wrap_keyword_plugin(pTHX_ Perl_keyword_plugin_t func, Perl_keyword_plugin_t *var) という関数の中でグローバル変数 PL_keyword_plugin に対し, 引数 func を代入していることがわかります.

更にこれは, define wrap_keyword_plugin(func, var) S_wrap_keyword_plugin(aTHX_ func, var) というマクロが定義されていて, wrap_keyword_plugin は Try.xs の末尾に, 次のような形で呼び出されています.

BOOT:
    (中略)
wrap_keyword_plugin(&my_keyword_plugin, &next_keyword_plugin);

このコードは, BOOT: から始まるBOOTキーワードの中にあります. BOOT以下に書かれたコードは, このXSを使ったモジュールを実行する際, 最初に実行されるブートストラップのコードです.

さて. ここで &my_keyword_plugin は関数 static int my_keyword_plugin(pTHX_ char *kw, STRLEN kwlen, OP **op) のアドレス(これは, 先に紹介した PL_keyword_plugin に代入可能な形で宣言されています), そして &next_keyword_plugin は定数 next_keyword_plugin, つまり static int (*next_keyword_plugin)(pTHX_ char *, STRLEN, OP **); のアドレスになります. これを踏まえて, 改めて関数 S_wrap_keyword_plugin (マクロである wrap_keyword_plugin を展開した先)を見てみましょう.

/* papix注釈  
 * func = &my_keyword_plugin, *var = &next_keyword_plugin
 */ 
static void S_wrap_keyword_plugin(pTHX_ Perl_keyword_plugin_t func, Perl_keyword_plugin_t *var)
{
  /* BOOT can potentially race with other threads (RT123547) */
 
  /* Perl doesn't really provide us a nice mutex for doing this so this is the
   * best we can find. See also
   *   https://rt.perl.org/Public/Bug/Display.html?id=132413
   */
  if(*var)
    return;
 
  OP_CHECK_MUTEX_LOCK;
  if(!*var) {
    *var = PL_keyword_plugin;
    PL_keyword_plugin = func;
  }
 
  OP_CHECK_MUTEX_UNLOCK;
}

重要なのは以下のコードです.

  if(!*var) {
    *var = PL_keyword_plugin;
    PL_keyword_plugin = func;
  }

つまり, 既にグローバル変数 PL_keyword_plugin にあるキーワードプラグイン用の関数を, *var すなわち定数 next_keyword_plugin に退避して, 改めて PL_keyword_pluginfunc, すなわちSyntax::Keyword::Tryを提供するための関数, my_keyword_plugin をセットしている訳です. PL_keyword_plugin がグローバル変数なら, キーワードプラグインを読み込むために上書きされていくはずで, どうやって複数のキーワードプラグインを実現するのだろう...? と思っていましたが, こういう実装になっている... のだと思います. 多分.

そして改めて関数 my_keyword_plugin を見てみると,

static int my_keyword_plugin(pTHX_ char *kw, STRLEN kwlen, OP **op)
{
  HV *hints;
  if(PL_parser && PL_parser->error_count)
    return (*next_keyword_plugin)(aTHX_ kw, kwlen, op);
 
  if(!(hints = GvHV(PL_hintgv)))
    return (*next_keyword_plugin)(aTHX_ kw, kwlen, op);
 
  if(kwlen == 3 && strEQ(kw, "try") &&
      hv_fetchs(hints, "Syntax::Keyword::Try/try", 0))
    return try_keyword(aTHX_ op);
 
  return (*next_keyword_plugin)(aTHX_ kw, kwlen, op);
}

...となっています. Syntax::Keyword::Tryのためのコードは, ここから改めてtry_keywordという関数を呼び出して実行しており, エラーが発生している場合や, Syntax::Keyword::Tryのコードが無事処理に成功した時は, (*next_keyword_plugin)(aTHX_ kw, kwlen, op); として, 先程退避した(別の)キーワードプラグインを実行する... という構成になっているようです.

今回のまとめ

XS, 本当に難しいですね... 一応大学時代, 修士論文はXSのモジュールを書いて卒業したのですが, その時の知見もほぼ失われ, 改めてイチから咀嚼しながらこの記事を書きました. かなり憶測というか, 「実際のコードやperldocの記載を見るとこうではないか...?」と, 自信のないまま書いているので, 間違いなどは多々あるかもしれません. その時は, Twitterやコメントなどで教えて頂けると幸いです.

XS, そしてキーワードプラグインは興味深い内容なので, これからも少しずつ読み解いていきたいと思います. 次は, 実際にSyntax::Keyword::Tryのための処理が書かれている... であろう, try_keyword についてコードを読んでいこうと思います.

明日のPerl Advent Calendar 2019の担当は sy250f さんです. 宜しくおねがいします.