Posts Tagged ‘book’

「脳に悪い7つの習慣」新書なのに長く効きそう!

水曜日, 12月 30th, 2009


この本を父からもらった。仕事への取り組み方や思考力を伸ばしたいと考えていた折に読んだので1章、3章、4章が参考になった。新書であるにも関わらず長く効きそうな内容なので、ブログに整理して我が身に知識を染み込ませることにした。

1章は、脳が情報を処理する仕組みについて解説があった。
処理の流れとしては、以下のようになる。

  1. A10神経系が情報を好きか嫌いか判断する
  2. 情報が前頭前野に送られ、理解する
  3. その情報が”自分ごと”ならば自己報酬系という通路に送られ、思考に入る
  4. 思考の結果を海馬系で記憶し、いつでも利用できるようにする

この流れの上で重要なのは、まず情報の好き嫌いの判断から、情報処理が始まるということ。情報を取り入れて思考まで持っていくためには、情報を嫌わずに、取り入れる姿勢が必要になる。その上で、主体性を持って(要するに興味を持って)情報に接することで、より高い思考に持ち込める。

脳の情報処理の仕組みに触れた上で、脳の特性(3つの本能と2つの癖)を踏まえる。脳には「生きたい」「知りたい」「仲間を作りたい」という本能がある。これらの本能を磨くことが、脳の活性化や高度な処理を可能にする。
その本能に加えて「自己保存」「統一性一貫性」という2つの癖がある。これらは生活に必要だが、うまく使わないと人生を制約する。「自己保存」は自分の今の状態を変えないでおこうとする癖だ。例えば、隠蔽工作をしていた社長がさらに嘘を上塗りするのは、社長という肩書きを捨てないための自己保存の行動と言える。「統一性一貫性」は、自分の意見に統一性があるように振舞う癖だ。この本能と癖をうまく扱い、種々の能力を高める方法を2章以降で書いている。

3章は特に、よりよく思考するための脳の使い方について書かれている。よりよく思考するには、自己報酬系をうまく働かせることが重要だ。自己報酬系をうまく働かせるコツは「目的と目標を明確にし」「ゴールを意識せず」「主体的に、自分がやってやるという意思をもって」「達成のしかたにこだわる」「目標の達成に向けて一気に駆け上がる」こと。

目的(抽象的、大きい)と目標(具体的、小さい)を明確にするのは、具体的な目標が設定されないと、自己報酬系がきちんと働かないかららしい。

ゴールを意識しない理由は、ゴールが見えてしまうとその直前で「もうだいたい出来たかな」と思ってしまうからだ。「だいたい出来た」と思ってしまうと、その時点で脳には報酬が支払われるため、それ以降の活動能力が落ちる。「達成の仕方にこだわる」というのも同様の理由だ。

主体的にやるのは、自己報酬系が自分がやってやる、という意思に大きく関わっているから。それは、情報に興味を持つという主体性がないと、自己報酬系に至る以前の情報の好き嫌いや理解を行う際に、情報がブロックされてしまうからだ。

コツコツやらず「目的の達成に向けて一気に駆け上がる」のは、コツコツやるというのに「失敗したくない」という自己保存の癖が働いており、脳の活動に制約をきたすかららしい。一気に駆け上がることで、脳はその目標に全力投球できる。

4章はまだまとめられていないので、後日。ただ、読書は1度読んだだけでは役に立たない、という点は非常に頭に残っている。なんども繰り返し読むことで、頭に入り、実際に役に立つ知識となる。ちょうどこの本を読んでいたときに、大学院の先生から「そいつに実力があるかを調べたかったら、ホワイトボードとペンだけ持たせて、理論の説明をさせてみればいい。丸腰の状態でどれだけ頭にあるかが実力だ」という話を聞いていた。これらには、本当に役に立つ知識は、本のインデックスを覚えて、いつでも情報を引き出せるようにしておくことではなく、頭に(というかもはや体に?)染み込ませているものだ、という点で共通するものを感じた。これまで、情報に飢えるように本を読んでいたので、読み方を本当に良い一冊を染み込むまで読むようにしたい。もちろん、これまで同様、良い本かどうかをザッピングすることはやめないが。

