恥ずかしながら文法から
やっぱRubyの基本文法くらい知らないとどうにもならないと思ったのでプログラミングRuby―達人プログラマーガイドを教科書に初めのほうから文法を学ぶことに。一応Javaは理解しているのでクラスとかそういうオブジェクト指向的な概念は分かる。でも、やっぱ言語違うと違うなぁ。C#もそうだけど、アクセサ周り(Javaでいうgetter、setter)とか違うよねー。Javaはイチイチ書かなきゃいけなくてあまりにイケてないもんな。
本で出てきた例でname,artist,durationというプロパティを持つSongクラスをJavaで表現するとこうなるのが、
public class Song { // プロパティ private String name; private String artist; private int duration; // コンストラクタを用意 public Song(String name, String artist, int duration){ this.name = name; this.artist = artist; this.duration = duration; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public int getDuration() { return duration; } public void setDuration(int duration) { this.duration = duration; } // toStingをオーバーライド public String toString(){ return "Song: " + name + "-" + artist + " (" + duration + ")"; } }
Rubyだとこんな感じ。
class Song attr_reader :name, :artist, :duration attr_writer :name, :artist, :duration def initialize(name, artist, duration) @name = name @artist = artist @duration = duration end #toStringにあたるメソッドをオーバーライド def to_s "Song: #{@name}-#{@artist} (#{@duration})" end end
長さが全然違う。。。getter/setterを書かなきゃいけないのもそうだけど、型の宣言をしないで済むので労力がまるで違う。というかJavaにeclipseのような強力なIDEが現れる訳がよくわかる。Javaは自力で書くにはめんどくさすぎる。とりあえずattr_readerとattr_writerがsetterとgetterに対応するのを覚えておこう。
ちなみに、":name"の":"は変数の名前そのものを指すそうだ。"name"だと値を刺すそうなので、Cのポインタで言うところの"&name"と"*name"みたいな感じかな?参照渡しと値渡しを区別出来るってことか。
追記
コメントを頂いて"attr_accessor"の存在を知りました!なるほど、一行だけで"attr_reader"と"attr_writer"を兼ねるわけですなー。これは知らなかった。。教えてくれた方、ありがとうございます!
というわけでRubyのソースはこんな感じに
class Song attr_accessor :name, :artist, :duration def initialize(name, artist, duration) @name = name @artist = artist @duration = duration end def to_s "Song: #{@name}-#{@artist} (#{@duration})" end end
うーん、ますます良い感じ。