たまにはクイズでRubyの基本を確かめてみてもいいんじゃないかなっていう話


Rubyに関してちょっとクイズです。
↓の記事が面白かったので、僕も少し書こうと思います。
https://qiita.com/aimof/items/cf89d83b2760c65abd84

スーーーーゴおおおおおい基本的なことだからみんなわかるよね。

## トップレベルに関して

とりあえず、これを解いてみよう。
以下の記述がされたファイルを実行するとどんな実行結果が得られるだろう？

```ruby:User.rb
puts "1"

class User

  puts "2"

  def initialize(name)
    @name = name
  end

  def name
    @name
  end

end

puts "3"

user = User.new("太郎")
puts user.name
```


1.太郎が出力される
2.1、2、3、太郎が出力される
3.2、太郎が出力される
4.3、太郎が出力される

<details>
<summary>解答</summary>
2.1,2,3,太郎が出力される
<br>
不正解だった方はドンマイなので、この記事を読み進めてもいいんじゃないでしょうか。
<br>
全て出力されます。
<br>
putsメソッドがなぜ使えるのかがポイントです。putsはKarnelモジュールで定義されていて、Objectクラスがそれをincludeしています。全てのクラスの元がObjectクラスとなるので、putsメソッドが使えるわけですね。
Userクラスの外は何かっていうことがポイントですが、とりあえず次の問いに行ってみましょう。
<br>

</details>

## トップレベルの扱いに関して

これはどうでしょう。パッと見selfが何かわかりますかね。

```ruby:User.rb
puts self

class User

puts self

  def initialize(name)
    @name = name
  end

  def name
    puts self
    @name
  end

end

puts self

user = User.new("太郎")
puts user.name
```

1.main、main、main、User、太郎
2.main、User、main、0x0000000004a5f3f8のようなもの、太郎
3.nil、User、User、User,太郎
4.エラーが起きて実行できない

<details><summary>解答</summary>
2.main、User、main、オブジェクトID、太郎
<br>
selfの問いです。クラス外はmain、Userクラス内はUser,Userクラスのnameメソッド内は0x0000000004a5f3f8のような文字列となります。
<br>
先ほどのputsが使えた理由は、mainがオブジェクトクラスのインスタンスだからですね。
</details>

## トップレベルのメソッドの扱いに関して

最初ruby勉強するときなんかはファイルにメソッド書いて、呼び出してとかやると思うんだ。
でもさ、そもそもこれってなんで実行できるの？クラスも定義していないよ？？

```ruby
def print_hello
  puts "hello"
end

print_hello
```

<details>
<summary>解答</summary>
トップレベルに書いたメソッドは、Objectクラスのprivateメソッドになります。
<br>
トップレベルで定義したら、Kernelモジュールのメソッドとして定義したのと同じ扱い。putsとかと同じように使えるってことだね。
</details>

## アクセサメソッドに関して
簡単でしょう。
これはどんな出力がされるでしょう？

```ruby:User.rb
class User
  attr_accessor :name

  def initialize(name)
    self.name = name
  end
end

user = User.new("太郎")
puts user.name
```

1.何も出力されない
2.太郎が出力される
3.nilが出力される

<details>
<summary>解答</summary>
2.太郎が出力される
<br>
インスタンス変数を機械的に使っていると、あんまりみない書き方かもしれない。
これは太郎が出力されます。アクセサメソッドを使うときには、`@name`なんかとするものを多く見るから新鮮かもしれない。
</details>

## クラスの継承
次はこれで。
クラス変数って継承されるんですかね？

```ruby
class Animal
  @@name = "animal"
  def name
    puts @@name
  end
end

class Dog < Animal
  def name
    puts @@name
  end
end

dog = Dog.new
dog.name
```
1.「animal」が出力される
2.何も出力されない
3.エラーが起きて実行できない

<details>
<summary>解答</summary>
1.「animal」が出力される
<br>
クラス変数は継承したクラスでも使うことができます。
</details>


## モジュールとクラスのメソッドってどっちが優先なの？
それじゃあ。次はこれだ。
割と簡単なはず。

```ruby
class Animal
end

module Bow

  def bow
    puts "うおおおおおおおおん"
  end

end

class Dog < Animal
  include Bow

  def bow
    puts "わんわん"
  end

end

dog = Dog.new
dog.bow

```
1.「うおおおおおおおおん」が出力される
2.「わんわん」が出力される
3.何も出力されない

<details>
<summary>解答</summary>
2
<br>
クラスに定義されているメソッドが先か取り込んだモジュールのメソッドが先かという問いです。同じメソッドがあった場合、クラス→モジュールの順で呼ばれます。
</details>



## クラスからsuperでモジュールのメソッドを呼び出せるの？

最後です。モジュールは継承はできないよね。クラス内のメソッドの中、superを使ってモジュール内の同名称のメソッドを呼び出すことはできるのでしょうか？

```ruby
module Bow
  def bow
    puts 'bowbow!!'
  end
end

class Dog
  include Bow

  def bow
    super
    puts 'うおおおおおおおおおおおおおん!!'
  end

end

dog = Dog.new
dog.bow
```

1. 「うおおおおおおおおおおおおおん!!」が出力される
2. 「bowbow!!」が出力される
3. 「bowbow!!」「うおおおおおおおおおおおおおん!!」が出力される

<details>
<summary>解答</summary>
3. 「bowbow!!」「うおおおおおおおおおおおおおん!!」が出力される<br>
クラスの中にメソッドを定義し、その中から同名称のモジュールのメソッドをsuperで呼び出すことはできます。
</details>

## まとめ

ざっと書いてみましがたが、全て論理的に説明できるでしょうか。
rails使ってアプリケーションを作っていくのもいいけど、たまにはRubyの基本を見るのもいいかもしれないですね。