西村佳哲さんの「自分をいかして生きる」が良い。

火曜日, 12月 22nd, 2009

読了。

前刊である「自分の仕事をつくる」を読んでから、自分のなかで仕事の定義が変わった。仕事とはかくあるべしといった押し付ける論調ではなく、問いかけや思考の切れ端がたくさん横たわっている。その切れ端の続きを、自然と考えてしまうような作りだ。その時、自分の仕事に対する考え方を見つめ直すことになる。単なるハウツー本や、xx術のような小手先の術の話は一切出てこない。エッセイのようであり、思想書のようでもあり、雑誌のようでもある。

読み進めていると、まるで親しい友人からの手紙を読んでいるような気分になる。もし今自分を活かした仕事をしていると思っていないなら、一度友人から届いた手紙だと思って手にとってみて欲しい。

「アイデア会議」読書ログ

日曜日, 10月 25th, 2009

アイデア会議という本を読んだ.

企画の根幹は,その企画の中心にあるアイデアにかかっている.そのため,企画の体裁や資料を整える前に,企画の元となるアイデアについての会議をしっかりとやろう!と提案し,そのアイデア会議の方法論を述べている.

複数の方法論が述べられているが,その他のブレスト系の本にも書かれている.特に僕が注目した方法として,会議をやる前の段階から紙にアイデアを用意しておくこと.いくつかアイデアがある上で会議が始まるとさらにアイデアが出やすくなる上に,他のtips(発言者と発言を切り離す)を会議開始時点から実現できるためだ.

大まかなところは,その他のアイデア発想法の本に書かれているのと同じ.特に僕が参考になったのは,以下.

  1. アイデアを発言者と切り離す(そのために全員の視線を同じ方向へ)
  2. プランナーはアイデアを紙に書いて持ち寄る(時間短縮のため)
  3. 「新しい」と「効果がある」は違う

プランナー側とディレクター側の各々の視点から,アイデア会議で注意すべき点が書かれているのも利用しやすいと思われる.

「おとなの小論文教室。」読書ログ

土曜日, 7月 25th, 2009

この本を手に取った理由

山田ズーニーが気になっていた

僕は,年明けから取り組んでいた就職活動の中で,姉から山田ズーニーさんの「おとなの進路教室。」というpodcastが参考になる,と勧められ,それを聞きながら就職活動に望んでいた.(おとなの進路教室。は,寿退社した人が復職した人や,会社をやめて起業した人が,山田ズーニーと対談する形のpodcastである.新卒のシュウカツの時に,会社に入ったあと,人は仕事に対してどう考えるかを知れたのは,会社を選ぶ時にとても参考になった)
彼女の発信する情報は,同じ部活の先輩からは聞けない帰宅部の先輩の意見という感じで,視点が斬新だけど的を得ていて,僕はとても面白いと感じていた.そのため,彼女の他の著作を手にとり,面白さの秘訣を知りたいと思った.特に,なぜ彼女はあのように的を得た表現ができるのかについて.そこで,表現することについての著作「おとなの小論文教室.」を手に取った.

表現について考えるところあり

「貧乏はお金持ち」にも書かれていた,今後自分の生活を自分で支えていく必要がある.会社に依存せずに自分の生活を支えるために,自分の価値を高めていく努力が重要だ.自分の価値を高める手段の一つとして,価値ある情報を発信する人として知られることがある.僕はブログという発信する場はあるのに,全然発信してない.価値ある情報のみ発信しようと思っていたが,価値ある情報を発信したいときには表現力がない.表現力を鍛えるためにも,毎日の生活を綴ってみようと考えた.

表現する対象として毎日の生活を選んだ理由は,先週の連休からずっと,僕はだらだらとした毎日を過ごしていたことに起因する.その日々では,まったく自分の望む毎日を過ごせていないと感じていながら,打開策を考えることがなかった.そのうちに,以前読んだ本「禅と内観」に,内観を終えた人は一日の終わりに,今日一日主人公たり得たか,を点検するというのを思い出した.そこで,毎日の生活を振り返る機会を,どうにかして設けようと思い,上の理由とあわせて毎日ブログに日々の生活を残すことにした.

