Ruby超入門 2周目 CHAPTER11-4 ブロックの高度な話 まで

 

f:id:kkouji0224:20191027224451p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

昨日も寝まくりで暖房つけて寝たら石ころみたいなカッチカチの目ヤニができてたよ。こんにちは。koujiです。

 

あー!!あーあーあー!!超入門が終わっちゃうよー!!この気持ちは面白い小説とか映画が終わっちゃう感じに似てるな… 入門書でもこういう気分にさせられるんだからすごいね。世界観のある入門書ってなかなか書けないのではないでしょうか…

 

ってことで気持ちを切り替えて今日も振り返っていきまーっす!

 

インスタンス変数を簡単に操作しようぜ!!

 

class Alc
  def name
    @name
  end
  def name=(text)
    @name = text
  end
end

alc = Alc.new
p alc.name

 

vscodeから今までコピペでインデントまで反映されてたんだけど、知らぬ間に反映されなくなっちゃったからインデントなしで見難いけどすまんねっ!

 

インスタンス変数の取得と代入は今まではこんな感じで書いてきたよね。

 

attr_accesser

 

class Alc
  attr_accessor :name
end

alc = Alc.new
p alc.name

 

こんなに省略して書けちゃう… attr_accesserメソッドは「同名のインスタンス変数を戻り値とするメソッドを定義する」と「同名のインスンタンス変数へ代入するメソッドを定義する」の2つのことをやってくれちゃうメソッド!!めっちゃ便利!

 
いきなりattr_accessorから書いてみたんだけど、attr_readerとattr_writerってのもあるんだよね。
 
上にも書いたとおり、attr_accessorは両方やってくれる。
 
attr_readerは「同名のインスタンス変数を戻り値とするメソッドを定義する」
attr_writerは「同名のインスンタンス変数へ代入するメソッドを定義する」
 
class Alc
  attr_reader :name
  def name=(text)
    @name = text
  end
end

alc = Alc.new
p alc.name

 

まずattr_readerね。

def name

  @name

end

これと同じことをやってくれてるんだね。

 

class Alc
  attr_reader :name
  attr_writer :name
end

alc = Alc.new
p alc.name

 

次はattr_writerね。

def name(text)

  @name = text

end

これと同じことをやってくれるんだよ!

 

で、両方やってくれちゃうのがさっきかいたattr_accessorだぜ!

 

selfを観察!!

 

class Alc
  def me
    p self.object_id
  end
end

alc = Alc.new
p alc.object_id
alc.me

 

selfはその場所でのレシーバを返すもの!ってことでクラスのインスタンスメソッドの中でselfを呼び出すと何が返ってくるのか…?上のプログラムを実行すると下のオブジェクトIDになるね。

 

47367875712620
47367875712620

 

インスタンスメソッドmeの番号と、Alc.newで作ったオブジェクトのIDと一致してる!

なので、クラスのインスタンスメソッドの中でのselfはそのメソッドを読んだ時のレシーバと同じってことだね!

 

じゃークラスメソッドのselfはどうなるのか?

 

class Alc
  def self.me
    p self.object_id
  end
end

p Alc.object_id
Alc.me

 

結果はこんな感じ

 

47101248501500
47101248501500

 

やっぱり同じだね。なので、クラスメソッドのselfは、そのメソッドを読んだ時のレシーバと同じになるんだぜ!

 

クラスメソッドとインスタンスメソッドのインスタンス変数は別だよ!

 

class Alc
  def name
    @name = "焼酎"
  end
  def self.name
    @name = "ウォッカ"
  end
end

alc = Alc.new
puts alc.name
puts Alc.name

 

alc.name は焼酎

Alc.nameはウォッカ

 

インスタンスオブジェクトが持ってるインスタンス変数と、クラスがもつインスタンス変数って感じだね!ややこしくなくていたってシンプル!!

 

ちなみにクラス変数ってものもあって@@nameみたいに@を2つ。これはクラスで共有できるんだけど、継承したクラスでも共有するんだってよっ!

 

正規表現

 

kanagawa = ["横浜市", "川崎市", "相模原市", "大和市"]

kanagawa.each do |city|
  puts city if city.match?(/大和市/)
end

 

正規表現ってのは特定の文字列を含んでいるかを調べるのに便利!

/大和市/は正規表現オブジェクトっていうらしくスラッシュで囲んであげると正規表現オブジェクトになって、これを「パターン」というんだぜ。

 

上のプログラムは配列kanagawaを.each使って1つづつcityに代入して、後置ifでmatch?メソッドで、正規表現の/大和市/が含まれてたらputs cityって感じだね。

 

正規表現はそれだけで1冊本が書けるぐらいのものらしい。きっと奥が深いのだろう…沼の予感がする… 

 

他にも/[A-Za-z0-9]/みたいな感じで範囲指定で書けたり、/a.c/みたいな任意の1文字だったり、と色々あるみたいなので、正規表現に絞って学ぶってのをやってみるのも面白いかもしれないね… 沼な予感するけどね…

 

 

ブロックを渡す

 

def alc
  if block_given?
    puts "英語バージョン"
    yield
  else
    puts "日本語バージョン"
    puts ["焼酎", "ビール", "ハイボール", "ワイン", "日本酒"].sample
  end
end

alc do
  puts ["beer", "shochu", "highball", "wine", "sake"].sample
end

 

実はブロックってメソッドに渡せるんだよっ!!これは面白いね!上のプログラムの場合はif block_given?でblock_given?メソッドってのでブロックが渡された場合はtrue、渡されて内場合はfalseになるので、trueの場合はifでputsとyieldが実行されるね。この

yieldを使うとメソッドの中で実行する処理を、呼び出し元でブロックで書くことができちゃうんだね!

 

ブロックを引数でうけとる!

 

def alc(&b)
  b.call
end

alc do
puts "生ビールは最高だ!"
end

 

ブロックは変数に代入できちゃう!このときのブロックをProcってオブジェクトとして扱われるんだね。Procオブジェクトはブロックの処理をオブジェクト化したもの。で、このプログラムだとalc(&b)って書いてあるけど、&を引数の前に書いてあげるとブロックを受け取れるようになる。で、bに代入してcallメソッドで実行するって感じ。これも面白いねー!なにがどう面白いのか説明できないけど面白いんだよ!

 

うおーーー!!終わってしまった!!超入門の振り返りが終わってしまった−−−!!

 

すごく楽しみながら振り返ることができた… ここまで面白いなぁーと思ってブログまで書いてみたのは初めてだったんだけど、楽しい物語が終わってしまう気分だ…

 

楽しかった。あとで振り返りのまとめも書いてみよう。

 

ということでRuby超入門の振り返りはここまでっ!!

 

素晴らしい時間でした!著者の五十嵐さんもTwitterでいいねくれたり、はてなの星くれたりと嬉しかったです!ありがとうございました!

 

ってことで超入門の振り返りはこれで終わりますが、まだまだこの道は続いていくぜー!!さーて次はなにをやろうかなっ!!

 

ってことで一旦このへんで!

 

アディオス!