プログラミング言語食べ比べ：PythonとRuby編

# はじめに

この記事は同じ動作をPythonとRubyで書いたらどうなるのかという比較をするための記事です。

あくまで備忘録として書いてるので拙いかもしれませんが、ご了承ください。

# 対話コンソール

Pythonでは`python`コマンド、Rubyでは`irb`を使う。

```shell-session:Python
$ python
Python 3.8.5 ...
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

```shell-session:Ruby
$ irb
irb(main):001:0> 
```

対話コンソールから抜ける場合、
Pythonであれば`exit()`か`Ctrl + Z`(Windowsの場合)、`Ctrl + D`(Linuxの場合)、
Rubyであれば`exit`か`Ctrl + D`
で対話コンソールから出ることができる

# Hello World!を書く

Pythonは`print`、Rubyは`puts`。

```python:Python
print("Hello World!")
```

```ruby:Ruby
puts "Hello World!"
```

# 分岐

両者とも書き方に大差はないが、
Pythonはif内はインデントを設ける必要があり、Rubyは定義終了時に`end`を付けなければいけない
`else if`を設ける場合、Pythonは`elif [式]:`、Rubyは`elsif [式]`なので注意

```python:Python
a = 1

if a == 1:
    print("aは1")
elif a == 2:
    print("aは2")
else:
    print("aは1でも2でもない")
```

```ruby:Ruby
a = 1

if a == 1
  puts "aは1"
elsif a == 2
  puts "aは2"
else
  puts "aは1でも2でもない"
end
```

# 繰り返し（反復）

配列等による繰り返しであれば、Pythonは`for`、Rubyであれば`each`を使う

```python:Python
for a in range(10):
    print(a)
```

```ruby:Ruby
(0..9).each do |a|
  puts a
end
```

# 関数定義

## 引数なしの場合

Pythonだとこんな感じ

```python:Python
def func_def():
    print("It's function")
    
if __name__ == "__main__":
    func_def()
```

Pythonの場合は引数がなくても`()`を付ける必要がある（ある場合とない場合では動作が違う）

Rubyだとこう

```ruby:Ruby
def func_def
  puts "It's function"
end

if __FILE__ == $0
  func_def # func_def() と同様
end
```

Rubyの場合、引数がない場合は`()`をつける必要がない（付けても動作する）

## 引数ありの場合

これもさほど変わらない。

```python:Python
def arg_func(one, two=2):
    print(f"one: {one}, two: {two}")

if __name__ == "__main__":
    arg_func(1)
```

```ruby:Ruby
def arg_func (one, two=2)
  puts "one: #{one}, two: #{two}"
end

if __FILE__ == $0
  arg_func(1)
end
```

余談だが、

Pythonの場合は`if __name__ == "__main__":`、
Rubyの場合は`if __FILE__ == $0`でメインファイルとして取り扱われるかを判別できる

また、
Pythonは`f"{variables}"`、
Rubyは`"#{variables}"`で各変数を文字列に代入できる

# クラス

PythonもRubyにもクラスの概念がある
ただ、両者を比べると使い勝手が少し違う

## 定義

クラスのコンストラクターは、Pythonは`__init__`、Rubyは`initialize`で定義する

```python:Python
class Greeter:
    def __init__(self, name="World"):
        self.name = name

    def hello(self):
        print(f"Hello {self.name}!")

    def evening(self):
        print(f"Good evening {self.name}!")
```

```ruby:Ruby
class Greeter
  def initialize(name = "World")
    @name = name
  end

  def hello
    puts "Hello #{@name}!"
  end

  def evening
    puts "Good evening #{@name}!"
  end
end
```

Rubyの変数は`attr_accessor :[インスタンス変数]`をすると、読むことができるようになる
とにかく、これを設定しないとインスタンス変数はプライベート扱いになると言っても過言ではない
なお、Pythonは変数の最初に`__`(アンダーバー2つ)を付け足すとプライベート扱いになる（関数も同様）

また、Pythonだと同じクラスを設定すると置き換わってしまうが、
Rubyの場合は同じクラスをもう一度書いても、付け足すことができる
（しかも既に作られているインスタンスにも適用される）

```ruby:Ruby
# -- snip -- (上記のGreeterクラスが既に定義されているとする)
class Greeter
  attr_accessor :name
end
```

## インスタンス作成

インスタンスの作成は、Pythonはそのままクラス名を、Rubyはクラス名に加えて`.new`を使う

```python:Python
# -- snip --
greet = Greeter("Qiita")
```

```ruby:Ruby
# -- snip --
greet = Greeter.new("Qiita")
```

# 最後に

- PythonとRubyは似ているところは似ている
- Pythonはインデントによる分岐等の処理記述
- Rubyは`end`までが処理記述なので区切りがわかる

Rubyのメモ書きはScrapbox(Yuzulia-ProgBuilder)にまとめているので、気が向いたら御覧ください。
https://scrapbox.io/yuzulia-pb/Ruby

気が向いたらまたこの記事を更新します。