23042009 Ruby
気になる本。
23042009 Ruby
気になる本。
やさしい Lisp の作り方 by Java and by C#を参考に書いてみる。
READ-PRINT-LOOPまでのものを動かしてみる
$ perl moosp.pl
Moosp> (1 2 3 4)
(1 2 3 4)
Moosp> (e r t)
(E R T)
Moosp> (2 . 3)
(2 . 3)
Moosp> (defun plus (a b) (+ a b))
(DEFUN PLUS (A B) (+ A B))
コード
package Moosp;
use Moose;
use Moosp::Env;
use Moosp::Reader;
use Term::ReadLine;
our $VERSION = 0.01;
sub run {
my $self = shift;
my $term = new Term::ReadLine 'Simple LISP REPL';
my $prompt = "Moosp> ";
my $OUT = $term->OUT || \*STDOUT;
while ( defined ($_ = $term->readline($prompt)) ) {
my $reader = Moosp::Reader->new();
my $sexp = $reader->readFromString($_);
warn $@ if $@;
print $OUT $sexp->serialize(), "\n" unless $@;
}
}
__PACKAGE__->meta->make_immutable;
no Moose;
1; # End of Moosp
moosp.pl
#!/usr/bin/env perl
use lib "./lib";
use Moosp;
Moosp->new->run();
富士の大淵の花として有名らしい(が、U隊長の知り合いの富士市民はみんな聞いたこともないと言ってた)ミツバツツジを見に行きたいというので車で出かけた。正直僕は毎日見ているので見飽きた。
桜のように花が咲いた後に葉っぱがでるので、まとめて咲いてるとかなり奇麗。

気になっていた蕎麦屋。

中では農作業かなんかを終えたおじいちゃんが一人で焼酎やってた。のどかな感じ。蕎麦は山芋をつなぎに使っていて、のどごしというよりは噛み応えがある感じ。キョウザンボウの田舎を細くした感じか。辛汁もだしが効いていて好み。

ワラビもつけてくれた。うまかった。

うどんはのどごしが良くて、評判だったのと、さしみこんにゃくがおいしかったので帰りに買って帰った。

きわだ路の近くの大淵二小のそば。いい感じのたたずまい。

外に用意されているテラスみたいなとこで、のんびりできそう。


