Rationalクラス
irb(main):002:0* 4/5 # 0になる
=> 0
irb(main):003:0> 4.0/5
=> 0.8
irb(main):004:0> 4/5r #分数で表示される
=> (4/5)
irb(main):005:0> (4/5r).to_f #小数点で表示される
=> 0.8
irb(main):006:0> 4/5.0
=> 0.8
多重代入と可変長引数
可変長引数は、以下3つを注意する
- デフォルト値は使えない
- 引数は配列として扱える
- 一つのメソッドに一つしか使えない
# 多重代入
irb(main):003:0* a,b,c = 1,2,3
=> [1, 2, 3]
irb(main):004:0> p a
1
=> 1
irb(main):005:0> p b
2
=> 2
irb(main):006:0> p c
3
=> 3
## 返り値に複数
irb(main):010:0* def foo
irb(main):011:1> return 1,2,3
irb(main):012:1> end
=> :foo
irb(main):013:0> a,b,c = foo
=> [1, 2, 3]
irb(main):014:0> p a
1
=> 1
irb(main):015:0> p b
2
=> 2
irb(main):016:0> p c
3
=> 3
## 配列
irb(main):020:0* a,b,c = [1,2,3]
=> [1, 2, 3]
irb(main):026:0> (a,b),c = [1,2],3
=> [[1, 2], 3]
## 値の個数が足りない
irb(main):031:0* a,b,c = 1,2
=> [1, 2]
irb(main):032:0> p c
nil
=> nil
## 一つの変数に複数の値を代入
irb(main):033:0> a = 1,2
=> [1, 2]
irb(main):034:0> p a
[1, 2]
=> [1, 2]
## 最後の変数に余った値を代入
irb(main):037:0> a, *b = [1,2,3]
=> [1, 2, 3]
irb(main):038:0> p a
1
=> 1
irb(main):039:0> p b
[2, 3]
=> [2, 3] # 配列で返ってくる
# 可変長引数
irb(main):040:0> def foo a, *b
irb(main):041:1> b
irb(main):042:1> end
=> :foo
irb(main):043:0> foo(1,2,3)
=> [2, 3] # 配列が返ってくる
## デフォルト値は使えない
irb(main):030:0* def hoge(*b=9)
irb(main):031:1> p b
irb(main):032:1> end
SyntaxError: (irb):30: syntax error, unexpected '=', expecting ')'
## 一つのメソッドに一つ
irb(main):038:0* def hoge(*a, *b)
irb(main):039:1> p a
irb(main):040:1> p b
irb(main):041:1> end
SyntaxError: (irb):38: syntax error, unexpected *
def hoge(*a, *b)
^
(irb):41: syntax error, unexpected keyword_end, expecting end-of-input
## 引数展開
irb(main):052:0> def foo1 a, *b
irb(main):053:1> p *b
irb(main):054:1> end
=> :foo1
irb(main):055:0> foo1(1,2,3)
2
3
=> [2, 3]
irb(main):056:0> def foo1 a, *b
irb(main):057:1> foo2(*b)
irb(main):058:1> end
=> :foo1
irb(main):048:0> def foo2 c, *d # *bの[2,3]が展開されて渡される
irb(main):049:1> d
irb(main):050:1> end
=> :foo2
irb(main):060:0* foo1(1,2,3)
=> [3]
例外
-
rescue
だけ書くとStandardError
から派生する全ての例外が対象となる -
rescue
は複数指定が可能だが、最初にマッチしたものしか実行されない - $! ... 同じスレッドとブロックで発生した最後の例外を組み込み変数
$!
として参照できる
irb(main):007:0* class Err1 < StandardError; end
=> nil
irb(main):008:0> class Err2 < Err1; end
=> nil
irb(main):009:0> begin
irb(main):010:1* raise Err2
irb(main):011:1> rescue => e # こっちが先に書かれているので対象になる
irb(main):012:1> puts "StandardError"
irb(main):013:1> rescue Err2 => ex # この例外処理は実行されない
irb(main):014:1> puts ex.class
irb(main):015:1> end
StandardError
=> nil
例外クラスの階層
- Exception
- ScriptError
- SyntaxError(文法エラーがあった場合)
- SignalException(補足していないシグナルを受けた場合)
-
StandardError
- ArgumentError(引数の数が合わない場合や値が正しくない場合)
- RuntimeError(特定の例外クラスには該当しないエラーが発生した場合や例外クラスを省略したraiseの呼び出し)
- NameError(未定義のローカル変数や定数を参照した場合)
- NoMethodError(未定義のメソッドを呼び出した場合)
- ZeroDivisionError(整数に対し整数の0で除算を行った場合)
- ScriptError
例外の再発生
irb(main):027:0* begin
irb(main):028:1* 1/0
irb(main):029:1> rescue ZeroDivisionError
irb(main):030:1> p $!.class
irb(main):031:1> raise
irb(main):032:1> end
ZeroDivisionError
ZeroDivisionError: divided by 0 # 最後に発生した例外を再度発生させてる
retry
irb(main):037:0> begin
irb(main):038:1* b = 1 / a
irb(main):039:1> rescue ZeroDivisionError
irb(main):040:1> a += 1
irb(main):041:1> retry # 再度begin節が実行される
irb(main):042:1> ensure # ensure節は一回だけ実行される
irb(main):043:1* p b
irb(main):044:1> end
1
=> 1
帯域脱出
irb(main):049:0* def foo
irb(main):050:1> throw :exit # throw = raise例外を発生させラベルと同じ名称のcatchに処理が映る。また、値を引数として渡すことができる
irb(main):051:1> end
=> :foo
irb(main):052:0> catch(:exit) {
irb(main):053:1* foo
irb(main):054:1> p 1
irb(main):055:1> }
=> nil
irb(main):056:0> p 2
2
ブロック {}
-
ブロック{...}
の場合は()の省略ができない -
do ... end
の場合は()の省略ができる
irb(main):002:0> 1.upto 5 do |x| puts x end
1
2
3
4
5
=> 1
irb(main):003:0> 1.upto 5 {|x| puts x } # {...}の場合は引数の()を省略できない
SyntaxError
irb(main):004:0> 1.upto(5) {|x| puts x }
1
2
3
4
5
=> 1
ブロック付きメソッド
呼び出し元のブロックを実行するには
-
yield
で呼び出す - &が付いた変数を定義するとProcオブジェクトとなるので、
Proc#call
で呼び出す
# yieldを使う場合
def tag(name)
puts "<#{name}>#{yield}</#{name}>"
end
tag(:p) {"Hello World"}
# 実行結果:<p>Hello World</p>
# Proc#callを使う場合
def tag(name, &block)
puts "<#{name}>#{block.call}</#{name}>"
p block.class #Procが表示される
end
tag(:p) {"Hello World"}
# 実行結果:<p>Hello World</p>