好き勝手に・げーあにん?

ファミコンと同い年の社会人ヌルオタの日記

『プログラミング言語 Ruby』読みおわた

プログラミング言語 Ruby

プログラミング言語 Ruby

Rubyを学ぶすべての人におくるRuby解説書の決定版である。

決定版である。心の底から納得したので背表紙の文の引用も含めて二回言いました。


知らなかったことが多すぎて涙目になりながら読了。

以下、読みながらメモっていた文を垂れ流し。主に、私の身についていないとこを思い出すためのメモなので、解説とかはしてません。わからないところがあったら、本を買えばいいと思うよ。

P.35

1.9 からピリオドが先頭だったら〜っての知らんかった。

puts []
  .push(6)
  .push(3)
  .push(4)
  .sort

ピリオド"だけ"特別ってのがキモイ気もするけど、ちょっと嬉しい。

P.53

puts 'インタプリタで'\
  '連結される'

puts %q(((括弧)などの(ペア)の対応が取れていれば))
puts %Q<<エスケープが><いらない>>
puts %Q[[対応してないのは\[エスケープ][必要]]

P.54

ヒアドキュメントよくわかってなかったorz

puts <<HERE + <<THERE + "World"
Hello
HERE
There
THERE

説明を読んでも出力が想像できんかったよorz

puts <<'たぬき'.delete('')
たアたイたマたスたがたすたきたでたすた
たぬき

文字列としての扱われかたもイマイチわかってなくて、メソッド呼ぶ時とか、いちいち変数に入れてたけど、これで良かったのね。文字列での終端指定も見慣れないのでついでに。

P.58

String#<< は数値を渡せるのも知らんかったけど、これはキモイな。なんか Ruby らしくない(主観)。

p 'A'<<66 #=> "AB"
p 'A'+66 # これは TypeError

P.104

左辺の括弧も使ったこと無かったのに、メソッド呼び出しが絡むと、もう何がなにやら。あとで理屈を読みなおす。

p ((x,y,z = 1,[2,3]))
p x,y,z
p ((x,(y,z) = 1,[2,3]))
p x,y,z

P.117

defined? の戻り値を意識したことが無かった。

def hoge; end
p defined? hoge #=> "method"

class Hoge; end
p defined? Hoge #=> "constant"

huga = ->{}
p defined? huga #=> "local-variable"

かっこいいなコレ。真偽値としてしか使わないけど(えー)。

P.140

自分で include Enumerable してる class を書くときの each も、 block が無いときは to_enum を返すようにした方がいいのかなー、と思った。

class EnumSample
  include Enumerable

  def each()
    return to_enum unless block_given? # これがあると嬉しいんじゃないかという話し
    0.upto(2) do |i|
      yield i
    end
  end
end

e = EnumSample.new
# e.to_enum を呼べばいいだけ何だけど、Array#each とかにあわせたくない?
p e.each #=> #<Enumerator:0xb98d18>

e.each do |i|
  puts i
end

P.149

1.9 から。ブロック内ローカル変数。

3.times do |x;y|
end

便‥‥利?

P.167

rescue 内で retry 書くとそんなんできるのか。知らんかったorz

P.171

BEGIN{} と END{} 使ったこと無い。

P.178

Continuation。コアライブラリから、標準ライブラリになった。Fiber を使って書きなおせないかを検討すべき。‥‥らしい。

P.191

1.9 からのデフォルト引数でこんな書き方できるようになった

def hoge(x, y = 1, z = 2, w)
  p x,y,z,w
end

‥‥どんな時に嬉しいんだこれ。他の機能拡張との関連での規制緩和

P.193

1.9 で enumratorも * で引数に展開できるようになった。これは便利! でも、意外と使う場面無い!(えー)

def hoge(x,y,z)
  p x,y,z
end

hoge(*3.times)

P.199

Proc.new のブロックをつけなかった時の挙動。
invoke1 と invoke2 は同じ意味。

def invoke1(&b)
  b.call
end

def invoke2
  Proc.new.call
end

invoke1 {p 'invoke1'}
invoke2 {p 'invoke2'}

P.201

従来のブロックベースのlambda作成メソッドと比べて、この新しいlambda構文が優れている部分の1つは、メソッドと同じようにデフォルト宣言ができるところである。

そうだったのか! キモイだけじゃなかったんだね!(コラ

p ->(x,y=2){x+y}.call(1)
p lambda {|x,y=2|x+y}.call(1)

‥‥あ、あれ? 今までの lambda の書き方でも動いてるよ? 1.8 ではダメだけど。

しかし、見慣れると短くかけるし、なんか可愛く見えてくるから困る。

P.202

Proc#call を .() でも呼べるようになった。演算子じゃなくて糖衣構文らしい。カリー化便利なのでついでに試す。

f = ->(x,y,z){p x+y+z}
f.call(1,2,3)
f[4,5,6]
f.(7,8,9)

f2 = f.curry[10,11]
f2.(12)

P.204

Proc.new と lambda の違い。まったく意識せずに使ってましたorz

def hoge
  p lambda {return 'lambda'}.call #=> "lambda"
  p Proc.new {return 'proc'}.call # p が呼ばれずにメソッドから抜ける
  raise 'ここにはこない'
end

puts hoge #=> proc

これ知らないで今まで lambda 使ってたのか‥‥恐ろしい‥‥。と、思ったら古いドキュメントに lambda と proc が Proc.new と同じ、みたいな記述があったから、たぶんこれを読んだんだな‥‥(責任転嫁)。新しい方には細かい説明がちゃんと書いてある。るりま++

Proc.new と lambda での動作の違いメモ。

return 違う
break 違う
next 同じ
redo 同じ
retry Proc の中では使えない(LocalJumpError)

P.210

なんかサラリと、脚注の監訳者注に本文否定が入ってること多いよね。否定というか、本文も直そうよ、というか。なんとなく事情もわかるんだけど、本文読んだあと、脚注見て「えー」って思うことがたまにある本だなぁ。妙に印象に残るからいいけど。‥‥ここまでが計算どおりなんですね。わかります。

P.212

UnboundMethod 使ったことなかったのでメモ。method とか send の方が使い慣れてるから、使うことなさそうな気もしつつ。

unbound_method = Fixnum.instance_method(:-)
p unbound_method.bind(2).call(4) #=> -2

symbol_method = :-
p 2.method(symbol_method).call(4) #=> -2
p 2.send(symbol_method, 4) #=> -2

P.268

autoload 知らんかったorz

autoload :TCPSocket, "socket"

Exerb の mkexy とかどうなるんだろ。あとで。

P.331

名前付きキャプチャを含む正規表現正規表現が =~ 演算子の左辺にある時だけで、右辺に正規表現じゃダメなのね。

if /^(?<year>\d{4})-(?<mon>\d{2})-(?<day>\d{2})/ =~ Time.now.to_s
  # 1.9 で Time#to_s の形式変わったのね
  puts "#{year}/#{mon}/#{day}" #=> 2009/01/28
end

P.349

Array#sort_by とか Array#max_by 便利だなー。よく使いすぎる。本だと 1.9 のみと書いてあるけど、この手の言語拡張が関係ないメソッドは 1.8.7 なら割と入ってるんですよね。たぶん。

p <<EOS.each_line.to_a.max_by {|a| a.length}
YAYOI
CHIHAYA
HARUKA
EOS

P.417

TRUE / FALSE ってまだ無くなってなかったのか。

あとで

  • Dir とか File の encoding まわりをあとで試す。主に Windows