昔ブログに書いた記事から。
当時のタイトルは『Rubyとは・・・。』で、書いたのは2005年10月23日。
当時のことを補足しておくと、自分はもっぱらPerlでプログラムを書いてて、Perlのオブジェクト指向機能も知ってた。
で、他に使ってた言語はCとJavaという感じ。
そんなときに出会ったRubyは衝撃的だったよ、という話。
人工知能に興味があるのはもちろんだけど、とりあえず人工無脳なるものも面白そうだと思い、どういう構造をしているのかというのが知りたかったから、『恋するプログラム――Rubyでつくる人工無脳』なる本を買ってみた。
恋するプログラム―Rubyでつくる人工無脳 (Mynavi Advanced Library)
- 作者: 秋山智俊
- 出版社/メーカー: マイナビ出版
- 発売日: 2014/12/04
- メディア: Kindle版
- この商品を含むブログを見る
んで、昨日と今日を使ってとりあえず6章までは読んだんだけど、思っていたのよりもスッキリした構造でビックリ。
こんな簡単に作れちゃうものなのかと。
(もちろん、最初のクラス設計がうまいからそう見えるんだろうけど)
やはり感情を表現していくのは難しいようだけど、でもそれなりのものが比較的簡単に実装できてる。
まぁ、そのうちPerlでも実装してみたいかな。
(ただ、正規表現がちょっと大変?)
それはさておき。
この本で初めてRubyがどんな言語なのかを見たんだけれど、なんというかそこまでオブジェクト指向なのかよ!っていう感じの言語。
まず、オブジェクトじゃないデータ型がない!
文字列はもちろん、正規表現もオブジェクトだし、なんと数字さえもがオブジェクト!
これにはかなりビックリさせられた。
だから、数字にもメソッドがあって、例えば
5+2
というのは、Rubyによれば5という数字の+というメソッドが2というオブジェクトを引数に呼び出された、と解釈されるみたい。
$str =~ /$pattern/;
と書くんじゃなくて、
/pattern/ =~ str # Rubyは(ローカル)変数に$は付けないし、;も文末に付けない
というふうに、/pattern/
という正規表現のメソッド=~
をstr
というオブジェクトを引数として呼び出す、と考えて書くみたい。
なので、オブジェクト指向に最適化されていて、すべてのデータがオブジェクトなので、変数に代入されるのは、常にオブジェクトへのリファレンス。
つまり、普通の言語でいう「普通の変数」(Javaでいうプリミティブ型の変数)なるものはなく、あるのはポインタ(Javaでいえば参照型、Perlで言えばリファレンス)のみ。
だから、逆にいえばポインタというものを変数とは別に扱う必要がなく、すごくスッキリした言語になっている。
また、配列やハッシュというのもオブジェクトで、○○クラスの配列、という概念はなく(Javaの場合はこれがある)、あるのは「いろいろなオブジェクトを収納するオブジェクト」あるいは「いろいろなオブジェクトをキーとセットで収納するオブジェクト」だけ。
だから、あるのはホントにオブジェクトへのリファレンスのみ。
おかげで、Perlにおける$
や@
などデータ型を表すものは必要ではなく、それらは変数のアクセス権や特徴を表すものとなっている。
(例えば、@
で始まる変数はインスタンス変数、@@
で始まる変数はクラス変数、$
で始まる変数はグローバル変数)
次に、Perlでいうforeach構文がオブジェクトのメソッドとして実装されている!
Perlで何かの処理を10回繰り返したいとすれば、
foreach my $t (1..10) { 処理内容 }
とするわけだけど、Rubyではこれと同じことを
10.times do |t| 処理内容 end # tには0, 1, … , 9と代入され、処理内で使える # do … endはブロック
と、つまり10というオブジェクトのtimes
メソッドで実現させている。
あるいは何か配列に処理を行いたいとすれば、Perlでは
foreach my $t (@array) { 処理内容 }
とするわけだけど、Rubyでは
array.each do |t| 処理内容 end
と、やはりarrayというオブジェクトのeach
メソッドで実現させている。
ここでさらに注目したいのがdo … end
によるブロックで、これってメソッドにサブルーチンへのリファレンス渡しているのと同じだよね?
つまり、ブロックすらもオブジェクトといえる・・・
最後に、カプセル化のレベルがすごい!
簡単に言ってしまえば、オブジェクトからフィールドを直接呼び出す文法が(たぶん)ない!
Javaだったらobject.field
とすることで(可視性がpublic
なら)アクセス出来てしまうし、Perlでも$object->{field}
とかすることでフィールドに外部から直接アクセスできる。
けれど、Rubyにはこの呼び出し方がない。
でも、代わりに便利な機能があって、
attr_reader :field
としておければ、field
というフィールドにアクセスするメソッドfield
、つまり
def field return @field end
というメソッドが自動で定義されるとのこと。
(上のは、Perlでいうと、sub field{ return $_[0]->field;}
というメソッド)
このattr_reader
というメソッドには引数をカンマで区切っておけるということなので、外部からもアクセスしたいフィールドのメソッドはこれで一発で定義でき、呼び出すにはobject.field
とするだけでいい。
この仕組みはとてもいいなぁ、と思う。
(PerlでもAUTOLOAD
と型グラブを使うことでこれと同じことが出来るみたいだけれど、正直それでもかなりめんどくさい)
けれど、やっぱり{}
をつかわないでdo … end
でブロックを書くのだけは見にくくて困るなぁ、と思うのは自分だけ?
こんな感じで、Rubyの言語設計はホントに見事の一言。
Rubyはいいぞ。
そんなわけで、Rubyのいいところを知っていると、Pythonを使う気になれない・・・
PythonはホントPerlに毛が生えたレベルのオブジェクト指向だからね。
Perlのオブジェクト指向もプリミティブな感じで、それはそれでよく出来てるなと感心するんだけど、Pythonもまぁ似たようなものだから。
(Perlはハッシュへのリファレンスを使ってオブジェクト指向を実現してて、その仕組みが丸見えなんだけど、Pythonもディクショナリでオブジェクト指向を実現してるようなもので、それを薄皮一枚で隠蔽している感じ)
2.x系と3.x系のゴタゴタが解消されていないのも、すごく印象が悪い。
Rubyがもっと流行ってくれればいいんだけどなぁ。
特に、機械学習の分野で。
今日はここまで!
恋するプログラム―Rubyでつくる人工無脳 (Mynavi Advanced Library)
- 作者: 秋山智俊
- 出版社/メーカー: マイナビ出版
- 発売日: 2014/12/04
- メディア: Kindle版
- この商品を含むブログを見る
- 作者: 高橋征義,後藤裕蔵,まつもとゆきひろ
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2016/02/26
- メディア: 単行本
- この商品を含むブログ (2件) を見る