得られたもの

そもそも,僕が何かを表現するっていうことは,僕は誰か,どんな考えを持ってるかということを他者に伝える作業だ.そのために,まず自分の立ち位置(何を得たいか,どこへいきたいか)をはっきりさせることが,表現することの原点にあり,その原点を考えることから本はスタートする.

自分のやりたいことは何か.それが考えられない場合,どうやって考えられるようにするか.(考えるきっかけになる小さな問いをいくつも作る),物事を,権威や見栄に歪まされず,自分の目でありのままに見えているか(ありのままに見えていないとだんだんと自分の感覚が狂ってくる).自分の伝えたいコアは何か(要約することでコアを見つける),伝わらない場合はどういう場合か,どうすればよいか(自分の発信したいことを自分の視点からではなく,他者と自分を含めた全体の関係性から見る),物事に取り組むときはどういう動機によって取り組むべきか(欲から生まれた動機でもかまわない,動機は多い方がよい)

2章は「自分の才能って?」と題されている.内容は,主に自分のやりたいことについて,より突っ込んだ思考をするためのきっかけが書かれている.第1章の内容を,より濃く考えるためのきっかけを提供しているように思う.
自分の才能は何か.才能は他者との関係から生まれるのではないか.表現力は一日にして成らず.表現力は「いま」をとらえるためのもの.「いま」を捉える練習をしろ.無用な気遣いで伝えたいことの本質を失ってないか.

3章の「一人称がいない」は,最近は一人称を抜いて表現することが増え,そのためによくわからない文になっているものが多い,ということを書いている.ただし,それは関係性がうまく掴めていないからではないか?という主張が見える.実をいうと,僕はこの章を把握できていない.

全ての章にいえることだが,考えるきっかけを与える文章が多く,一言で筆者の伝えたいことをまとめるのが難しい.とても乱暴にまとめるなら「おまえら,考えろ!」なのかもしれない.簡単な文章なんだけど,頭にひっかかり,「あれ,なんでだろう」と考えられるようになっている.

普段なら,大まかにでも筆者の言いたいことを理解してから,まとめとして記事を書くのだが,今回はあえて筆者がいいたいことがまだちゃんとわからないうちに書くことにした.なんだかよくわからないものを,自分なりに感じたことを書くことも,筆者のいう「いま」を捉える表現力につながるのではないか,と考えるからだ.「よくわからないけど,僕はいま
この文章をよんでこう感じる,こう考える.」このことを発信するのが,表現力を鍛えるのに重要だと思うようになった.

「貧乏はお金持ち」読書ログ

日曜日, 7月 19th, 2009

「貧乏はお金持ち」という本を読んだので,ログを残す.

前半,特にまえがきと1章2章あたりの内容がすごく興味深かった。

面白かったのは,自由の定義と,会社と個人の関係性だ.著者によると,自由とは「人生を選択できる経済的な土台」である.自分を養う資力がなければ,資力的にどこかに依存する必要がある.この経済的に支配されてる状態を,一般に「隷属」と呼ぶ.

依存先は,仕事をした対価として資力をくれる会社や,ある年代までは面倒を見てくれる親だったりするわけだ.隷属の状態では,自由な人生を送っているとは言えない.経済的に支配されているため,たとえば会社の仕事をこなさなければならなかったり,親の言うことを最低限守る必要があったりする.と考えると,自由な人生を送るには自分の手で金を稼ぐことが重要だ.

自分の手で稼ぐとはいうが,今の世の中で稼ぐ方法は抽象化すると一つと言う.

「資本を市場に投資し,リスクを取ってリターンを得る」

通常は,人的資本(つまり労働力)を高めることでリターン(お金)を得ている.人的資本を高めるというのは,簡単にいうと高い学歴を持つとか,高いスキルを持つとかそういうことになる.一般的には,若いうちは人的資本で稼ぎ,歳を取れば年金や若いうちに稼いだ資本を運用することで生活する.

そういうわけで,ふつう若い人は人的資本を最大化し,リターンを多く得る戦略を取る.ここで重要なのが,リターン = お金ではなく,その人の精神的な満足度も含まれることにある.なので,就職先に5年間は辛いけど儲かるコンサルを選ぶ人もいるし,農家を継いで父母と暮らす人もいる.

