恥ずかしながら文法から

やっぱ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を書かなきゃいけないのもそうだけど、型の宣言をしないで済むので労力がまるで違う。というかJavaeclipseのような強力な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

うーん、ますます良い感じ。