参考書読んで覚えたこと雑記
- rescue HogeError で、HogeErrorクラスを継承しているクラスの例外ならそれもキャッチされる。(よく考えたらrescue Exceptionが全部拾うなぁ)
- コマンドラインオプション
- 有効な環境変数
- RUBYOPT:デフォルトで指定するコマンドラインオプション、RUBYLIB:デフォルトライブラリ検索パス
- メソッドの中から外側のローカル変数は参照できない
- 親クラス名の取得は、obj.class.superclass
- %と%Qは同義(ダブルクオート扱い)。
- 文字列の%演算子はsprintfと同じ意味になる。
- "%02d" % 1 #=> "01"
- 剰余演算子と混同するな!
- eql? は==と大体同じだけど、違うときもある
- 1 == 1.0 #=> true だけど、 1.eql?(1.0) #=> false だ!
- a = Array.new(2, "a")でできるa[0]とa[1]は同一オブジェクト
- 別物にするにはブロックを渡す。a = Array.new(2) { "a" }
- 配列に*を使うとjoin扱いになる
- [1,2,3]*"-" #=> "1-2-3"
- for式ではブロックスコープが作成されない
- ハッシュに存在しないキーを指定したときのデフォルト値は変更できる
- h = Hash.new("a"); h[:nokey] #=> "a"
- Hashでハッシュを作るときは=>ではなくすべてカンマ区切り
- 正規表現マッチは=~だけでなく===でもt/fが返ってくる
- /abc/ === "abcde" #=> true
- "abcde" === /abc/ ではないことに注意!
- ブロックを引数として渡すと、そのときの外部の変数を参照できる
- x = 10; 1.upto(5) { |i| x += i }; x #=> 25
- Procとブロックは引数が違ってもnilで埋めてくれるが、lambdaはArgumentErrorを発生させる
- raiseを空実行させると、直前の例外を再発生させる
- begin; 1/0; rescue; p "error"; raise; end
- throwしたらcatchを抜ける
- ancestorsメソッドでクラスの継承チェーンを参照できる(クラスメソッド)
- 1.class.ancestors #=> [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
- ↑1.8.7
- 1.class.ancestors #=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
- ↑1.9.3
- 包含関係は大なり小なりで確認できる
- Fixnum < Integer #=> true
- includeするとそのモジュールの無名クラスが作られて、親クラスとの間に勝手に差し込まれる
- しかしsuperclassやancestorsでは出てこないので注意
- メソッド内で定義されているメソッドは、外側のメソッドが実行されるまで定義されない
- extendとは、特異クラスに対してincludeすること
- foo.extend(Bar)は、class << foo; include Bar; endと同義
- privateメソッドはselfを省略した形でしか呼び出せない
- 組み込み関数とはKernelモジュールのprivateメソッド
- ただし独自の組み込み関数を定義するときはObjectクラスにすべき
- インスタンス変数はメソッドのように探索されない
- メソッド内で定数を定義すると、SyntaxErrorとなる
- メソッドは複数回の実行が前提なので定数の初期化、値の更新を許していない
- constantsメソッドでそのモジュール・クラスの定数を配列で返してくれる
- 定数が同モジュール・クラス内に存在しない場合、外側に探索する
- スーパクラスでも定数が見つからない場合、const_missingが呼び出される
- Ruby1.8.7では、puts nilで「nil」が表示される
- raise => e; e.backtrace でスタックトレース
- オーバライドできない演算子
- ?: ... .. ! not && and || or ::
- 配列同士の引き算では、右辺にある要素に該当する左辺要素すべて削除される
- [1,1,2,2,3]-[1,2] #=> [3]
- Array#unshift は引数を指定しなければ何もしない
- [1,2,3].unshift #=> [1,2,3]
- String#index の第2引数は探索開始位置を指定できる
- String#, String#slice で数値指定・範囲指定・文字列指定・正規表現で抽出できる。マッチした文字だけ返す。
- "abcdefg"[0] #=> "a"
- "abcdefg"[0..1] #=> "ab"
- "abcdefg"[0...1] #=> "a"
- "abcdefg"["a"] #=> "a"
- "abcdefg"[/.*/] #=> "abcdefg"
- String#delete の引数は、正規表現でいうところの「文字クラス」を文字列にしたもの
- "abcdefg".delete('a-c') #=> "defg"
- "abcdefg".delete('^a-c') #=> "abc"
- String#scan はマッチした部分の文字列を「配列」で返す
- "abcdefg".scan(/.../) #=> ["abc", "def"]
- Hash#include?, Hash#member? はキーに一致するかを見てる
- { :a => 1, :b => 2 }.include?(:a) #=> true
- { :a => 1, :b => 2 }.member?(2) #=> false
- includeするとモジュール名もancestorsメソッドで確認できる
- module Hoge;end
class Fuga; include Hoge; end
Fuga.ancestors
#=> [Fuga, Hoge, Object, Kernel]
- Float + Ratinal #=> Float
- Float + Complex #=> Complex
- ただのattr :hogeはattr_reader :hogeと同義。attr :huge, trueは、attr_accessor :hugeと同義。
- クラス変数はサブクラスに共有される。
- sortにブロックを渡して評価するなら、左が小さいなら「-1」にする
- begin end内でのexitは、SystemExit例外を投げる
- freezeはオブジェクトの内容の変更を禁止するのであって、参照変数自身は変更可能である。
- a = [1,2,3].freeze
- a += [4,5]
- a #=> [1,2,3,4,5]
- ancestorsメソッドはModuleクラスのインスタンスメソッド
- Time - Time #=> Float