初めてのRuby復習(3)

ローカル変数(p100)

ローカル変数はメソッド定義の def ... end を境界としてスコープが分離されます。

Rubyを使いはじめのころよくエラーになりました。

ローカル変数は最初の代入式によって発生します。

定数(p102)

Rubyの動的性質は定数への再代入を結局は許容します。

擬似変数(p103)

ファイルのトップレベルでは self は main と呼ばれる特殊な Object を参照しているらしい。

irb(main):024:0> self.class
=> Object
irb(main):025:0> self.object_id
=> 22412490
irb(main):026:0> self.inspect
=> "main"

再定義可能な演算子(p106)

  • 単項プラスと単項マイナスは +@, -@ メソッド。

自己代入演算子(p106)

対応する二項演算子を定義すると使えるようになる。
例).+(other) を定義すれば += も使える

多重代入(p108)

swapが簡単に書ける。確かLuaでもあったはず。

a, b = b, a

多値と配列展開(p108)

メソッド引数、戻り値での扱いとあわせて覚えておこう。

制御式(p113)

制御式も値を持つ。次のコードはRubyではよくあるとのこと。

result = if value == "ok" then
  "good"
else
  "bad"
end

case 比較演算子(p117)

case式の柔軟な挙動は、標準ライブラリが適切に===をオーバーライドすることで実現されているのです。

なるほど。

関数的メソッド(p127)

レシーバに含まれる情報を使わないので、レシーバによらず同じ挙動をするとういこと。

多値の返却(p130)

多値を戻すことは配列を戻すことと同義。

irb(main):044:0> def some
irb(main):045:1>   return 1, 2
irb(main):046:1> end
=> nil
irb(main):047:0> some
=> [1, 2]
irb(main):048:0> def other
irb(main):049:1>   return [1, 2]
irb(main):050:1> end
=> nil
irb(main):051:0> other
=> [1, 2]

クロージャーとしてのブロック(p135)

ブロックはクロージャーであり、ブロックの中のコードに現れる自由変数はブロックの外部環境に従います。

クロージャはなじみも薄く、これを使うイメージがもてない。ということは恐らく使わない予感。

ブロック引数とブロックローカル引数(p136)

  • ブロックは独自のローカル変数を持つことができる
  • ブロック引数はRuby1.8では変数への代入に近い
irb(main):059:0> a,b = 10, 20
=> [10, 20]
irb(main):060:0> [[1,2],[3,4]].each do |a, b|
irb(main):061:1*   p [a, b]
irb(main):062:1> end
[1, 2]
[3, 4]
=> [[1, 2], [3, 4]]
irb(main):064:0> a
=> 3
irb(main):065:0> b
=> 4

これよりは1.9の方がよさそう。

覚えておくべきことは次の2点とのこと。

  • 外部のローカル変数と同名のブロック引数を用いない
  • 外部で既出のローカル変数は、ブロック内外で共有される(クロージャー)

Proc(p140)

  • ブロック引数からProcは仮引数リストの最後に&をつけた引数を置く
  • Procを引数で渡すには &をつけた仮引数リストの最後に置く
irb(main):102:0> def make_proc(&block)
irb(main):103:1>   raise unless block
irb(main):104:1>   return block
irb(main):105:1> end
=> nil
irb(main):106:0> make_proc
RuntimeError:
        from (irb):103:in `make_proc'
        from (irb):106
        from ^C:0
irb(main):107:0> make_proc { |x| p x }
=> #<Proc:0x02a9bd50@(irb):107>
irb(main):113:0> proc = make_proc { |x| p x }
=> #<Proc:0x02b6874c@(irb):113>
irb(main):114:0> 10.times(&proc)
0
1
2
3
4
5
6
7
8
9
=> 10