モチベーションを管理する

ここ最近仕事が落ち着いてすごく時間ができた。それ自体はいいことなのだが。
悪いことにすごくやる気が起きない。
途中まで読み進めていた本や、塩漬けしていた個人プロジェクトなどやるべきことはあるのだが一日のほぼすべてを睡眠に費やしてしまった。

ダメだなーとなんとなく思いながらも相も変わらず体は惰眠を貪っている。
なぜモチベーションが起こらないのか、どう行動したらいいのかというところをぼんやりと考えた。

まず何もやる気が起こらない、と言うのは言い換えると何も体験することがない状態とほぼ等しいと思う。
自分が富を得たり成長したりすることがない反面、失敗してリスクを負ったり気分が落ち込むこともない。
つまり何も変化のない平衡状態だといえる。

ではなぜ何も変化のない状態に身をおきたがるのかというと、単純に体験を積む行為自体がエネルギーを消費するからである。
いわゆる面倒くさい。ということである。

もうちょっと掘り下げると面倒くさいと思う理由がさらに一つあることに気がついた。
そもそもリターンを欲していない場合、リターンがほしいがそのリターンが得られないと思っている場合、または頭ではリターンが得られそうだと思っていてもその実体験を積んでいない(リターンを得られるという確信がない)場合には特に面倒くさいと感じる。
ようするに面倒くさいというのは行動コスト対リターンのパフォーマンスが悪いと思っている行為とも言いかえられる。

例えば仕事の依頼が来てそれに対応することを考えてみよう。
これは自分の中でこの行為を行った実績がある。その為行動コストは少ない。
また行為の対価としてお金を得られることが見込める。
その為リターンも得られるため、モチベーションは悪くなさそうだ。

じゃあコンビニにご飯を買いに行くという行為はどうだろう。
これも自分の中で行為を行った実績があるため行動コストは少ない。
またそもそも腹が減っているという原始的な欲求を満たすことができるためリターンを得られる。

また更に行動コストというものを分解して考えてみる。
行動が完了したとみなすのは、いわゆる目的が達成できたという点である。成功するとも言える。
対して目的を達成できなかった場合を失敗と定義しよう。

この時に今までに体験したことのない新しい目的地に達する場合は、当然そう安々とは行かないだろう。
こうすればうまくいくだろうという計画を練って実施する際には何度か計画通りに行かないこともある。
そのたびに計画を細かく修正しながら進める必要があり、成功(目的を達成する)ためには非常に労力を要する(だろうということを今までの人生で学習している)
対して失敗するのは簡単である。そもそも何もしなければいいし、計画がうまく行かなかった時点で諦めてもいい。
成功を得るためには全ての工程をこなさないといけないのに対して、失敗するのはいつでもできる。

対して一度成功した体験を再度実施するのは極めて簡単である。
どういうリスクが有りどうすればそれを回避できるかなどをすでに知っているからである。

で、話を戻してなぜ新しい行動する意欲が起きないかというとコスパが悪いと思いこんでいる点にあると解釈した。
成功して初めてリターンが得られる。失敗したことにより得られるものはないと思っている。

というわけで考え方を変えることにした。

まず失敗の定義であるが、細かい点でうまく行かなかったとき(仮にこれを細かい失敗とでも呼ぼう)。これは失敗とは呼ばない。
目的を達成することを諦めた時点で初めて失敗と言える。

逆に細かい失敗は、成功とも解釈することができる。
なんでかというと、「目的に対してこういう計画で試してみたがうまく行かなかった」というリターンを得られたと解釈できるから。
最終的な成功に向けて計画を修正すれば良い。

人間はDNAレベルでじっとはしていられない。
日々成長できる何かがあればそれは十分に価値があるリターンと言って良い。

新しいことをやる際には、細かい成功体験を積み重ねていくしかない。
むしろ新しいことをやる際の細かい失敗に対応する体験が一番のリターンだ。

同じところぐるぐる回っているだけじゃ面白くないでしょう。
同じことを繰り返し続けているのはそれこそリスクだ。


makefileおさらい

概要

linuxシステムのカーネル触る機会があるんだかないんだかで、改めてmakefileについておさらい。
今回はほとんど自分のメモみたいなものです。

makefileファイル