でもここで,論理的に矛盾があるように思った.自由な人生を送るには,自分の手で金を稼ぐと言う.しかし,自分一人で金を生み出すことはできない.上記の例で言うならば,人的資本を市場に投資しリターンとして金を得るのだから,
人的資本を投入する市場に隷属することになる.もっと具体的に言えば,金は,誰かに必要とされるサービスの対価としてもらうものだから,サービスを使ってお金を落としてくれるユーザーに隷属するんじゃないかと思う.

だから,会社に属さず一人で仕事をしたとしても,結局は資力は他者に依存する.そういう意味では,どんなふうにしても,他者に隷属する状態が続き,人は自由ではいられない.なので,著者の言う自由には定義的に無理があるなぁ,と思いました.

でも,その隷属する先が会社一つだと,それがこけたとき危ないのは当然だよね.だから,隷属する先をいくつも用意するとか,他の会社が欲しがってくれるスキルを持つとか,節税のために国家を道具として利用し,生き延びる戦略を持つとか,対策をしておいた方が良いよということでした.その点は非常に同意だし,特に国家を利用するTipsが色々書かれているので,手元に置いておくのは良いかも.

ただ,結局節税は,そもそも収入がある人が如何に利益を多く手にするか,という話なので,収入は頑張って自分で上げて下さい,とのことでした.w

「初めてのPerl第3版」(リャマ本)読書ログ – 第17章「上級テクニック」

土曜日, 6月 20th, 2009

初めてのPerl

0による除算エラーや不正な正規表現は,プログラムをクラッシュさせる可能性がある.それら致命的なーエラーをキャッチするには,コードをevalでくくればよい.

[perl]
my $dino = 0;
eval {
$barney = $fred / $dino;
};
[/perl]

evalはwhileなどの制御構造ではなく式なので,evalの後ろにはセミコロンが必要になる.
eval内で実行されたコードが不正終了したのかどうかを調べるには,特殊変数$@が用いられる.evalが致命的なエラーをキャッチした場合,$@にメッセージがセットされる.$@が空なら,eval内のコードは正しく実行されたと考えてよい.

evalブロックの中に,他のevalブロックをネストすることもできる.内側のevalブロックでエラーをトラップすると,外側のevalブロックではエラーをトラップしない.エラーを伝播させるには,dieを使えばよい.

evalが致命的なエラーをトラップした場合,その戻り値はundefか空リストになる.そのため,上記の例では,$barneyの値がundefかどうかを調べれば致命的なエラーが起こったかどうかを知ることができるため,$@を見ることで致命的なエラーが起こったかどうかを調べる必要はない.

evalでトラップできないエラーは4種類ある.1)Perlそのものをクラッシュさせるエラー(メモリ不足,シグナル等),2)evalブロック内で発生した構文エラー(コンパイル時にキャッチされる),3)exit演算子(プログラムを終了させる),4)警告(ユーザーがwarnによって発生させた警告)からなる4つである.

リストから一部の要素だけ取り出したい,ということがよくある.リストの中から,奇数だけを取り出したい,Fredという名前が入ったものだけ取り出したい,等である.grep演算子でそれらは可能だ.

[perl]
my @odd_numbers = grep { $_ % 2} 1..1000;
#1から1000までの間で,奇数のもののみodd_numbersにpush
[/perl]

ブロックを引数に取り,そのブロック内の操作で値を返したものがリストに入る.

[perl]
my @matchin_lines = grep { /\bfred\b/i } <FILE>;
my @matchin_lines = grep /\bfred\b/i , <FILE>; #さらにシンプルに書ける!
[/perl]

数値リストを金額として一時的に表示する場合,mapを使ってリストを変換できる.
[perl]
my @data = {4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95};
my @formatted_data;

foreach (@data) {#この処理がmapを使うことで短縮できる
push @formatted_data, &big_money($_);
}

my @formatted_data = map{ &big_money($_) } @data;
[/perl]

map演算子は,引数の内容を$_にマップし,ブロックに渡す.

