ruby基本クラスの作成

3147 ワード

ルビーは文法が多いので、見ても忘れられないし、見られる時間も多くないので、少しずつ自分のブログに書き込んで印象を深めてみましょう.
基本的なクラスのフォーマットは次のとおりです.

class Point
    def initialize(x,y)
         @x,@y=x,y
    end
    def x
        @x
    end
    def y
        @y
    end
    def x=(value)
        @x=value
    end
    def y=(value)
        @y=value
    end
    def to_s
        "(#@x,#@y)"
    end
end

このクラスのメソッド呼び出しも簡単です.

p=Point.new(1,2)
p.x=3
p.y=4
print p

実際には、上記のクラスはもっと簡単に定義できます.

class Point
    def initialize(x,y)
         @x,@y=x,y
    end
    #attr_accessor :x,:y
    attr_reader :x,:y
    attr_writer :x,:y
    def to_s
        "(#@x,#@y)"
    end
end

上のattr_readerとattr_writerを統合すると、コメントされた行のコードattrになります.accessor.
ポイントには、次のような操作方法を追加することもできます.

...
    def +(other)
      Point.new(@x+other.x,@y+other.y)
    end
..

rubyでは、すべてのインスタンス変数がselfを暗黙的に使用する、selfを使用する場合はselfを使用することができる.x.上記のコードから分かるように,otherオブジェクトがx,y変数のアクセス方法を持っていればよいが,必ずしもPointオブジェクトである必要はない.これが「Duck typing」方式であり,アヒルのように見える限りアヒルとして扱う.
equを上書きするのも簡単ですが、いくつかの方法があります.==方法を書くこともできます.

   def ==(o)
      if o.is_a?(Point)
        @x==o.x&&@y==o.y
      elsif
          false
      end
    end
    alias eql? ==

最後の行のコードはeqlを==処理として表す.
もちろんrubyには、インスタンスメソッドであるキーワードprivate、protected、publicもあります.
1.宣言がない場合、デフォルトはpublic
2.initializeメソッドはprivate
3.privateメソッドは暗黙的な呼び出ししかできず、o.mまたはselfは使用できない.mが呼び出す
4.privateはクラスまたはそのサブクラスのインスタンスメソッドによってのみ呼び出されます.
5.protectedは、クラスまたはそのサブクラスのインスタンスメソッドによって呼び出されるほか、クラスのインスタンスによって表示される呼び出しであってもよいが、クラスのユーザはこれらのメソッドにアクセスできない.
使い方は簡単です.

    def +(other)
      Point.new(@x+other.x,@y+other.y)
    end
    def -(other)
      Point.new(@x-other.x,@y-other.y)
    end
    private :-,:+
.........

クラスメソッドを定義するのも少し意味がありますが、クラスメソッドはjavaのstaticメソッドに相当し、定義の方法は大きく2つあります.

....
    def self.sum(*points)
      x=y=0
      points.each{|p| x+=p.x;y+=p.y}
      Point.new(x,y)
    end
...

そのselfは現在のクラス名で代用できます.もう1つは、複数のクラスメソッドを容易に定義するためです.

  class << self
    def sum(*points)
      x=y=0
      points.each{|p| x+=p.x;y+=p.y}
      Point.new(x,y)
    end
  end
......

これはかなりjavaにとって、実は悪くなくて、ただ少し面白いと感じました.
定数名は大文字で、クラスの内外で定義でき、内部で直接アクセスでき、外部では「クラス名::定数名」でアクセスする必要があります.次のようになります.

...
UNIT_X=Point.new(1,0)
UNIT_Y=Point.new(0,1)
...

Point::UNIT_X+Point::UNIT_Y

Javaコードに比べて、確かに簡素化されていますが、正直、javaコードを書くのは少しも優美感がありません.rubyコードを書くのは少し楽しみです.