Masteries

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

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 さんです. 宜しくおねがいします.

最近の読書法

この記事は, 「はてなエンジニア Advent Calendar 2019」の21日目の記事です.

qiita.com

昨日は id:dekokun さんの「Kinesis Data Streams + Lambdaが詰まった時の対処法」でした.

dekotech.dekokun.info

最近の読書法

「読書習慣が定着しないな...」という課題を延々と持ち続けていて, 積読本も無限に溜まっていたのですが, 最近徐々に消化が進んできました. うまくサイクルが回り始めた理由を考えていて, 幾つか気付いたことを書き残しておこうと思います. 結論としては, 本を読むにあたって現在は以下の3点に気をつけています:

  • 少しでもいいので読む
  • 理解できなくてもひとまず読む
  • とはいえ, グッと来なかったら読み飛ばす

少しでもいいので読む

既に読書の習慣が定着しているならともかく, そうでないのなら, まずは「定期的に本を読む」ようになるのが大事だと思いました.

読書の習慣がなかった頃は, 面白そうな本をとりあえず買うものの, 読書の習慣が定着していないので当然のように積まれていって, だからこそ気持ちが高まってきた時に「消化するぞ! たくさん読むぞ!!!」と思うものの, その気持が逆に読書のハードルを自分で高めてしまい(折角読むのだからたくさん読もう, 折角読むのだから理解しよう, 等...), 結果として挫折する... といった悪循環を, 延々と繰り返してしまっていました.

この辺りは, 今年「小さな習慣」を読んだ影響があって, 毎日少しずつでもいいので, なるべくコンスタントに読書をしていく... という習慣を試みていて, それが徐々に定着してきているように感じます. とにかく, 本を読むハードルを意図的に, どんどん下げていっています.

papix.hatenablog.com

直近だと,

  • Kindleで, 1日2ページは読むようにする
  • 飲みすぎたり疲れた日は休んでも良い, が翌日は2倍読む(2倍と言っても4ページ)

...という感じでやっています. Kindleで2ページ程度であれば, どう転んでも10分もあれば読み切れるので, 出勤時間にサクッと読んでしまえますし, 仕事で多少疲れた時でも寝る前にベッドの中でなんとか読了できる量だと思います(そして, 本当に疲れている時は前述のように諦めてもよく, 代わりに翌日2倍読む).

これの良い所は, 「とりあえず2ページで...」という気持ちで本を読み始めると, 時と場合によってはだんだん面白くなってきて, 結果として2ページ以上読み進めている... ということが結構ある点です. 読書に対するハードルを, 極限まで下げているはずなのに, 結果としては気合いを入れて本を呼んでいた時よりもたくさんの分量を, コンスタントに読み進めることができるようになったと思います.

理解できなくてもひとまず読み進める

読書の習慣が定着しない頃, 何かのきっかけで本を読むか! となった時, 先にも述べたように, 「せっかく読むのだから, 全部理解しよう...!」と意気込みすぎた事が多かったように思います. 結果としてページは進まず, 「うーん, うーん...」と悩んでいるうちに時間が過ぎ去ってしまい, 更にそのせいか「また続きを読もう!」という気持ちになれない... という, 悪循環を起こしていました.

これもまた, 読書のハードルを下げる観点の1つではあるのですが, まずはとりあえず「どんな事が書かれているかわかればいいや」という気持ちで本と向き合うようにしています. サクサク読んでいって, 興味深いと思ったところだけしっかり読む, という雰囲気です. 気持ちとしては, 「じっくり読もうとして進まないより, とりあえず1冊読み切った方がまだ有益」と思うことにしています.

...とはいえ, そういう読み方をしていても, 1冊あたり(分量によりますが)どれだけ少なくても2〜3ポイントくらいは学びというか, 新しい視点が得られるものだなあと思っています. また, 何より「この本には, こういう事が書いてある」というインデックスを作ることが出来るのが有益で, まずはそこを目指す程度で十分ではないか, と思うようにしています. そうすれば, ある意味で本を「外部記憶」にできる訳で, いつか将来, 「これ, あの本に書いてあったな...!」というタイミングがあれば, また本を開いて, 今度は必要なところを理解出来るまで読み込む... という使い方が出来るはずです.

課題としては, 本のジャンルによってはこういう読み方が明らかに不向きなことがある(例えばプログラミング言語の解説/入門書などはそういうジャンルと思います)というところで, そこについては今後の課題としたいと思います.

とはいえ, グッと来なかったら読み飛ばす

先に, 「理解できなくてもひとまず読み進める」と書きましたが, とはいえ読んでいて「グッと来ない」と思った所は, 思い切って読み飛ばすようにしています. 「せっかく読書するのだし, 全部読むようにしよう!」と思っていた時期もあったのですが, そのような理由で無理やり文言と向き合っても頭に入ってきませんし, そういう状態で本を読んでも得るものはほとんどない... という結論に至りました.

なので, 最近は「この辺りはあまりグッと来ないな...」と思ったら, 各節のタイトル等をサッと眺めて読み飛ばすようにしています. 「各節のタイトルをさっと眺めておく」というのは大事だと思っていて, 先に「本のインデックスを作って外部記憶にする」という話をしましたが, そのためにもそれくらいは読んでおく必要があると思っています.

まとめ

とにかく, まず本を読む習慣を定着させたい! と思うのであれば, ただひたすらに「本を読むハードルを下げる」必要があると思っています. ここで紹介した3つのポイントは, それを実現するために自分が実施していることです.

かつての自分は, 「本をたくさん読み, そして多くのことを理解したい」と思っていました. しかし, 二兎を追う者は一兎をも得ず, という諺があるように, (少なくとも自分には)その2つをシュッと両立することはできませんでした...

なので, 最近はこうした施策によって本を読むハードルを下げ, 読書習慣を定着させ, その次のフェイズとして, 読解力や本から得るものを増やしていく... という取り組む方が良さそうという結論に至っています. 皆さんはどのようにして「本」と向き合っていますか? この機会に言語化してみると得るものが多いかもしれません.

明日の担当は id:side_tana さんです. 宜しくおねがいします.