今回取り上げるのは

PREFIX = /usr/local
DEST_HEADER = $(PREFIX)/include/

TARGET = librpi_gpio.a
SRCS = rpi_gpiolib.c
OBJS = $(subst .c,.o,$(SRCS))
HEADERS = rpi_gpiolib.h rpi_gpio.h

RM := rm
CC := gcc
AR := ar

CPPFLAGS = -g -fPIC -O2 -l./
LDFLAGS = -g -fPIC
ARFLAGS = cr

$(TARGET): $(OBJS)
	$(AR) $(ARFLAGS) $@ $^ $(LOADLIBES)

install: $(TARGET) $(HEADERS)
	mkdir -p $(PREFIX)/lib/
	install -m644 $(TARGET) $(PREFIX)/lib/$(TARGET)
	mkdir -p $(DEST_HEADER)
	install -m644 $(HEADERS) $(DEST_HEADER)

.PHONY: clean

clean:
	$(RM) $(OBJS) $(TARGET)

出典は下記の書籍を読み進めていて出てきました。話はそれますが低レイヤの知識を得る際にオススメです。興味のある方は是非どうぞ。

さて私はそんなにmakefileをガッツリ触ったことがあるわけではないので、分からない点をひとつひとつ掘り下げていきます。

subst関数

まずここsubst関数について

SRCS = rpi_gpiolib.c
OBJS = $(subst .c,.o,$(SRCS))

Makefileで使えるユーザ関数であり、substは3つの引数を受け取ります。
c言語ライクにかくならば subst(from, to, text); のようなイメージになります。

この関数は text 文字列を対象として from を to に置換します。
したがって上記のMakefileの中で言うと “.c” という文字列を “.o” という文字列に置換することになります。
最終的に OBJS変数には rpi_gpiolib.o という文字列が格納されることになります。
文字通りコンパイル時のオブジェクトファイルの文字列を格納しているようです。

ビルド

AR := ar
ARFLAGS = cr

$(TARGET): $(OBJS)
	$(AR) $(ARFLAGS) $@ $^ $(LOADLIBES)

まずは細かいメタ変数の部分から確認すると
$@ はターゲット名なので librpi_gpio.a
$^ は全依存関係のリストなので rpi_gpiolib.c
を指すことになります。

その後いきなり arコマンドが展開されているので、.oを生成するルールが無いように見えるのですが
makefileにはデフォルトルールがありそこに .oターゲットが定義されており .cを依存ファイルとしてコンパイルするルールが存在します。
このあたりは make -p で確認できるようです。

下記のようなルールを確認しました。

make -p
...
%.o: %.c
#  commands to execute (built-in):
        $(COMPILE.c) $(OUTPUT_OPTION) $<
...

$(LOADLIBES)に関しては定義されていないようなので、この場合は特に意味を成さないですが、通常はリンクするライブラリのパスを入れます。

さて最後に ar コマンドに関してですが、アーカイブを作成します。
現在ではもっぱらライブラリの作成時にのみ使用されるコマンドで、複数オブジェクトをまとめてライブラリを作成する際の典型的なパターンです。
これによって複数の .oファイル(この例に関しては1角ファイルですが)から .aファイルを作成します。

インストール

install: $(TARGET) $(HEADERS)
	mkdir -p $(PREFIX)/lib/
	install -m644 $(TARGET) $(PREFIX)/lib/$(TARGET)
	mkdir -p $(DEST_HEADER)
	install -m644 $(HEADERS) $(DEST_HEADER)

installコマンドにより作成したライブラリファイルを適切な場所にコピーします。
cpコマンドと何が違うのかというと、コピーと同時に属性を指定することができます。
こちらは特に難しいことはないですね。

以上となります。
はじめはよくわからなかったですが分解して見たらかなりしっかりした構造であることがわかりました。
また調べていてこちらのページを見つけたのですが、リンカ/ローダの仕組みを歴史的な側面からも見つつ体系的に非常によくまとめられていたのでオススメです。

参考ページ

http://qiita.com/chibi929/items/b8c5f36434d5d3fbfa4a
http://0xcc.net/blog/archives/000107.html
http://linuxjf.osdn.jp/JFdocs/Program-Library-HOWTO/shared-libraries.html