読者です 読者をやめる 読者になる 読者になる

せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】パーフェクトRuby 学習感想文 ~第3章

それでは3章を読んでいきます。

(参考・経緯など)
パーフェクトRuby 学習感想文 ~はじめに



P74 単項演算子の「+」、二項演算子の「+」

+@や-@は単項の+ と- で、+365のような式の演算子を指します

って。「+365のような式の演算子」といわれて果たして何割の人が理解できるんだ。

  1. 365 ←単項

1.+(1) ←二項

うーん、私は分かるけどね。。
大学の参考書(数学科)や、
誰も理解できないまま進んでいく授業などがふとよみがえりました。



 

P76 =~ って何?

if /darwin/ =~ RUBY_PLATFORM

 
ちなみにRUBY_PLATFORM って定数で、Rubyインタプリタが実行対象としている環境を取れるらしい。

irb(main):001:0> print RUBY_PLATFORM
i386-mingw32=> nil


なるほど。正規表現比較のときは「=~」なのですね。



 

P78 ===メソッドの挙動がオブジェクトによって違う

このあたり、Javaでequals()のメソッドを書いたことあるから分かるけど、
初見だときついだろうなあ。このあたりが↓

Range [動作]引数が自身の範囲内に含まれるなら真を返す

ここで言う「引数」ってつまり、=== の右辺、なんですが、
「=== はメソッド」といわれてピンと来る人間しか分からない気がする。
そして「=== はメソッド」といわれてピンと来る人間が前提とされている。。

まだ・・まだ負けない!



 

P80 なぞの「シンボル」

for key, val in {a: 1, b: 2}
	puts key # :a や :b などのキーを表示
	puts val
end

何故いきなり「:a」なんてシンボルなんですか先輩・・・。
実行してみた。

■hoge.rb

for key, val in {a: 1, b: 2}
	puts key
	puts val
end

■実行結果

a
1
b
2

ただの文字列だけど。ひょっとしてデバッグ用のp関数なら違うかも!再チャレンジ

■hoge.rb

for key, val in {a: 1, b: 2}
	p key
	p val
end

■実行結果

:a
1
:b
2

シンボルになってる!
しかし、シンボルってなんだ。変数名とはちょっと違うし。まだ分からない。



 

P82 「それ」を永遠に繰り返します。の「それ」って?

繰り返し構文の中でのnext redo の話。
実行コードは載っているものの、実行結果が載っていない!
初心者に優しくない(泣)

この実験台がやってみます。
変数名・文字列は一部簡略化しています。

■hoge1.rb

lans = %w(a b ruby c d)

lans.each do |lan|
	puts lan
	next unless lan == 'ruby'
	
	puts 'found ruby!'
end


■実行結果

a
b
ruby
found ruby!
c
d


■hoge2.rb

lans = %w(a b ruby c d)

lans.each do |lan|
	puts lan
	if lan == 'ruby'
		puts 'found ruby!'
		redo
	end
end


■実行結果

a
b
ruby
found ruby!
ruby
found ruby!
ruby
found ruby!
ruby ・・・

予想通りだったけれども、やっぱりこういう結果は載せてくれたほうが安心感がありますね。



 

P89 「リトライ」は4回では?

確かに5回、puts文が実行されているけど、1回目は正常フローであり、
リトライは4回ではないか?

■hoge3.rb

begin
	failed ||= 0
	puts 'trying...'
	
	raise StandardError
rescue
	failed += 1
	
	retry if failed < 5
end


■実行結果

trying...
trying...
trying...
trying...
trying...

 

P97 ブロックの中でのnext

Rubyといえばブロック。ブロックといえばRuby(かな)。

このあたりから一気に難しくなってきます。

ブロックの中でnext を呼び出すと処理は「yieldの呼び出し元」に戻ります。

って、、載っている例が「nextあるとき」「nextないとき」で全く挙動が同じで
理解の助けにならないよ!
しょうがないので自作

■hoge4.rb

def display_value
	puts yield
end

display_value do
	4423
	"hoge"
end


■実行結果

hoge  #最期に評価された式の値が返るから

■hoge4.rb

def display_value
	puts yield
end

display_value do
	next 4423
	"hoge"
end


■実行結果

4423

たしかに、next 以降の行は実行されていない。



 

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

すみません。正直に告白すると、
このP100を理解するのに30分以上かかりました。
っていうのも、これ、説明とサンプルがごっちゃになってて(ということに気づくまでに30分かかった)混乱するのです。。

======(以下引用)========================

さらにProcオブジェクト以外の実引数にも&をつけることが出来ます(文1)。
その場合は、引数に対してto_procメソッドを呼び出した結果がメソッドに渡されます(文2)。
例えば:upcase のようなシンボルに対して呼び出したto_pocは
「Proc.new{|val| val.upcase}」と同じ動きをするProcオブジェクトを返します(文3)。
それぞれを比較してみましょう(文4)。

 
コードA

p1 = Proc.new{|val| val.upcase}
p2 = :upcase.to_proc

p1.call('hi')  ←"HI"
p2.call('hi')  ←"HI"

  

Array#map はeachと同様に配列の要素を繰り返すメソッドですが・・・(文5)。
以下のように、すでにある配列から新しい配列を作る際によく利用されます(文6)。

 
コードB

people = %w(alice bob tom)
people.map{|person| person,upcase} ←["ALICE","BOB","TOM"]

  

上記のような処理は、Symbol#to_proc を用いて以下のように記述できます。(文7)

 
コードC

people.map(&:upcase)  ←["ALICE","BOB","TOM"]


こんなふうに、コードと説明が交互にあります。
分からなかったのは、例えばこういう感じ
「え?文7には”to_proc”を使うとあるけど、コードCでは使ってなくない??」
「文1には”&”を使うとあるけど、コードAでは使ってなくない?」


文1と文2は、コードCでの説明だったんですね。
ここまでは、ごく自然に、説明とコードが1対1対応していたのですが、
ここにきて混ざってしまった感があります。

ハードル高いです!!!


結局自分が学習したのは引数に&:メソッド名、があったら気をつけようって程度ですかね。。。
理解に行くまでに、燃え尽きました。


 

P108 組み込み関数の説明が!

ようやく、組み込み、についての説明が出てきた。
なるほど。 例えば、Kernel.#gets っていうのは、スクリプトの中で直接getsを実行できる(レシーバーがいらない)ってことか。


ここまで一日(4時間ほど)で読みました。