投稿目的
- 個人の学習目的で投稿していきます。
- Rubyの入門を読みながら自分なりの思考で記述しています。
参考資料
ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)
クラスの高度な話
インスタンス変数を簡略的に定義
class Greeting # Greetingクラス定義
def morning # morningメソッド定義
@morning # morningインスタンス変数定義
end
def morning=(text) # morning=メソッドに引数1つ定義
@morning = text # 受け取った引数をインスタンス変数に代入
end
end
greeting = Greeting.new # インスタンス作成
greeting.morning = "おはようございます" # morning=メソッドを呼び出し
puts greeting.morning # morningメソッドを呼び出し
# 結果: おはようございます
- 下記のように記述することでインスタンス変数を簡略的にすることが可能です。
attr_readerメソッド
- 上記のGreetingクラスに追加すると下記のようになります。
- attr_readerメソッドは同名のインスランス変数を戻り値とするメソッドを定義します。
class Greeting
attr_reader :morning # 戻り値が同名のインスタンス変数のメソッドを定義
def morning=(text)
@morning = text
end
end
greeting = Greeting.new
greeting.morning = "おはよう"
puts greeting.morning
# 結果: おはよう
attr_writerメソッド
- attr_writerメソッドを利用することで引数を受け取って同名のインスタンス変数に代入するメソッドを簡略的に定義することができます。
class Greeting
attr_reader :morning
attr_writer :morning # 同名のインスタンス変数に引数を受け取り代入するメソッドを定義
end
greeting = Greeting.new
greeting.morning = "おはよう!!"
puts greeting.morning
# 結果: おはよう!!
attr_accessorメソッド
- さらに上記の2つはセットで利用することが多いのでその2つの機能を持つメソッドがattr_accessorメソッドです。
class Greeting
# 同名のインスタンス変数に代入、戻り値が同名のインスタンス変数
attr_accessor :morning
end
greeting = Greeting.new
greeting.morning = "Good morning"
puts greeting.morning
# 結果: Good morning
self
- selfは自分自身(レシーバ)を指している。
- メソッド内でselfを指定すると返ってくるオブジェクトはインスタンスメソッドならクラスのインスタンス、クラスメソッドならクラスのように自分自身を指している。
インスタンスメソッド
class Greeting
def me # インスタンスメソッドを定義
self.morning # インスタンスメソッドなのでクラスのインスタンスを指している
end
def morning # インスタンスメソッドを定義
puts "おはよう"
end
end
greeting = Greeting.new
greeting.me # 結果: おはよう
クラスメソッド
- クラスメソッドの場合はメソッド名の前にselfを付ける必要がある。
class Greeting
def self.me # クラスメソッドを定義
self.morning # クラスメソッドなのでクラス自身を指している
end
def self.morning #クラスメソッドを定義
puts "おはよう"
end
end
Greeting.me # 結果: おはよう
- 自分自身のメソッドを呼び出すのにself(レシーバ)と付けるのは手間なのでself(レシーバ)指定を省略することができる。
class Greeting
def me
morning
end
def morning
puts "おはよう"
end
end
greeting = Greeting.new
greeting.me # 結果: おはよう
インスタンスメソッドとクラスメソッドが持つインスタンス変数は別物
- インスタンス変数の持ち主はselfが指すオブジェクトです。
- クラスにインスタンスとクラスはオブジェクトが違うのでインスタンス変数の持ち主も別々になります。
class Greeting
def morning # インスタンスメソッドを定義
@morning = "おはよう" # インスタンスメソッドのインスタンス変数に代入
end
def self.morning # クラスメソッドを定義
@morning # クラスメソッドのインスタンス変数が戻り値で返る
end
end
greeting = Greeting.new
greeting.morning # インスタンスメソッドのmorningを呼び出し
p Greeting.morning # クラスメソッドのmorningを呼び出し
# 結果: nil
クラス変数
- インスタンス変数、ローカル変数の他にクラス変数が存在します。
- クラス変数は変数名の前に@@を付けることで定義できます。
- クラス変数はクラスを継承した先でも利用することができる。
class GreetingA
@@morning = "おはよう" # クラス変数に代入
def morning
@@morning
end
end
greetingA = GreetingA.new
puts greetingA.morning # 結果: おはよう
class GreetingB < GreetingA # GreetingAのクラスをGreetingBに継承
def morning
@@morning # greetingAのクラス変数を利用
end
end
greetingB = GreetingB.new
puts greetingB.morning # 結果: おはよう
文字列を調べる正規表現
文字列を含むかを判定
- match?メソッドを利用することで特定の文字列を含んでいるかが判定できます。
- match?の引数にパターンを渡すことで含むかを判定できます。
- /で囲むことで正規表現(Regexp)オブジェクトとなりこれをパターンと呼びます。
- 下記はフルーツと文字が含むものがtrueとなります。
p "グレープフルーツ".match?(/フルーツ/) # true
p "りんご".match?(/フルーツ/) # false
p "ドラゴンフルーツ".match?(/フルーツ/) # true
その他の正規表現
- \zを加えることで末尾に指定された文字が含まれているかを判定します。
- \Aを加えることで先頭に指定された文字が含まれているかを判定します。
p "グレープフルーツ".match?(/フルーツ\z/) # true
p "フルーツレモン".match?(/\Aフルーツ/) # true
- よく使われる正規表現.
- []で囲むと中の1文字どれかが含まれているかを判定します。
/[abc]/ # aかbかcが含まれていればtrue
- []の中に範囲指定で記述して判定することもできます。
- アルファベットの大文字か小文字、数字のいずれか1文字が含まれているかを判定します。
p "りんごv".match?(/[A-Za-z0-9]/) # true
p "りんご5".match?(/[A-Za-z0-9]/) # true
p "a0b".match?(/a.b/) # true
p "agb".match?(/a.b/) # true
- *は前の文字が0回以上繰り返すかどうかを判定します。
p "abc".match?(/ab*c/) # true
p "c".match?(/ab*c/) # false
p "aaac".match?(/ab*c/) # true
p "ac".match?(/ab+c/) # false
p "abc".match?(/ab+c/) # true
p "bbc".match?(/ab+c/) # false
条件と一致する文字を置換
- gsubメソッドを利用することで文字の置換をすることができます。
- 第1引数が置換元で第2引数が置換先になります。
p "フルーツオレ".gsub("フルーツ", "カフェ") # カフェオレ
p "グレープフルーツサワー".gsub("サワー", "ジュース") # グレープフルーツジュース
p "フルーツフルーツ".gsub(/\Aフルーツ/, "ミックス") # フルーツミックス
正規表現とif文
- 正規表現を利用してif文で分岐することができます。
- 下記のプログラムはフルーツと含まれているものだけを表示する条件です。
["バナナジュース", "グレープフルーツサワー", "フルーツオレ"].each do |drink|
puts drink if drink.match?(/フルーツ/)
end
# 結果: グレープフルーツサワー フルーツオレ
ブロックの高度な話
- eachメソッドなどを使用する際にdoからendをブロックと呼びます。
- ブロックとはプログラムのかたまりをメソッドへと渡すことができる仕組みです。
- ブロックは引数と似ています引数はオブジェクトを渡してブロックは処理のかたまりを渡すイメージです。
- ブロックは1つしか渡すことができません。
渡されたブロックを実行
- block_given?メソッドを利用することでブロックが渡されたどうかを判別してくれます。
def foo
p block_given
end
foo #=> false
foo do
end #=> true
- 渡されたブロックを実行するにはyieldを利用します。
def dice
if block_given? # ブロックの有無を判別
puts "run block"
yield # 渡されたブロックを実行
else # ブロックが渡されていない場合の処理
puts "normal dice"
puts [1, 2, 3 , 4, 5, 6].sample
end
end
dice # 結果: ブロックを渡していないので1~6をランラムで表示
dice do # ブロックが渡されたのでブロックの処理を実行
puts [4, 5, 6].sample # 結果: 4~6をランダムに表示
end
渡されたブロックを引数で受け取る
- 引数にブロックを渡す際は変数名の前に&を付けることで受け取ることができます。
- callメソッドで変数に代入されたブロックを実行することができる。
- 変数に代入されているブロックをprocオブジェクトと呼びます、プログラムの処理もオブジェクトとして扱うことができます。
def foo(&greeting) # &でブロックを受け取る
greeting.call # 代入されたブロックを実行
end
foo do
puts "おはようございます!"
end
# 結果: おはようございます!
ゼロからわかるRuby超入門の教本は終了です。