Learning ruby by the cherry book! (Chapter 2)
Ruby Programming
プログラミング言語の再学習としてプロを目指す人のためのRuby入門[改訂2版]を読み始めましたので、気になる点をまとめます。
2.10.4 case文
基本的な文法
case .. # 対象のオブジェクトや式
when a
# 処理
when b
# 処理
else
# どれにも一致しない場合の処理
end
複数の値でマッチさせることができる
country = 'アメリカ'
case country
when 'japan', '日本'
'こんにちは'
when 'us', 'アメリカ'
'Hello'
else
'???'
end
#=> "Hello"
caseの式を省略すると最初にTrueになる処理を行う
country = 'us'
case
when country == 'japan'
'こんにちは'
when country == 'us'
'Hello'
else
'???'
end
#=> "Hello"
最後に評価された式を返すので変数に入れることもできる
country = 'us'
message =
case
when country == 'japan'
'こんにちは'
when country == 'us'
'Hello'
else
'???'
end
puts message
#=> "Hello"
また分岐にはRangeオブジェクトや正規表現オブジェクト、クラスオブジェクトを使うことができる。
2.10.5 条件演算子(三項演算子)
n = 11
if n > 10
'10より大きい'
else
'10以下'
end
#=> 10より大きい
# 条件演算子で書き換え
n = 11
n > 10 ? '10より大きい' : '10以下'
#=> 10より大きい
## 結果を変数に代入することも可能
message = n > 10 ? '10より大きい' : '10以下'
puts message
#=> '10より大きい'
返って読みづらくなることもあるのでコードの可読性を考慮しながら使うこと。
2.11 メソッド定義についてもっと詳しく
2.11.1 デフォルト値付きの引数
def greet(country = 'japan')
if country == 'japan'
'こんにちは'
else
'hello'
end
end
greet #=> こんにちは
greet('us') #=> hello
# デフォ有無を混在することも可
def greet(country, num = 1)
# 処理
end
# メソッドの戻り値などを設定することもできる
def greet(country, now = Time.now, message = bar)
# 処理
end
def bar
'BAR'
end
# 第1引数を第2引数のデフォにすることもか
def point(x, y = x)
# 処理
end
## 第2引数を第1引数のデフォにはできない
def point(x = y, y)
p x, y
end
point(1)
#=> NameError: undefined local variable or method `y' for main:Object
# in `point'
2.11.2と3 ?,!で終わるメソッド
?で終わるメソッドは慣習として真偽値を返す
!で終わるメソッドは!がついていないメソッドよりも危険という意味を持つ
変数名には?,!はつけられない
「コラム:!で終わるメソッドは破壊的メソッドであるは間違い」
- 同じ動作で破壊的・非破壊的メソッドの療法がある場合は!がつくと破壊的であるというのは正しい
- 破壊的であっても非破壊的メソッドがない場合は!が付かない
- 破壊的かどうか関係なく、安全、非安全なメソッドがある場合は!がつく
2.11.4 エンドレスレスメソッド定義
Ruby 3.0から登場した記法。
便利な場合もあるが、3.0時点では実験的機能という位置づけなので、3.1では仕様変更となる場合もあるので注意。
def greet
'Hello'
end
def greet = 'Hello'
# 呼び方はどちらも同じ
greet
#=> 'Hello'
# 引数あり
def add(a, b)
a + b
end
def add a, b = a + b
2.12 その他
ガベージコレクション 自動的に使用されなかったオブジェクトを回収し、メモリを開放する
エイリアスメソッド
'hello'.length
'hello'.size
式と文
式:値を返し、結果を変数に代入できるもの
文:値を返さず、変数に代入しようとすると構文エラーになるもの
if文も値を返す(if式のほうが適している)
疑似変数
true
false
self
__FILE__
__LINE__
__ENCODING__
2.12.5. 参照の概念の理解
Rubyの変数にはオブジェクトそのものではなく、オブジェクトへの参照が格納される。
変数を変数に渡すと元のオブジェクトと同じ変数を参照する。
a = 'hello'
b = 'hello'
a.object_id
#=> 70101841430320
b.object_id
#=> 70101864957360 # aとは違うオブジェクト
c = b
c.object_id
#=> 70101864957360 # bと同じオブジェクトを参照
def m(d)
d.object_id
end
m(c)
#=> 70101864957360 # c(b)と同じオブジェクトを参照
# .equal?で同じオブジェクトか判定できる
a.equal?(b)
#=> false
b.equal?(c)
#=> true
b.upcase!
p c
=> "HELLO" # cも変更される
a ---- [hello]
b ---- [hello]
c -----┘
└ b -┘
メソッドm
2.12.8 puts/print/p/pp
puts/printは一般ユーザ向け
p/ppは開発者向け
'abc'.to_s
#=> "abc"
'abc'.inspect
#=> "\"abc\""
表をよく見ておく
2.10.4 case文
基本
case .. # 対象のオブジェクトや式
when a
# 処理
when b
# 処理
else
# どれにも一致しない場合の処理
end
複数の値でマッチ
country = 'アメリカ'
case country
when 'japan', '日本'
'こんにちは'
when 'us', 'アメリカ'
'Hello'
else
'???'
end
#=> "Hello"
caseの式を省略すると最初にTrueになる処理を行う
country = 'us'
case
when country == 'japan'
'こんにちは'
when country == 'us'
'Hello'
else
'???'
end
#=> "Hello"
最後に評価された式を返すので変数に入れることもできる
country = 'us'
message =
case
when country == 'japan'
'こんにちは'
when country == 'us'
'Hello'
else
'???'
end
puts message
#=> "Hello"
また分岐にはRangeオブジェクトや正規表現オブジェクト、クラスオブジェクトを使うことができる。
2.10.5 条件演算子(三項演算子)
n = 11
if n > 10
'10より大きい'
else
'10以下'
end
#=> 10より大きい
# 条件演算子で書き換え
n = 11
n > 10 ? '10より大きい' : '10以下'
#=> 10より大きい
## 結果を変数に代入することも可能
message = n > 10 ? '10より大きい' : '10以下'
puts message
#=> '10より大きい'
返って読みづらくなることもあるのでコードの可読性を考慮しながら使うこと。
2.11 メソッド定義についてもっと詳しく
2.11.1 デフォルト値付きの引数
def greet(country = 'japan')
if country == 'japan'
'こんにちは'
else
'hello'
end
end
greet #=> こんにちは
greet('us') #=> hello
# デフォ有無を混在することも可
def greet(country, num = 1)
# 処理
end
# メソッドの戻り値などを設定することもできる
def greet(country, now = Time.now, message = bar)
# 処理
end
def bar
'BAR'
end
# 第1引数を第2引数のデフォにすることもか
def point(x, y = x)
# 処理
end
## 第2引数を第1引数のデフォにはできない
def point(x = y, y)
p x, y
end
point(1)
#=> NameError: undefined local variable or method `y' for main:Object
# in `point'
2.11.2/3 ?/!で終わるメソッド
?で終わるメソッドは慣習として真偽値を返す
!で終わるメソッドは!がついていないメソッドよりも危険という意味を持つ
変数名には?,!はつけられない
「!で終わるメソッドは破壊的メソッドであるは間違い」
- 同じ動作で破壊的・非破壊的メソッドの療法がある場合は!がつくと破壊的であるというのは正しい
- 破壊的であっても非破壊的メソッドがない場合は!が付かない
- 破壊的かどうか関係なく、安全、非安全なメソッドがある場合は!がつく
2.11.4 エンドレスレスメソッド定義
Ruby 3.0から登場した記法。
便利な場合もあるが、3.0時点では実験的機能という位置づけなので、3.1では仕様変更となる場合もあるので注意。
def greet
'Hello'
end
def greet = 'Hello'
# 呼び方はどちらも同じ
greet
#=> 'Hello'
# 引数あり
def add(a, b)
a + b
end
def add a, b = a + b
2.12 その他
ガベージコレクション
- 自動的に使用されなかったオブジェクトを回収し、メモリを開放する
エイリアスメソッド
'hello'.length
'hello'.size
式と文
式:値を返し、結果を変数に代入できるもの
文:値を返さず、変数に代入しようとすると構文エラーになるもの
if文も値を返す(if式のほうが適している)
疑似変数
true
false
self
__FILE__
__LINE__
__ENCODING__
2.12.5参照の概念の理解
Rubyの変数にはオブジェクトそのものではなく、オブジェクトへの参照が格納される。
変数を変数に渡すと元のオブジェクトと同じ変数を参照する。
a = 'hello'
b = 'hello'
a.object_id
#=> 70101841430320
b.object_id
#=> 70101864957360 # aとは違うオブジェクト
c = b
c.object_id
#=> 70101864957360 # bと同じオブジェクトを参照
def m(d)
d.object_id
end
m(c)
#=> 70101864957360 # c(b)と同じオブジェクトを参照
# .equal?で同じオブジェクトか判定できる
a.equal?(b)
#=> false
b.equal?(c)
#=> true
b.upcase!
p c
=> "HELLO" # cも変更される
a ---- [hello]
b ---- [hello]
c -----┘
└ b -┘
メソッドm
2.12.8 puts/print/p/pp
puts/printはto_sで文字列に変換されるため一般ユーザ向け
p/ppはinspectで文字列化され、開発者向けの情報を含むため開発者向け
'abc'.to_s
#=> "abc"
'abc'.inspect
#=> "\"abc\""
表 2-1 putsメソッド、printメソッド、pメソッド、ppメソッドの違い
メソッド | 出力後の改行 | 配列の表示 | 文字列変換 | 戻り値 |
---|---|---|---|---|
puts | あり | 要素ごとに改行 | to_s | nil |
なし | 改行しない | to_s | nil | |
p | あり | 改行しない | inspect | 引数のオブジェクト |
pp | あり | 見やすく整形 | inspectに似た方法 | 引数のオブジェクト |