次に,ハッシュのショートカットを紹介する.ハッシュのキーを書く際は,クォートを省略できる.キーが英文字と数字と下線だけから成り,先頭が数字以外のものであれば,クォートを省略できる.このようなキーのことを裸のワード(bareword)という.

[perl]
my %score = (
barney => 195,
fred => 205,
dino => 30,
);
[/perl]

次は正規表現のコツについてだ.通常の量指定子(+や*等)は,欲張りなマッチを行う.すなわち,パターン/fred.+barney/と文字列”fred and barney went bowling last night”が合ったときに,パターンはfredとマッチしたあと,.をマッチさせる為にnightのtからじょじょにバックトラックする形でマッチの試行を行う.barneyまでマッチ試行がバックトラックしたときに初めて結果を返す.
しかしこのような欲張り型のマッチだと,あるHTML文書からタグだけ抜き出すような場合や,文章が長い場合には適さない.そこで,欲張りでないマッチを行いたい場合には,量指定子に?を付けよう.

[perl]
$str = "<html>hogehoge<bold>fuga</bold>. hogefuga<bold>hoge</bold>.</html>";
if($str =~ /<bold>(.*)<\/bold>/) {#欲張りな量指定子の時
print $1; #fuga</bold>.hogefuga<bold>hogeが出力される.
}

if($str =~ /<bold>(.*?)<\/bold>/) {#欲張りでない量指定子の時
print $1; #fugaが出力される.
}
[/perl]

また,複数行のテキストに対するマッチを行うこともできる.そのためには/mオプションを指定すれば良い.

[perl]
$_ = "I’m much better\nthan Barney is\n at bowling, \nWilma.\n";#4行のテキスト
print "found ‘wilma’ at start of line\n" if /^wilma\b/im;
[/perl]

リストはリストスライスという機能によって,その要素のいくつかだけを簡単に取り出すことができる.
例えば,以下のように.

[perl]
$_ = "1:tomoaki sano:24";
my $sano_old = (split /:/)[2];

my @names = qw/ zero one two three four five six seven eight nine /;
my @numbers = @names[9, 0, 2, 1, 0];#配列もスライスできる

my %scores = {fred => 68, dino => 110};
my @two_scores = @scores {qw/ fred dino /};#ハッシュもスライスできる
[/perl]

「初めてのPerl第3版」(リャマ本)読書ログ – 第16章「単純なデータベース」

金曜日, 6月 19th, 2009

初めてのPerl

perlはシンプルなデータベースであるDBMがデフォルトで利用できる.DBMのデータベースは,my_database.dirとmy_database.pagという2つのファイルからなる.DBMの利点は,perlプログラム上でハッシュと同じようにDBのコンテンツを扱えることにある.

[perl]
dbmopen(%DATA, "my_database", 0644) #my_databaseというDBMをオープンする
or die "Cannot create my_database: $!";

$DATA{"fred"} = "bedrock"; #DBMへのデータ追加
$DATA{"barney"} = "hoge";
remove $DATA{"barney"}; #DBMからのデータ削除

foreach my $key (keys %DATA) {
print "$key\n";
}
[/perl]

なお,データ数が増えるほど,keysを使ってハッシュのキーリストを得る処理は重くなる可能性がある.keysはハッシュ全体をスキャンするので,大きなリストを生成するかもしれないから.DBMハッシュをスキャンするときは,一般には,each関数を使った方がメモリの使用量が少なくて済む.

[perl]
while( my($key, $value) = each(%DATA)) {
print "$key has value of $value\n";
}
[/perl]

データをDBMに格納する際,1つのキーに対して複数の値を格納したいときは,pack/unpack関数を利用する.packは,フォーマット文字列と引数のリストを受け取って,それらをもとに1個の文字列を生成する.

[perl]
my $buffer = pack("c s l", 31, 4159, 263539);
my($char, $short, $long) = unpack("c s l", $buffer);#charには31, shortには4159, longには263539が入る
[/perl]

DBMはいうなれば巨大なハッシュだったが,他にも固定長や可変長のテーブルを利用することができる.固定長テーブルと可変長テーブルについての解説は必要になれば追記する.

