パーフェクトRubyお勉強フェスティバル 第3章

oftonkingdom.hatenablog.com

こんにちは,おふとん王国の王です.(これを言いたいだけです.)

こつこつ勉強はしているのですが,ブログを書く時間がとれず一週間ぶりに… 社会人として時間の使い方をもう少しうまくできるようにしていきたいです.

さて,今日もフェスティバっていきますのでよろしくお願いします.

3章です.

演算子

&と&&とand,|と||とorの違いは?

調べました.優先順位が違う(高い順に&,&&,and |,||,or)ということと,「&」「|」はメソッドであるということがわかりました.

また,Javaでのそれと同様&&や||はショートサーキット演算子であり,左辺の値により演算結果が確定する場合は右辺の評価を行わない.

実際にプログラムを書いていくとして使い分ける自信がないですね…

d.hatena.ne.jp

improve-future.com

初見の演算子たち

  • <=> 左右の数を比較して大小関係により異なる結果を返す.例えば,
a<=>b

a < bなら-1,a == bなら0、a > b なら1、比較できないならnil をそれぞれ返す.

  • !~ 第2章のときに出てきた=~(正規表現にマッチすればtrueを返す)のと逆で,マッチしなかった場合にtrueを返す.

==と===とequal?の違い

まず,テキストでは「==」はほとんどのクラスで同値性を判断するメソッドとして定義されている.同値かどうかはクラスによって定義が異なるし,オーバーライドすることで「何を持って同値とするか」を定義できる.

また,同様テキストにおいて「equal?」は同一性(同じインスタンスであること)を確認するために使われるとあります.オブジェクトIDが同じならtrueを返す.メモリ空間上で同じアドレス上に存在するかということですね.

テキストには書いていませんが2章正規表現のところで出てきた「===」はじゃあ何なのだ?調べました.これは所属性を確認するためのもの. 右辺が左辺に含まれていればいい.よく使われるのは左辺が正規表現のときに右辺がマッチすれば「===」はtrueを返す.というものである.

私は知らなかったですがeql?もあるんですね…

Rubyにおける==と===とeql?とequal?の違いを今更 [俺の備忘録]

d.hatena.ne.jp

基本的な制御構造

case

あるケースにマッチした後は次のケースに処理が進んで行くわけではないため,breakは書かなくてよい.

human_status = 'nemui'

case human_status
when 'nemui'
  puts 'inside futon'
when 'nemukunai'
  puts 'out of futon'
else
  puts 'welcome to futon '
end

for

配列の要素を1つずつ取り出して処理をするには以下のようにする.

for animal in %w(ミミズ オケラ アメンボ)
  puts "#{animal}だって"
end

puts 'みんな みんな生きているんだ友だちなんだ'

同様にハッシュの取り出しも.

#配列の0番目要素にキー,1番目要素に値が入る
for val in {ofton: 'justice', omochi: 'umai'}
  puts "#{val[0]}#{val[1]}"
end

# oftonはjustice
# omochiはumai

#多重代入でキーと値を別々に取り出す
for key, val in {ofton: 'justice', omochi: 'umai'}
  puts "#{key}#{val}"
end

# oftonはjustice
# omochiはumai

無限ループはloopで書ける

loop do
  私は何度でも繰り返す
end

指定回数繰り返しはtimesメソッド

5.times do
  puts "こんにちは"
end

ジャンプ構文

ループを抜けるのはbreak,ループ内のそれ以降の処理をスキップして次のループ処理を行う場合はnext,ここまでは他の言語でも見たことあるのでわかるが,redoというのが面白い.

redoを呼び出すと,その繰り返しをやり直す. どんなときに使えるんだろう?調べました. ja.stackoverflow.com

ブロックは奥が深い

メソッドはブロック(処理のかたまりのようなもの)を受け取ることができる.

yield

メソッドの中でyieldが呼び出されたタイミングでブロックが実行される.

そもそも「yield」の意味には譲るとかゆだねる,などがありますね.

「yield」と書いた部分については,メソッド呼び出し時に与えられた処理にゆだねるよ!と覚えることにします.

def ofton
  puts "こんにちは"

  yield #ここで渡されたブロックの処理を実行!
  
  puts "さようなら"
end

ofton do
  puts "渡されるブロックの処理です"
end

#こんにちは
#渡されるブロックの処理です
#さようなら

この,「処理を渡す」って感覚,便利そうな予感がします.

繰り返し処理であるとか,基本は同じ処理をするんだけど時と場合によって違う処理をする箇所がある,みたいなときによく使われるらしいですが,プログラムの見通しがよくなりそうですね.

オブジェクトをブロックとして渡す

ブロックは「Procオブジェクト」に入れることで変数として扱える.で,メソッドに渡すときは,変数の頭に&を付けて渡せば,ブロックとして渡せる!

のであるが,Procオブジェクト以外もProcオブジェクトに変換した上で,ブロックとして渡せる.

で,ここで出てきた例で,:upcaseというシンボルのto_procメソッドを呼び出すとProcオブジェクトが返って,それをメソッドに渡して…という話がでてきたのですが,ちょっと難しかった.

シンボル出ましたね.前回よくわからなかったものです.

ref.xaio.jp

シンボルのto_procメソッドはまず上記のような働きをする,ということは理解.

それでもって,メソッド呼び出しの際に「&」を引数の頭につけると,to_procを呼び出した戻り値を渡すことになるよーと.

ofutons = %w(vocal guitar bass drums)
block = :upcase.to_proc

ofutons.map(&block) #=> ["VOCAL", "GUITAR", "BASS", "DRUMS"]

ofutons = %w(vocal guitar bass drums)

ofutons.map(&:upcase) #=> ["VOCAL", "GUITAR", "BASS", "DRUMS"]

は一緒!ということ!

まとめ

曲がりなりにも人様に見せる形で文章化すると,理解がはっきりしますね.

にしてもRuby,よくできていますね.