かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Ruby勉強二日目

実際二日目じゃないけど、ここに記述するのは二日目ってことで!!!

クラスの定義

オブジェクト指向言語といえばクラスでしょう。
これが無きゃはじまらない!!!

定義は

class 名前
  ここに色々
end

でいける!
早速!!!

サンプル クラスの定義
# クラス作るぜ
class Hoge
	def foo
		puts "Hoge#foo"
	end
end

# クラス使うぜ
hoge = Hoge.new # インスタンス化
hoge.foo        # 定義したメソッド呼び出し
実行結果
Hoge#foo


予想通り。
インスタンス変数は、どうなってるんだろう?と思ったら@をつけたらいいらしい。
早速!!!
ついでだしコンストラクタも使うサンプルにしてしまおう。
initializeっていう名前のメソッドがコンストラクタのようだ。
引数も指定し放題?
デフォルトの値も設定できるようだ。C++みたい。

サンプル (コンストラクタ、フィールド)
# 人!
class Person
	# コンストラクタ! 引数に名前を受け取る!デフォはTarouさん
	def initialize name = "Tarou"
		@name = name # @つきがフィールド
	end
	
	# 挨拶くらいしなさいということで
	def greet
		puts "Hello!! My name is #{@name}."
	end
end

# デフォの名前
tarou = Person.new
# 明示的に名前を指定する
jirou = Person.new "Jirou"

# 後は太郎と二郎に挨拶させる
tarou.greet
jirou.greet
実行結果
Hello!! My name is Tarou.
Hello!! My name is Jirou.


無問題。
こうやって作ったフィールドって外からアクセスできるのかな?
やってみよう。
さっきのコードの後に次の文を加えて実行をしてみた。

tarou.name = "Saburou"
tarou.greet

結果は、エラー。

D:/iyan/rb140.tmp:35: undefined method `name=' for #<Person:0x2940000 @name="Tarou"> (NoMethodError)


そんなメソッドは無いか…。
じゃぁ@つければいいのか?ということでこうしてみた。

tarou.@name = "Saburou"
tarou.greet

結果は、エラー。

D:/iyan/rb140.tmp:35: parse error, unexpected tIVAR
tarou.@name = "Saburou"


文法すらあってないようだ。普通の状態じゃアクセスできないのね。
カプセル化ってやつか!!!


次。
こういうときに、外からアクセスしたいフィールドもあるよね。
そんな時の書き方が載ってた。

def なんとか=(arg)
  @なんとか = arg
end

みたいにすれば、外から代入できるみたい

def なんとか()
  return @なんとか
end

これで外から取得できるらしい。
Javaでいうところのgetter/setterってところですな。

早速!!

サンプル(getter/setter)
# 人!
class Person
	# コンストラクタ! 引数に名前を受け取る!デフォはTarouさん
	def initialize name = "Tarou"
		@name = name # @つきがフィールド
	end
	
	# 挨拶くらいしなさいということで
	def greet
		puts "Hello!! My name is #{@name}."
	end
	
	# 名前は自由にお使いください
	# getter
	def name=(name)
		@name = name
	end
	
	# setter
	def name()
		return @name
	end
end

# デフォの名前
tarou = Person.new
# 明示的に名前を指定する
jirou = Person.new "Jirou"

# 後は太郎と二郎に挨拶させる
tarou.greet
jirou.greet

# name=メソッドで名前書き換え
tarou.name = "Saburou"
tarou.greet
# nameメソッドで名前取得
puts tarou.name
実行結果
Hello!! My name is Tarou.
Hello!! My name is Jirou.
Hello!! My name is Saburou.
Saburou


名前がちゃんと書き換わってる。やりたいことが出来た。
でも、いちいち書くのめんどくさいだろ?っていうことで略記法が用意されてるらしい。

attr_accessor :名前

これでOKだとか。ラクチン。
さっきのPersonクラスをこれを使って書き換えると

# 人!
class Person
	# コンストラクタ! 引数に名前を受け取る!デフォはTarouさん
	def initialize name = "Tarou"
		@name = name # @つきがフィールド
	end
	
	# 挨拶くらいしなさいということで
	def greet
		puts "Hello!! My name is #{@name}."
	end
	
	# 名前は自由にお使いください
	# getter
	# def name=(name)
	# 	@name = name
	# end
	# setter
	#def name()
	#	return @name
	#end
	attr_accessor :name
end


スッキリ。
読み取り専用、書き込み専用の略記法もある。

読み取り専用 attr_reader :hoge
書き込み専用 attr_writer :hoge
両方 attr_accessor :hoge


用途に応じて使い分けてください。

継承

ついに継承。
といってもそんなに書くことは無い。
継承の仕方は

class クラス名 < 親クラス名
end

以上!!


簡単なサンプルだけでお茶をにごす。

サンプル(継承)
# 本当に普通の人なんです。
class Man
    attr_accessor :name
    
    def initialize name = "Tarou"
        @name = name
    end
    
    # 挨拶は大事
    def greet
        puts "こんにちは。私の名前は#{@name}です。"
    end
    
    # 謙虚さも大事
    def talk
        puts "私は普通の人ですよ."
    end
end

# あの人なんです。でも所詮普通の人が元なんです。
class SuperMan < Man
    # でも、しゃべることは凄いんです。
    def talk
        puts "私は凄い人ですよ."
    end
end

# 普通の人お願い!
man = Man.new
man.greet
man.talk

# スーパーマンお願い!
super_man = SuperMan.new
super_man.greet
super_man.talk
実行結果
こんにちは。私の名前はTarouです。
私は普通の人ですよ.
こんにちは。私の名前はTarouです。
私は凄い人ですよ.


同じTarouさんとは思えないくらい自信満々になっちゃいました。
継承することで、自信の無い部分を自信満々に置き換えちゃったんですね。


今日はここまで!!
次は正規表現かな〜?