LoginSignup
0
0

More than 5 years have passed since last update.

プログラミング初心者のRubyゴールド勉強記録(文法)

Last updated at Posted at 2016-08-29

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で除算を行った場合)

例外の再発生

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>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0