ちょっと甘めだけど、美味しかった。
MooseX::Singletonでuseしたクラスが継承している場合instanceで呼ばれたオブジェクトはスーパークラスのメソッドを呼べないという挙動ではまった。
package Foo;
use Moose;
sub p { return "XXX" }
package Sng;
use MooseX::Singleton;
extends 'Foo';
package main;
my $sng_new = Sng->new();
warn $sng_new->p();
my $sng_instance = Sng->instance;
warn $sng_instance->p();
実行
$ perl ms.pl
XXX at ms.pl line 15.
Can't locate object method "instance" via package "Sng" at ms.pl line 17.
version
$ perl -MMooseX::Singleton\ 999
MooseX::Singleton version 999 required--this is only version 0.14.
予約した
やさしい Lisp の作り方 by Java and by C#を参考に書いてみる。
readerは文字列(strings)と今読んでいる位置(index)と現在読んでいる文字の値(char)の属性を用意してあって、一文字読み進めてインデックスを一つ進めるget_charと一文字読み進めるけどインデックス値は進めないという先読み機能のnext_charというメソッドで移動していく。
先読みメソッドを用意するよりはインデックス値を一つ巻き戻すメソッドを用意しておいて、必要に応じてインデックス値を減らすという実装のほうだとcharアトリビュートを用意しておく必要はないかなと思った。
よくわからなくなってきたのでもう一度きちんと見直すかも
package Moosp::Reader;
use Moose;
use Moosp::Nil;
use Moosp::T;
use Moosp::List;
use Moosp::Integer;
use Moosp::Symbol;
use Moosp::Env;
has env => ( is => 'rw', isa => 'Moosp::Env', default => sub { Moosp::Env->new });
has index => (is => 'rw', isa => 'Int', default => 0 );
has strings => (is => 'rw', isa => 'Str');
has char => (is => 'rw', isa => 'Str');
sub get_char {
my $self = shift;
my $index = $self->index;
$self->char(substr($self->strings,$index,1));
$self->index($index + 1);
return $self->char;
}
sub next_char {
my $self = shift;
$self->char(substr($self->strings,$self->index,1));
return $self->char;
}
sub getSexpPrepare {
my $self = shift;
$self->getSexpPrepareString(@_);
}
sub readFromString {
my ($self, $input) = @_;
$self->getSexpPrepareString($input);
$self->getSexp;
}
sub getSexpPrepareString {
my ($self, $input) = @_;
$self->strings($input);
}
sub getSexp {
my $self = shift;
while (my $ch = $self->get_char()) {
if ($ch eq '(') { return $self->makeList(); }
elsif ($ch eq '\\') { return $self->makeQuote(); }
elsif ($ch eq '-') { return $self->makeMinusNumber(); }
else {
if ($ch =~ /\s/) { last; }
if ($ch =~ /\d/) { return $self->makeNumber($ch); }
return $self->makeSymbol($ch);
}
}
return Moosp::Nil->instance;
}
sub makeList {
my $self = shift;
my $top = Moosp::List->new();
my $list = $top;
my $ch;
while(1) {
$list->car($self->getSexp());
$ch = $self->char;
last if ($ch eq ')');
return Moosp::Nil->instance if ($ch eq '');
if ($self->next_char eq '.') {
$ch = $self->get_char();
$ch = $self->get_char();
$list->cdr($self->getSexp());
return $top;
}
$list->cdr(Moosp::List->new());
$list = $list->cdr();
}
$ch = $self->get_char();
return $top;
}
sub makeNumber {
my ($self, $str) = @_;
while (my $ch = $self->get_char()) {
last if $ch eq '(' || $ch eq ')';
last if $ch =~ /\s/;
unless ($ch =~ /\d/) {
$self->index($self->index - 1);
return $self->makeSymbolInternal($str);
}
$str .= $ch;
}
return Moosp::Integer->new({value => $str});
}
sub makeSymbol {
my ($self, $ch) = @_;
return $self->makeSymbolInternal($ch);
}
sub makeSymbolInternal {
my ($self, $str) = @_;
while (my $ch = $self->get_char()) {
last if $ch eq '(' || $ch eq ')';
last if $ch =~ /\s/;
$str .= $ch;
}
$str = uc $str;
return Moosp::T->instance if ($str eq 'T');
return Moosp::Nil->instance if ($str eq "NIL");
my $sym = $self->env->symbol->{$str};
return $self->env->set_symbol(Moosp::Symbol->new(name => $str)) unless defined($sym);
return $sym;
}
sub makeMinusNumber {
my $self = shift;
my $nch = $self->next_char();
return $self->makeSymbolInternal("-") unless $nch =~ /\d/;
return $self->makeNumber("-");
}
sub makeQuote {
my $self = shift;
my $top = Moosp::List->new();
my $list = $top;
$list->car($self->env->symbol->{"QUOTE"});
$list->cdr(Moosp::List->new());
$list = $list->cdr();
$self->get_char();
$list->car($self->getSexp());
return $top;
}
1; # End of Moosp::Reader
Readerが出来るとそれっぽくなってきた感じがする。
うちの近所だと、日曜日に開いているまともな酒屋が少ないので、どんなに疲れていても土曜日に酒屋詣でをするのだけど、先週はなぜかお参りできなかったので、仕方なく吉原のあたりをぶらぶらしてたら、アドニスの近くに酒屋を見つけたので入ってみた。
品揃え的には七賢とかそんな感じだったのだけど、高砂のとこでやっている鎮国之山があったので購入。まぁ知らないところの冷蔵管理の酒はちょっとヘジテートするので、火入れで。

ラベルはなし。高砂にしてはすっきり目でなかなかうまい。あとは酒屋のヒトとはよく話すようにしている。純米はないのかとか一升はないのかとか、冷蔵庫みれば分かるじゃん的な質問をジャブ的にかますと、色々教えてくれたりするので楽しい。
19042009 work
自分で失敗を自覚するまで納得できない人は失敗が確定するまで、失敗が近づけば近づくほど指数関数的に頑張り(そして周りにもがんばりを強要し)、精神論をまき散らしつつ周りを巻き込み疲弊させ最終的に集団心中するようなタイプが多いような気がする。
しかし、本人は頑張ったという達成感で一杯なので、次もめげずに同じことを繰り返すのだ。
屍を超えていくのではなく、屍を再生産しようとするそのスタイルは僕は好きではなかったりする。
娘がオムライスを食べたいと言い出したので、セロリ畑へ行くことにした。記憶(というかデータベース)を辿ると実に三年半ぶりだった。

娘はビーフのオムライス。僕は辛さ4のカツカレー。カレーはやはり甘さと酸味が強いのでこのくらい辛くても良い感じ。もう一段辛くてもいいかな。あと卓上のスパイスミルを振りかけることで香りが向上していい。次はナンのセットにしたいとこ。

帰りに近くにある通称新幹線の公園に行った。僕だけ初めてだったがなかなかよさげ。鉄道のレールは30Kg/mあってかなり重いというまめ知識を仕入れた。

鉄道鉄琴がかなり面白くて、娘と一緒になって叩きまくった。

あと、機械と自然のフュージョンっぷりがなかなかよろしかった。