業務でPythonを使っていますが、ひょんなことからRubyを学ぶ機会が出来たのでPythonとの基本的な構文の違いをまとめています。
Rubyは初心者なので、変なことを書いていたらご指摘ください。
似ている所も多いので、業務と趣味で使っていたら混乱しそうだ...
RubyとPythonの違うところ
RubyとPythonで三項演算子の記法が異なる
以下のように、記法が異なります。
Ruby: 変数 = 条件式 ? 条件式がTrueの時の値 : 条件式がFalseの時の値
Python: 変数 = 条件式がTrueの時の値 if 条件式 else 条件式がFalseの時の値
サンプルコードを見ていきましょう。
Ruby
size = 185
result = size > 180 ? 'Big size' : 'Small size'
p result # -> Big size
Python
size = 185
result = "Big size" if size > 180 else "Small size"
print(result) # -> Big size
メソッド呼び出し
メソッド呼び出し時、Rubyでは以下の呼び出し方法が可能です。
Ruby
- オブジェクト.メソッド(引数,引数,引数)
- オブジェクト.メソッド 引数,引数,引数
- 引数が無い場合: オブジェクト.メソッド
コードをPythonと比べてみましょう。
Ruby
def func_1(a, b)
puts(a + b)
end
text_1 = 'Hello '
text_2 = 'Ruby'
func_1(text_1, text_2) # -> Hello Ruby
func_1 text_1, text_2 # -> Hello Ruby
def func_2()
puts('Hello Ruby')
end
func_2() # -> Hello Ruby
func_2 # -> Hello Ruby
Python
def func_1(a, b):
print(a, b)
text_1 = 'Hello '
text_2 = 'Python'
func_1(text_1, text_2) # -> Hello Python
func_1 text_1, text_2 # -> Syntax Error
def func_2():
print('Hello Python')
func_2() # -> Hello Python
func_2 # -> なにも起きない(オブジェクトが呼ばれただけ)
Ruby: ハッシュ, Python: dict
RubyではPythonのdict型のような型をハッシュと呼ぶ。
JavaだとHashMapとかもあるので、ハッシュという名前に違和感は感じない。
Ruby
user = {
"name" => "やまもと ルビ子",
"phone" => "080-0000-0000",
"address" => "埼玉県草加市"
}
puts(user) # -> {"name"=>"やまもと ルビ子", "phone"=>"080-0000-0000", "address"=>"埼玉県草加市"}
Python
user = {
"name": "やまもと ルビ子",
"phone": "080-0000-0000",
"address": "埼玉県草加市"
}
print(user)
Rubyではダブルクォートの文字列なら式展開を利用できる
Rubyではダブルクォートで囲み、"#{1+1}"
のように#{式}で表すと、文字列の中に式の値を入れることが出来ます。
Pythonではfstringを使う必要があります。f'{1+1}'
のように。
Ruby
item = 'おにぎり'
message = "#{item}をお買い上げですね。ありがとうございます。"
puts(message) # -> おにぎりをお買い上げですね。ありがとうございます。
Python
item = "おにぎり"
message = f"{item}をお買い上げですね。ありがとうございます。"
print(message) # -> おにぎりをお買い上げですね。ありがとうございます。
Rubyではfalseになる値が少ない
Pythonでは以下のような値がFalse判定される。
- 数値の0
- 空の配列やdictなどのコレクション
- 空文字
- None
Rubyでは以下の値がFalse判定される。
- nil
- false
Pythonとの違いというより、RubyはFalse判定されるものが極端に少ない。他言語で慣れている場合、実装時はこの違いを忘れないようにしなくてはならない。
Ruby
puts('0 is true') if 0
puts('{} is true') if {}
puts('[] is true') if []
puts('nil is true') if nil
puts('false is true') if false
# ->
# 0 is true
# {} is true
# [] is true
Python
print(bool(0)) # -> False
print(bool({})) # -> False
print(bool([])) # -> False
print(bool(None)) # -> False
print(bool(False)) # -> False
Rubyではif文が戻り値を返す
Rubyではif文が戻り値を返すため、そのまま変数に詰めることが出来ます。
Ruby
time = 'noon'
eat =
if time == 'morning'
'break fast'
elsif time == 'noon'
'runch'
elsif time == 'night'
'dinner'
else
'snack'
end
puts(eat)
Rubyではメソッドの戻り値にreturnを使う必要がない
Rubyでは最後の式がメソッドの戻り値になるため、returnを使う必要がありません。また、returnを使わない方が好ましいとされているようです。
returnを使うのは、メソッドの途中で結果を戻したいときに明示的に使う用です。
returnを使わない場合のRubyとPythonのメソッドと実行結果を見てみましょう。
Ruby
def greeting_morning()
return 'good morning!'
end
def greeting_noon()
'hello'
end
def greeting_night
'good night'
end
puts greeting_morning # -> "good morning!"
puts greeting_night # -> "hello"
puts greeting_noon # -> "good night"
Python
def greeting_morning():
return 'good morning!'
def greeting_noon():
'hello'
def greeting_night():
'good night'
print(greeting_morning()) # -> "good morning!"
print(greeting_night()) # -> None
print(greeting_noon()) # -> None
Rubyではifの逆の意味を持つunless文が存在する
unless文はifと逆で、条件式がfalseの時に内部の処理を実行します。
以下、サンプルコードです。
Ruby
hp = 500
status = 'poison'
if status == 'poison'
hp -= 10
end
p hp # -> 490
status = 'healing'
unless status == 'poison'
hp += 20
end
p hp # -> 510
Rubyではcase文がある
Pythonでcase文、switch文のようなことをすることは出来ず、elseifであらわす必要があります。
Rubyにはcase文があります。
month = 10
season =
case month
when 12, 1, 2
'winter'
when 3, 4, 5
'spring'
when 6, 7, 8
'summer'
when 9, 10, 11
'autumn'
end
p season # -> autumn
Rubyではモジュールをインポートする際、モジュール名を文字列にしなければいけない
Rubyではライブラリをインポートするとき、require 'Date'
のように、ライブラリ名を文字列とする必要があります。
Pythonではimport datetime
のようにインポート可能です。
Ruby
require 'Date'
p Date.today
Python
import datetime
print(datetime.datetime.now())
RubyとPythonの同じところ
すべてがオブジェクト
RubyもPythonもオブジェクト指向言語なので、すべてがオブジェクトです。
インクリメント、デクリメントの演算子が無い
num++やnum--が使えません。
代わりに、num+=1, num-=1を使います。
サンプルコード
num_1 = 10
num_1 += 100
puts(num_1) # -> 110
num_2 = 10
num_2 -= 100
puts(num_2) # -> 90
数値と文字列の暗黙的な変換は行われない
1 + "1" = 2
1 + "1" = 11
みたいなことは行われません。
サンプルコード
puts(1 + "1") # -> `+': String can't be coerced into Integer (TypeError)
AND条件やOR条件の戻り値は式の評価が終わったタイミング
こちらはRuby, Pythonのみの話ではなく、一般的にこの動作です。
式の評価が終わるタイミングは、AND条件とOR条件で大きく異なります。
AND条件: 左から評価していき、最初にFalseが評価されたタイミング または 最後まで値がTrueで最後の値を評価したタイミング
OR条件: 左から評価していき、最初にTrueが評価されたタイミング または 最後まで値がFalseで最後の値を評価したタイミング
AND条件では1つの値がFalseな時点で、式全体がFalseになります。
OR条件では1つの値がTrueな時点で、式全体がTrueになります。
それでは、サンプルコードを見ていきましょう。
Ruby
# AND条件 最初にFalse or 最後の値
p 1 && 2 && 3 # -> 3
p 1 && nil && 3 # -> nil
p nil && 2 && 3 # -> nil
p 1 && false && 3 # -> false
# OR条件 最初にTrue or 最後の値
p 1 || 2 || 3 # -> 1
p 1 || nil || 3 # -> 1
p nil || 2 || 3 # -> 2
p false || false || 3 # -> 3
p false || false || nil # -> nil
Python
# AND条件 最初にFalse or 最後の値
print(1 and 2 and 3) # -> 3
print(0 and 1) # -> 1
print(1 and False and 20) # -> False
# OR条件 最初にTrue or 最後の値
print(1 or 5) # -> 1
print(0 or False or [] or 20) # -> 20
メソッドの引数の数が違うとエラーになる
メソッドの数が違うとエラーになるため、引数を柔軟にするためには可変長引数やデフォルト引数を使う必要があります。
def method(a, b)
p a
p b
end
method('A', 'B')
method('A', 'B', 'C') # -> wrong number of arguments
method('A') # -> wrong number of arguments
Python
def method(a, b):
print(a)
print(b)
method('A', 'B')
method('A', 'B', 'C') # -> method() takes 2 positional arguments but 3 were given
method('A') # -> method() missing 1 required positional argument: 'b'