perlはちょっとした処理を行う為に,一行のプログラムをさくっと実行するモードを用意している.

[perl]
$perl -p -i.bak – w -e ’s/Rnadall/Randal/g’ fred*.dat
[/perl]

-pオプションは以下のようなプログラムを追加する処理をする.

[perl]
while(<>) {print;}
[/perl]
-eオプションで指定されるのが,実行して欲しいプログラムとなる.これが,上のwhile(<>)内に入ると考えれば良い.-i.bakオプションは,実行前に$^Iに.bakをセットする.これはすなわち,ダイアモンド演算子で指定されたファイルのバックアップファイルの拡張子として,.bakを利用する,というものである.-wオプションは,先に述べた通り,警告を出させる.-eオプションの次に来るfred*.datがプログラムに対する引数となる.

「初めてのPerl第3版」(リャマ本)読書ログ – 第15章「文字列処理とソート」

木曜日, 6月 18th, 2009

初めてのPerl

index関数を使うと,ある文字列の部分文字列を検索できる.返り値は部分文字列が出現する場所の位置インデックスを返す.インデックスは0から始まる.つまり,文字列「hogefuga」の中で「ho」という部分文字列を探すと,indexは0を返す.部分文字列が見つからなければ-1を返す.また,indexは常に最初に見つかった部分のインデックスを返す.

[perl]
$where = index($str, $small);
#$strの中から$smallにマッチする位置インデックスを返す
[/perl]

常に最後に見つかった部分文字列のインデックスがほしければ,rindex関数をindex関数と同様に呼び出せば良い.

substrは他の言語と同じように,部分文字列を取得できる.3つの引数を取り,対象とする文字列,取得する開始位置インデックス,取得する終了位置インデックスを渡す.
さらに,第1引数の文字列が変数なら,その変数のうち,指定した部分のみ書き換えることができる.

[perl]
my $mineral = substr("Fred J. Flintstone", 8, 5); # Flintを返す
my $rock = substr "Fred J. Flintstone", 13, 1000; #stoneを返す(末尾を超える指定の場合,最後まで返す)
my $pebble = substr "Fred J. Flintstone", 13; #stoneを返す(末尾の指定がない場合,最後まで返す)

my $string = "Hello, world!";
substr($string, 0, 5) = "Goodbye"; #$stringにはGoodbye, world!となる
[/perl]

C言語にあるsprintfも,同じように利用できる.

次に,ソートサブルーチンについて説明する.すでに,リストやハッシュをソートする関数sortについて述べた.しかしリストの内容によってソートする方法は違う.そこで,ソートサブルーチンを利用することで,自分の望むようにリストをソートできるようになる.
ソートサブルーチンは,通常のルーチンのように宣言するが,引数として$a, $bが規定される.具体的には以下のように書く.

[perl]
sub by_number {
if($a < $b) {-1 } elsif ($a > $b) {1} else {0}
}
[/perl]

ソートサブルーチンをツアクには,キーワードsortとソートすべきリストの間にその関数を置く.以下のように.

[perl]
my @result = sort by_number @some_numbers;
my @result = sort {$a <=> $b } @some_numbers; #通常はこっち
[/perl]

ソートサブルーチンの中では$aと$bを宣言したり,値をセットしたりする必要はないことに注意せよ.上記のby_number関数の処理はよくあることなので,スペースシップ演算子(<=>)を使うことで同様の機能を実装できる.しかし,スペースシップ演算子は数値のみに有効である.文字列に対しては,cmp関数を利用する.
実際はソートサブルーチンを書くことはまれで,2個目の例のように関数をインラインで書く.

数値を降順(大きいものから小さいものの順)でソートする場合,$aと$bを逆にするだけでよい.

ハッシュを値によってソートする場合は以下のように書く.

