Javaエンジニアが今さらRubyの基礎文法を覚えるために対比した その1(基本、変数編)

# はじめに
別の思想の言語を覚えるなら差分で覚えるのが早いのではないかと思って、Rails始める前に基礎文法やり直そうチートシートみたいなのを作成すると覚えるやろ的な発想です。

色々と不足はあるとは思いますが、とりあえず今考えて必要かなと思ったところだけにしてるので、ご了承ください。
書くことが多いため記事は分割しまくります。

つっこみは大歓迎です。

# 環境
[paiza.io](https://paiza.io/)でこういう時は実行すると楽です

これを作った時のバージョンは以下です。バージョンは[ヘルプ](https://paiza.io/help?locale=ja-jp)から確認できます。

Ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
Java openjdk version "12" 2019-03-19

# コメント
コメントの書き方について

```Java
// 1行の場合

/*
  複数行の場合
*/
```

``` Ruby
# 1行の場合

=begin
  複数行の場合
=end

__END__
この行以降は全てコメントになる
```

# 処理の区切り文字
実行する際の区切り文字の話です。

``` Java
String str = "World"; // 処理の区切りはセミコロンのみで行われる
```

``` Ruby
tmp1 = 1 # 基本は改行が区切りになる
tmp2 = 2;print("#{tmp1 + tmp2}") # セミコロンも区切りとして有効
```

# 標準出力

## Hello World
まずはHello Worldから。
Javaはクラスを作成しないといけないので、タイプ量が多いです。
Rubyはいきなり処理が書けるため、タイプ量が少ないです。

``` java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

```

``` ruby
# いくつか呼び方があるようなので、以下を参照ください
# https://qiita.com/naoge/items/f5d84581d3a301a9c22f
print("Hello World")
```

## 変数展開
変数を表示することも多いでしょう。
Javaだとprintfメソッドで書式指定子を宣言し変数を設定することで展開されます。
Rubyだと変数展開が使えるので、それでやります。

``` java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        String str = "World";
        // System.out.println("Hello" + str)でも可能。
        System.out.printf("Hello %s", str);
    }
}

```

``` ruby
str = "World";
print("Hello #{str}") #{式(変数)}で変数展開可能
```

# 変数定義
上で少し変数を使っていますが、ここで変数について記載します。
Rubyの変数については少し複雑なので、スコープに関してはここで扱うと面倒になりそうなので、見なかったことにしています。
その影響もあり、Rubyの方の変数を全てカバー出来る訳ではないと思いますがご了承ください。

## ローカル変数
Javaは静的型付け言語のため、変数がどの型かを宣言する必要があります。
Rubyは動的型付け言語のため、特に型の指定は必要ありません。
Rubyのルールとして、小文字またはアンダースコアで始まる識別子がローカル変数となっています。アンダースコアは使わない変数用らしいので、その辺に注意が必要です。

``` Java
String tmp1 = "1";
```

``` Ruby
tmp1 = "1"
```

Rubyは一度宣言した変数に別の型の変数も入れることが可能です。

``` Ruby
tmp1 = 1

puts("#{tmp1}") # putsは改行ありの標準出力

tmp1 = "2"

puts("#{tmp1}")
```

## 定数
Javaはfinalを付けて書き換えを防ぎつつ宣言します。大体はstatic付けておいて問題ないので、staticもつけます。
Rubyは英語大文字で開始した変数については定数と定義されているため、変数名だけで判断することになります。

``` Java
public static final String ONE = "1";
```

``` Ruby
ONE = "1"

__END__
この変数を書き換えると以下warningが発生してプログラムが動作しません。

warning: already initialized constant ONE
```

Rubyの定数はJavaと違い、トップレベルにも定義可能です。
そして、同名の定数をclass内にも可能となっています。
その場合の優先順位は使用箇所から向かって外部に向かっていくにつれて優先順位が下がっていきます。

```
ONE = "1"

class A
   ONE = "2"
   
   def print
       p ONE
   end
end

a = A.new
a.print # これは2と表示される

p ONE # これは1と表示される
```
## グローバル変数
Javaは厳密な意味でのグローバル変数はありません。
全てがOjbectに属する必要があるため、全体に見える変数は作れますがグローバル変数ではありません。

Rubyは`$`を先頭に付与することでグローバル変数として宣言出来ます。
宣言していないグローバル変数も参照出来ますが、`nil`となります。

``` Ruby
$str = "a"
```

## インスタンス変数
ここらへんからRubyの変数の複雑さが出てきます。
インスタンス変数は自分の中ではJavaでいうメンバー変数と同様という理解です。
スコープ的にはprotectedと同様の扱いという認識！

Rubyは`@`を先頭につけて変数を宣言します。
Javaと違ってメンバー変数として宣言しない上に(した場合はクラスインスタンス変数)参照範囲が広いので、クラスを複雑化させると何処で何か行われてるか分からなくなるので注意って感じがします。
これを使わないじゃなくてクラスをシンプルに保つのが正しいやり方だと思うので、そこは注意。

また、Rubyの場合はクラスメソッド(self)とインスタンスメソッド(selfつかない)の参照は別となります。
selfはstaticメソッドぽい感じがするので、そういう理解をとりあえずしています。

``` Java
public class A {
    protected String str;
}
```

``` Ruby
class A
  def save(target)
    @str = target;
  end
end
```

## クラス変数
クラスに属する変数です。
Javaでいうstatic扱いになるようで、別のクラスインスタンスにも影響を及ぼします。

これは使わない方が無難ですね。
混沌を生み出す原因にしか思えないです。

``` Java
public class A {
    protected static String str;
}
```

``` Ruby
class A
  def save(target)
    @@str = target;
  end
end
```

## クラスインスタンス変数
インスタンス変数をクラスに属するように宣言するとクラスインスタンス変数となり、クラスメソッド(self)からのみ参照出来るようになります。
インスタンス変数との違いは、自分のクラスメソッドからのみのスコープとなる点のようです。他から見ようとするとインスタンス変数扱いになります。

Javaだとこれは出来なさそうなので、こういうことも出来ると覚えるしかなさそうですね。

``` Ruby
# Your code here!
class A

  def save(user_name)
    @str = user_name
  end
    
  def self.save(user_name)
      @str = user_name
  end

  def self.print
    p @str
  end

  def print
    p @str
  end
end

a = A.new
a.save("aaa")
a.print

A.save("bbb")
A.print
```