[perl]
my %score = ("barney => 195, "fred" => 205, "dino" => 30);
sub by_score {$score{$b} <=> $score{$a}}
[/perl]

「初めてのPerl第3版」(リャマ本)読書ログ – 第14章「プロセス管理」

木曜日, 6月 18th, 2009

初めてのPerl

Perlで子プロセスを起動する方法の一つにsystem関数を利用することがある.
[perl]
system "date"; #unixのdateコマンドを呼び出す
[/perl]

system関数は,Perlの標準入力,標準出力,標準エラーをそのまま受け継ぐ.上の例では,dateコマンドの結果をPerlのSTDOUTと同じところに送られる.
また,Perlはsystemで起動した子プロセスが終了するまで次の式の実行を待つ.すなわち,dateコマンドの実行に10秒かかるとしたら,10秒間は次の式を実行しない.ここのことから,systemで起動するコマンドが,対話側のものだった場合に問題が起こる.例えば,dateコマンドが単純に時刻を返すコマンドではなく,起動時に「どの地域の時刻を返しますか?」と聞き,入力を促すコマンドだった場合,入力を渡すまでこのPerlスクリプトは終了しない.しかし,system関数の時点でdateコマンドの終了を待つため,永遠にPerlスクリプトが終わらないことが起こりえる.
シェルのバックグランドプロセスを起動することで,この動作を回避できる.

system関数の中で,Bourneシェル(/bin/sh)を起動し,シェルスクリプトの実行も可能である.

[perl]
system ‘for i in *.pl; do echo == $i ==; cat $i; done’; #.plファイルの中身を出力する
[/perl]
シングルクォートを使うのは,$記号をPerlスクリプト内の変数と混同しないため.

2個以上の引数を渡して,system演算子の起動も可能だが,その場合はシェルは起動できない.

[perl]
my $tarfile = "something*wicked.tar";
my @dirs = qw(fred|flintstone <barney&rubble> betty );
system "tar", "cvf", $tarfile, @dirs; #きっかり5つの引数がtarコマンドに渡される.
[/perl]

systemに渡される引数は,第1引数がコマンド名で,それ以降の引数はコマンドに渡される引数となる.上の例では,tarコマンドに,”cvf”, $tarfile, “fred|flintsone”, ““, “betty”の5つの引数が渡される.

上の例に比して,以下の例は危険である.絶対に真似せぬよう.
flintstoneコマンドに大量のデータを流し込む動作をすることになる.

[perl]
system "tar cvf $tarfile @dirs";
[/perl]

なお,system関数は,成功すればUNIXでの成功をあらわす0を返す.0以外の終了値は何かがうまくいっていないことを示す.

system関数と似た動作をする関数としてexecがある.違いは,execからコマンドを実行した場合,それはPerlの子プロセスとならず,Perlのプロセスを終え,そのコマンドを実行するプロセスのみが残ることになる.exec関数は,他のプログラム実行するための環境を用意する際に活きる.

system関数を使う場合,気になるのが環境変数PATHだろう.Perlでは環境変数は以下のようにして設定する.

[perl]
$ENV{‘PATH’} = "/home/rootbeer/bin:$ENV{‘PATH’}"; #環境変数PATHへの追加
delete $ENV{‘IFS’}; #環境変数IFSの削除
[/perl]

system関数呼び出したコマンドの出力は,標準出力に送られることは既に書いた.しかし,コマンドの出力を取得して変数に格納するのに,もっと簡単な方法もある.逆クォートを利用することである.

[perl]
my $now = `date`; #dateコマンドの実行結果をnow変数に格納する
[/perl]

しかし,出力を取り込まないときは,逆クォートを利用するべきでない.出力をperlが拾っているのに,せっせと捨てることになるし,意図がわからなくなるためだ.

リストコンテキストで逆クォートを利用すると,結果を行毎に分割して格納する.

これまではPerlから子プロセスを生成し,子プロセスの処理が終了するまで待つ,という同期プロセスを扱ってきた.しかし,Perlとの通信を行いつつ,処理が完了するまで独立して実行される子プロセスもPerlは扱える.それには,open関数を利用する.open関数は並列実行するプロセスをファイルハンドルとして扱う.また,並列実行するコマンドの真絵馬は後ろに縦棒を付けたものを指定する.

[perl]
open DATE, "date|" or die "cannot pipe form date: $!";
open MAIL, "|mail merlyn" or die "cannot pipe to mail: $!";
[/perl]

縦棒がコマンドの右についているもの(date|)では,コマンドの標準出力が,入力用にオープンされたDATEファイルハンドルに連結される. 逆に縦棒がコマンドの左についているもの(|mail)では,コマンドの標準入力が,出力用にオープンしたMAILファイルハンドルに連結される.

データの入力,出力されたデータの取得は通常のファイルハンドルと同様に行う.

perlからUnixのシグナルの送信が可能である.シグナルは名前(SIGINT割り込みシグナル)とそれに対応する小さな整数値によって識別される.例えば,端末からコントロールC等の割り込み入力を行うと,プロセスにSIGINTシグナルが送られる.

Perlスクリプトからシグナルを送るには,シグナルの種類と,プロセスのIDが必要になる.
プロセス番号4211のプロセスにシグナルを送るには,kill関数を利用する.

[perl]
kill 2, 4211 or die "cannnot signal 4211 with SIGINT: $!";
[/perl]

killの第1引数はシグナルの種類を表す.2はSIGINTを送る.

「初めてのPerl第3版」(リャマ本)読書ログ – 第13章「ファイルとディレクトリの取り扱い」

木曜日, 6月 18th, 2009

初めてのPerl

perlスクリプトからファイルを削除するにはunlink演算子を使う.ディレクトリは削除できない.

[perl]
unlink "slate", "bedrock", "lava.pl"; #slate, bedrock, lava.plというファイルを削除する
[/perl]

unlinkは引数にリストを取るので,globを使って複数のファイルを削除できる.

[perl]
unlink glob "*.o";
[/perl]

unlinkは削除に成功したファイルの個数を返す.

[perl]
$remove_num = unlink glob "*.o";
print "removed file num : $remove_num\n";
[/perl]

ただし,この場合,1や2が返ってくると,どのファイルが削除されたかわからない.その場合は,ファイルリストをforeachで回し,一つずつ削除するべきだ.この場合,unlinkが返すのは,1か0の値となり,bool値として扱える.

また,unlinkが失敗した場合,$!にオペレーティングシステムエラーに関するメッセージが入る.デバッグの際は$!を利用すると良い,

ファイル名の変更には,rename演算子を使う.

[perl]
rename "old", "new"; #oldという名前のファイルをnewという名前に置き換える
[/perl]

renameが失敗すると返り値として偽を返し,$!にオペレーティングシステムエラーに関するメッセージが入る.

次はハードリンクをperlスクリプトで貼る方法だ.link演算子を使うことで実現できる.renameと同じく,失敗すると偽を返し,$!にエラーメッセージを返す.

[perl]
link "hoge" "fuga"; #hogeへのリンクであるfugaを生成する
[/perl]

シンボリックリンクを貼るには,symlink関数を使う.逆にシンボリックリングが指している場所を知るには,readlink関数を使う.

[perl]
symlink "dodgson", "carroll";
my $where = readlikn "carroll"; #dodgsonが得られる.
[/perl]

ディレクトリの作成はmkdir関数を使う.引数はファイル名とパーミッションの2つだ.

[perl]
my $name = "fred";
my $permissions = "0755";
mkdir $name, oct($permissions); #oct関数は文字列を強制的に8進数と見なす
[/perl]

ディレクトリの削除はrmdirだ.また,パーミッションの変更はchmod関数を利用する.オーナーの変更はchown関数を利用する.これはunixのchmodと同じ構文で利用できるので解説しない.

現在の時刻の取得はtime関数を引数無しで呼び出すことで実現される.また,ファイルのタイムスタンプを変更するには,utime関数を利用する.

[perl]
my $now = time;
my $ago = $now – 24 * 60 * 60;
utime $now, $ago, glob "*"; #カレントディレクトリのファイル群のタイムスタンプを変更
[/perl]

ファイルパスからベース名を取得するには,File::Basenameモジュールを使う.

[perl]
use File::Basename;
my $name = "/usr/local/bin/perl";
my $basename = basename $name; # ‘perl’となる
[/perl]

File::Basenameモジュールの中には複数の関数が含まれている.use宣言を使って関数をスクリプトに読み込ませる際に,”インポートリスト”を利用することで,どの関数を読み込むか指定することができる.

[perl]
use File::Basename qw / basename /; #basename関数のみ読み込ませる
[/perl]